Chris@16
|
1 /*
|
Chris@16
|
2 Copyright 2005-2007 Adobe Systems Incorporated
|
Chris@16
|
3
|
Chris@16
|
4 Use, modification and distribution are subject to the Boost Software License,
|
Chris@16
|
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 http://www.boost.org/LICENSE_1_0.txt).
|
Chris@16
|
7
|
Chris@16
|
8 See http://opensource.adobe.com/gil for most recent version including documentation.
|
Chris@16
|
9 */
|
Chris@16
|
10
|
Chris@16
|
11 /*************************************************************************************************/
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef GIL_CONCEPT_H
|
Chris@16
|
14 #define GIL_CONCEPT_H
|
Chris@16
|
15
|
Chris@16
|
16 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
17 /// \file
|
Chris@16
|
18 /// \brief Concept check classes for GIL concepts
|
Chris@16
|
19 /// \author Lubomir Bourdev and Hailin Jin \n
|
Chris@16
|
20 /// Adobe Systems Incorporated
|
Chris@16
|
21 /// \date 2005-2007 \n Last updated on February 12, 2007
|
Chris@16
|
22 ///
|
Chris@16
|
23 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
24
|
Chris@16
|
25 #include <functional>
|
Chris@16
|
26 #include "gil_config.hpp"
|
Chris@16
|
27 #include <boost/type_traits.hpp>
|
Chris@16
|
28 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
29 #include <boost/concept_check.hpp>
|
Chris@16
|
30 #include <boost/iterator/iterator_concepts.hpp>
|
Chris@16
|
31 #include <boost/mpl/and.hpp>
|
Chris@16
|
32 #include <boost/mpl/size.hpp>
|
Chris@16
|
33
|
Chris@16
|
34 namespace boost { namespace gil {
|
Chris@16
|
35 template <typename T> struct channel_traits;
|
Chris@16
|
36 template <typename P> struct is_pixel;
|
Chris@16
|
37 template <typename dstT, typename srcT>
|
Chris@16
|
38 typename channel_traits<dstT>::value_type channel_convert(const srcT& val);
|
Chris@16
|
39 template <typename T> class point2;
|
Chris@16
|
40 template <std::size_t K, typename T> const T& axis_value(const point2<T>& p);
|
Chris@16
|
41 template <std::size_t K, typename T> T& axis_value( point2<T>& p);
|
Chris@16
|
42 template <typename ColorBase, int K> struct kth_element_type;
|
Chris@16
|
43 template <typename ColorBase, int K> struct kth_element_reference_type;
|
Chris@16
|
44 template <typename ColorBase, int K> struct kth_element_const_reference_type;
|
Chris@16
|
45 template <typename ColorBase, int K> struct kth_semantic_element_reference_type;
|
Chris@16
|
46 template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type;
|
Chris@16
|
47 template <typename ColorBase> struct size;
|
Chris@16
|
48 template <typename ColorBase> struct element_type;
|
Chris@16
|
49 template <typename T> struct channel_type;
|
Chris@16
|
50 template <typename T> struct color_space_type;
|
Chris@16
|
51 template <typename T> struct channel_mapping_type;
|
Chris@16
|
52 template <typename T> struct is_planar;
|
Chris@16
|
53 template <typename T> struct num_channels;
|
Chris@16
|
54
|
Chris@16
|
55 template <typename It> struct const_iterator_type;
|
Chris@16
|
56 template <typename It> struct iterator_is_mutable;
|
Chris@16
|
57 template <typename It> struct is_iterator_adaptor;
|
Chris@16
|
58 template <typename It, typename NewBaseIt> struct iterator_adaptor_rebind;
|
Chris@16
|
59 template <typename It> struct iterator_adaptor_get_base;
|
Chris@16
|
60
|
Chris@16
|
61
|
Chris@16
|
62 // forward-declare at_c
|
Chris@16
|
63 namespace detail { template <typename Element, typename Layout, int K> struct homogeneous_color_base; }
|
Chris@16
|
64 template <int K, typename E, typename L, int N>
|
Chris@16
|
65 typename add_reference<E>::type at_c( detail::homogeneous_color_base<E,L,N>& p);
|
Chris@16
|
66
|
Chris@16
|
67 template <int K, typename E, typename L, int N>
|
Chris@16
|
68 typename add_reference<typename add_const<E>::type>::type at_c(const detail::homogeneous_color_base<E,L,N>& p);
|
Chris@16
|
69
|
Chris@16
|
70 #if !defined(_MSC_VER) || _MSC_VER > 1310
|
Chris@16
|
71 template <typename P, typename C, typename L> struct packed_pixel;
|
Chris@16
|
72 template <int K, typename P, typename C, typename L>
|
Chris@16
|
73 typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type
|
Chris@16
|
74 at_c(packed_pixel<P,C,L>& p);
|
Chris@16
|
75
|
Chris@16
|
76 template <int K, typename P, typename C, typename L>
|
Chris@16
|
77 typename kth_element_const_reference_type<packed_pixel<P,C,L>,K>::type
|
Chris@16
|
78 at_c(const packed_pixel<P,C,L>& p);
|
Chris@16
|
79
|
Chris@16
|
80 template <typename B, typename C, typename L, bool M> struct bit_aligned_pixel_reference;
|
Chris@16
|
81
|
Chris@16
|
82 template <int K, typename B, typename C, typename L, bool M> inline
|
Chris@16
|
83 typename kth_element_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>::type
|
Chris@16
|
84 at_c(const bit_aligned_pixel_reference<B,C,L,M>& p);
|
Chris@16
|
85 #endif
|
Chris@16
|
86
|
Chris@16
|
87 // Forward-declare semantic_at_c
|
Chris@16
|
88 template <int K, typename ColorBase>
|
Chris@16
|
89 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
|
Chris@16
|
90 template <int K, typename ColorBase>
|
Chris@16
|
91 typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
|
Chris@16
|
92
|
Chris@16
|
93 template <typename T> struct dynamic_x_step_type;
|
Chris@16
|
94 template <typename T> struct dynamic_y_step_type;
|
Chris@16
|
95 template <typename T> struct transposed_type;
|
Chris@16
|
96
|
Chris@16
|
97 namespace detail {
|
Chris@16
|
98 template <typename T>
|
Chris@16
|
99 void initialize_it(T& x) {}
|
Chris@16
|
100 } // namespace detail
|
Chris@16
|
101
|
Chris@16
|
102 template <typename T>
|
Chris@16
|
103 struct remove_const_and_reference : public remove_const<typename remove_reference<T>::type> {};
|
Chris@16
|
104
|
Chris@16
|
105 #ifdef BOOST_GIL_USE_CONCEPT_CHECK
|
Chris@16
|
106 #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept);
|
Chris@16
|
107 template <typename C> void gil_function_requires() { function_requires<C>(); }
|
Chris@16
|
108 #else
|
Chris@16
|
109 #define GIL_CLASS_REQUIRE(T,NS,C)
|
Chris@16
|
110 template <typename C> void gil_function_requires() {}
|
Chris@16
|
111 #endif
|
Chris@16
|
112
|
Chris@16
|
113 /// \ingroup BasicConcepts
|
Chris@16
|
114 /**
|
Chris@16
|
115 \code
|
Chris@16
|
116 auto concept DefaultConstructible<typename T> {
|
Chris@16
|
117 T::T();
|
Chris@16
|
118 };
|
Chris@16
|
119 \endcode
|
Chris@16
|
120 */
|
Chris@16
|
121 template <typename T>
|
Chris@16
|
122 struct DefaultConstructible {
|
Chris@16
|
123 void constraints() {
|
Chris@16
|
124 function_requires<boost::DefaultConstructibleConcept<T> >();
|
Chris@16
|
125 }
|
Chris@16
|
126 };
|
Chris@16
|
127
|
Chris@16
|
128 /// \ingroup BasicConcepts
|
Chris@16
|
129 /**
|
Chris@16
|
130 \codeauto concept CopyConstructible<typename T> {
|
Chris@16
|
131 T::T(T);
|
Chris@16
|
132 T::~T();
|
Chris@16
|
133 };
|
Chris@16
|
134 \endcode
|
Chris@16
|
135 */
|
Chris@16
|
136 template <typename T>
|
Chris@16
|
137 struct CopyConstructible {
|
Chris@16
|
138 void constraints() {
|
Chris@16
|
139 function_requires<boost::CopyConstructibleConcept<T> >();
|
Chris@16
|
140 }
|
Chris@16
|
141 };
|
Chris@16
|
142
|
Chris@16
|
143 /// \ingroup BasicConcepts
|
Chris@16
|
144 /**
|
Chris@16
|
145 \code
|
Chris@16
|
146 auto concept Assignable<typename T, typename U = T> {
|
Chris@16
|
147 typename result_type;
|
Chris@16
|
148 result_type operator=(T&, U);
|
Chris@16
|
149 };
|
Chris@16
|
150 \endcode
|
Chris@16
|
151 */
|
Chris@16
|
152 template <typename T>
|
Chris@16
|
153 struct Assignable {
|
Chris@16
|
154 void constraints() {
|
Chris@16
|
155 function_requires<boost::AssignableConcept<T> >();
|
Chris@16
|
156 }
|
Chris@16
|
157 };
|
Chris@16
|
158 /// \ingroup BasicConcepts
|
Chris@16
|
159 /**
|
Chris@16
|
160 \code
|
Chris@16
|
161 auto concept EqualityComparable<typename T, typename U = T> {
|
Chris@16
|
162 bool operator==(T x, T y);
|
Chris@16
|
163 bool operator!=(T x, T y) { return !(x==y); }
|
Chris@16
|
164 };
|
Chris@16
|
165 \endcode
|
Chris@16
|
166 */
|
Chris@16
|
167 template <typename T>
|
Chris@16
|
168 struct EqualityComparable {
|
Chris@16
|
169 void constraints() {
|
Chris@16
|
170 function_requires<boost::EqualityComparableConcept<T> >();
|
Chris@16
|
171 }
|
Chris@16
|
172 };
|
Chris@16
|
173
|
Chris@16
|
174 /// \ingroup BasicConcepts
|
Chris@16
|
175 /**
|
Chris@16
|
176 \code
|
Chris@16
|
177 concept SameType<typename T, typename U>;// unspecified
|
Chris@16
|
178 \endcode
|
Chris@16
|
179 */
|
Chris@16
|
180
|
Chris@16
|
181 template <typename T, typename U>
|
Chris@16
|
182 struct SameType {
|
Chris@16
|
183 void constraints() {
|
Chris@16
|
184 BOOST_STATIC_ASSERT((boost::is_same<T,U>::value_core));
|
Chris@16
|
185 }
|
Chris@16
|
186 };
|
Chris@16
|
187
|
Chris@16
|
188 /// \ingroup BasicConcepts
|
Chris@16
|
189 /**
|
Chris@16
|
190 \code
|
Chris@16
|
191 auto concept Swappable<typename T> {
|
Chris@16
|
192 void swap(T&,T&);
|
Chris@16
|
193 };
|
Chris@16
|
194 \endcode
|
Chris@16
|
195 */
|
Chris@16
|
196 template <typename T>
|
Chris@16
|
197 struct Swappable {
|
Chris@16
|
198 void constraints() {
|
Chris@16
|
199 using std::swap;
|
Chris@16
|
200 swap(x,y);
|
Chris@16
|
201 }
|
Chris@16
|
202 T x,y;
|
Chris@16
|
203 };
|
Chris@16
|
204
|
Chris@16
|
205 /// \ingroup BasicConcepts
|
Chris@16
|
206 /**
|
Chris@16
|
207 \code
|
Chris@16
|
208 auto concept Regular<typename T> : DefaultConstructible<T>, CopyConstructible<T>, EqualityComparable<T>,
|
Chris@16
|
209 Assignable<T>, Swappable<T> {};
|
Chris@16
|
210 \endcode
|
Chris@16
|
211 */
|
Chris@16
|
212
|
Chris@16
|
213 template <typename T>
|
Chris@16
|
214 struct Regular {
|
Chris@16
|
215 void constraints() {
|
Chris@16
|
216 gil_function_requires< boost::DefaultConstructibleConcept<T> >();
|
Chris@16
|
217 gil_function_requires< boost::CopyConstructibleConcept<T> >();
|
Chris@16
|
218 gil_function_requires< boost::EqualityComparableConcept<T> >(); // ==, !=
|
Chris@16
|
219 gil_function_requires< boost::AssignableConcept<T> >();
|
Chris@16
|
220 gil_function_requires< Swappable<T> >();
|
Chris@16
|
221 }
|
Chris@16
|
222 };
|
Chris@16
|
223
|
Chris@16
|
224 /// \ingroup BasicConcepts
|
Chris@16
|
225 /**
|
Chris@16
|
226 \code
|
Chris@16
|
227 auto concept Metafunction<typename T> {
|
Chris@16
|
228 typename type;
|
Chris@16
|
229 };
|
Chris@16
|
230 \endcode
|
Chris@16
|
231 */
|
Chris@16
|
232 template <typename T>
|
Chris@16
|
233 struct Metafunction {
|
Chris@16
|
234 void constraints() {
|
Chris@16
|
235 typedef typename T::type type;
|
Chris@16
|
236 }
|
Chris@16
|
237 };
|
Chris@16
|
238 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
239 //
|
Chris@16
|
240 // POINT CONCEPTS
|
Chris@16
|
241 //
|
Chris@16
|
242 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
243
|
Chris@16
|
244 /// \brief N-dimensional point concept
|
Chris@16
|
245 /// \ingroup PointConcept
|
Chris@16
|
246 /**
|
Chris@16
|
247 \code
|
Chris@16
|
248 concept PointNDConcept<typename T> : Regular<T> {
|
Chris@16
|
249 // the type of a coordinate along each axis
|
Chris@16
|
250 template <size_t K> struct axis; where Metafunction<axis>;
|
Chris@16
|
251
|
Chris@16
|
252 const size_t num_dimensions;
|
Chris@16
|
253
|
Chris@16
|
254 // accessor/modifier of the value of each axis.
|
Chris@16
|
255 template <size_t K> const typename axis<K>::type& T::axis_value() const;
|
Chris@16
|
256 template <size_t K> typename axis<K>::type& T::axis_value();
|
Chris@16
|
257 };
|
Chris@16
|
258 \endcode
|
Chris@16
|
259 */
|
Chris@16
|
260
|
Chris@16
|
261 template <typename P>
|
Chris@16
|
262 struct PointNDConcept {
|
Chris@16
|
263 void constraints() {
|
Chris@16
|
264 gil_function_requires< Regular<P> >();
|
Chris@16
|
265
|
Chris@16
|
266 typedef typename P::value_type value_type;
|
Chris@16
|
267 static const std::size_t N=P::num_dimensions; ignore_unused_variable_warning(N);
|
Chris@16
|
268 typedef typename P::template axis<0>::coord_t FT;
|
Chris@16
|
269 typedef typename P::template axis<N-1>::coord_t LT;
|
Chris@16
|
270 FT ft=gil::axis_value<0>(point);
|
Chris@16
|
271 axis_value<0>(point)=ft;
|
Chris@16
|
272 LT lt=axis_value<N-1>(point);
|
Chris@16
|
273 axis_value<N-1>(point)=lt;
|
Chris@16
|
274
|
Chris@16
|
275 value_type v=point[0]; ignore_unused_variable_warning(v);
|
Chris@16
|
276 point[0]=point[0];
|
Chris@16
|
277 }
|
Chris@16
|
278 P point;
|
Chris@16
|
279 };
|
Chris@16
|
280
|
Chris@16
|
281 /// \brief 2-dimensional point concept
|
Chris@16
|
282 /// \ingroup PointConcept
|
Chris@16
|
283 /**
|
Chris@16
|
284 \code
|
Chris@16
|
285 concept Point2DConcept<typename T> : PointNDConcept<T> {
|
Chris@16
|
286 where num_dimensions == 2;
|
Chris@16
|
287 where SameType<axis<0>::type, axis<1>::type>;
|
Chris@16
|
288
|
Chris@16
|
289 typename value_type = axis<0>::type;
|
Chris@16
|
290
|
Chris@16
|
291 const value_type& operator[](const T&, size_t i);
|
Chris@16
|
292 value_type& operator[]( T&, size_t i);
|
Chris@16
|
293
|
Chris@16
|
294 value_type x,y;
|
Chris@16
|
295 };
|
Chris@16
|
296 \endcode
|
Chris@16
|
297 */
|
Chris@16
|
298
|
Chris@16
|
299 template <typename P>
|
Chris@16
|
300 struct Point2DConcept {
|
Chris@16
|
301 void constraints() {
|
Chris@16
|
302 gil_function_requires< PointNDConcept<P> >();
|
Chris@16
|
303 BOOST_STATIC_ASSERT(P::num_dimensions == 2);
|
Chris@16
|
304 point.x=point.y;
|
Chris@16
|
305 point[0]=point[1];
|
Chris@16
|
306 }
|
Chris@16
|
307 P point;
|
Chris@16
|
308 };
|
Chris@16
|
309
|
Chris@16
|
310 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
311 //
|
Chris@16
|
312 // ITERATOR MUTABILITY CONCEPTS
|
Chris@16
|
313 //
|
Chris@16
|
314 // Taken from boost's concept_check.hpp. Isolating mutability to result in faster compile time
|
Chris@16
|
315 //
|
Chris@16
|
316 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
317
|
Chris@16
|
318 namespace detail {
|
Chris@16
|
319 template <class TT> // Preconditions: TT Models boost_concepts::ForwardTraversalConcept
|
Chris@16
|
320 struct ForwardIteratorIsMutableConcept {
|
Chris@16
|
321 void constraints() {
|
Chris@16
|
322 *i++ = *i; // require postincrement and assignment
|
Chris@16
|
323 }
|
Chris@16
|
324 TT i;
|
Chris@16
|
325 };
|
Chris@16
|
326
|
Chris@16
|
327 template <class TT> // Preconditions: TT Models boost::BidirectionalIteratorConcept
|
Chris@16
|
328 struct BidirectionalIteratorIsMutableConcept {
|
Chris@16
|
329 void constraints() {
|
Chris@16
|
330 gil_function_requires< ForwardIteratorIsMutableConcept<TT> >();
|
Chris@16
|
331 *i-- = *i; // require postdecrement and assignment
|
Chris@16
|
332 }
|
Chris@16
|
333 TT i;
|
Chris@16
|
334 };
|
Chris@16
|
335
|
Chris@16
|
336 template <class TT> // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept
|
Chris@16
|
337 struct RandomAccessIteratorIsMutableConcept {
|
Chris@16
|
338 void constraints() {
|
Chris@16
|
339 gil_function_requires< BidirectionalIteratorIsMutableConcept<TT> >();
|
Chris@16
|
340 typename std::iterator_traits<TT>::difference_type n=0; ignore_unused_variable_warning(n);
|
Chris@16
|
341 i[n] = *i; // require element access and assignment
|
Chris@16
|
342 }
|
Chris@16
|
343 TT i;
|
Chris@16
|
344 };
|
Chris@16
|
345 } // namespace detail
|
Chris@16
|
346
|
Chris@16
|
347 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
348 //
|
Chris@16
|
349 // COLOR SPACE CONCEPTS
|
Chris@16
|
350 //
|
Chris@16
|
351 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
352
|
Chris@16
|
353 /// \brief Color space type concept
|
Chris@16
|
354 /// \ingroup ColorSpaceAndLayoutConcept
|
Chris@16
|
355 /**
|
Chris@16
|
356 \code
|
Chris@16
|
357 concept ColorSpaceConcept<MPLRandomAccessSequence Cs> {
|
Chris@16
|
358 // An MPL Random Access Sequence, whose elements are color tags
|
Chris@16
|
359 };
|
Chris@16
|
360 \endcode
|
Chris@16
|
361 */
|
Chris@16
|
362 template <typename Cs>
|
Chris@16
|
363 struct ColorSpaceConcept {
|
Chris@16
|
364 void constraints() {
|
Chris@16
|
365 // An MPL Random Access Sequence, whose elements are color tags
|
Chris@16
|
366 }
|
Chris@16
|
367 };
|
Chris@16
|
368
|
Chris@16
|
369 template <typename ColorSpace1, typename ColorSpace2> // Models ColorSpaceConcept
|
Chris@16
|
370 struct color_spaces_are_compatible : public is_same<ColorSpace1,ColorSpace2> {};
|
Chris@16
|
371
|
Chris@16
|
372 /// \brief Two color spaces are compatible if they are the same
|
Chris@16
|
373 /// \ingroup ColorSpaceAndLayoutConcept
|
Chris@16
|
374 /**
|
Chris@16
|
375 \code
|
Chris@16
|
376 concept ColorSpacesCompatibleConcept<ColorSpaceConcept Cs1, ColorSpaceConcept Cs2> {
|
Chris@16
|
377 where SameType<Cs1,Cs2>;
|
Chris@16
|
378 };
|
Chris@16
|
379 \endcode
|
Chris@16
|
380 */
|
Chris@16
|
381 template <typename Cs1, typename Cs2>
|
Chris@16
|
382 struct ColorSpacesCompatibleConcept {
|
Chris@16
|
383 void constraints() {
|
Chris@16
|
384 BOOST_STATIC_ASSERT((color_spaces_are_compatible<Cs1,Cs2>::value));
|
Chris@16
|
385 }
|
Chris@16
|
386 };
|
Chris@16
|
387
|
Chris@16
|
388 /// \brief Channel mapping concept
|
Chris@16
|
389 /// \ingroup ColorSpaceAndLayoutConcept
|
Chris@16
|
390 /**
|
Chris@16
|
391 \code
|
Chris@16
|
392 concept ChannelMappingConcept<MPLRandomAccessSequence CM> {
|
Chris@16
|
393 // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
|
Chris@16
|
394 };
|
Chris@16
|
395 \endcode
|
Chris@16
|
396 */
|
Chris@16
|
397 template <typename CM>
|
Chris@16
|
398 struct ChannelMappingConcept {
|
Chris@16
|
399 void constraints() {
|
Chris@16
|
400 // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
|
Chris@16
|
401 }
|
Chris@16
|
402 };
|
Chris@16
|
403
|
Chris@16
|
404
|
Chris@16
|
405
|
Chris@16
|
406 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
407 ///
|
Chris@16
|
408 /// Channel CONCEPTS
|
Chris@16
|
409 ///
|
Chris@16
|
410 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
411
|
Chris@16
|
412 /// \ingroup ChannelConcept
|
Chris@16
|
413 /// \brief A channel is the building block of a color. Color is defined as a mixture of primary colors and a channel defines the degree to which each primary color is used in the mixture.
|
Chris@16
|
414 /**
|
Chris@16
|
415 For example, in the RGB color space, using 8-bit unsigned channels, the color red is defined as [255 0 0], which means maximum of Red, and no Green and Blue.
|
Chris@16
|
416
|
Chris@16
|
417 Built-in scalar types, such as \p int and \p float, are valid GIL channels. In more complex scenarios, channels may be represented as bit ranges or even individual bits.
|
Chris@16
|
418 In such cases special classes are needed to represent the value and reference to a channel.
|
Chris@16
|
419
|
Chris@16
|
420 Channels have a traits class, \p channel_traits, which defines their associated types as well as their operating ranges.
|
Chris@16
|
421
|
Chris@16
|
422 \code
|
Chris@16
|
423 concept ChannelConcept<typename T> : EqualityComparable<T> {
|
Chris@16
|
424 typename value_type = T; // use channel_traits<T>::value_type to access it
|
Chris@16
|
425 typename reference = T&; // use channel_traits<T>::reference to access it
|
Chris@16
|
426 typename pointer = T*; // use channel_traits<T>::pointer to access it
|
Chris@16
|
427 typename const_reference = const T&; // use channel_traits<T>::const_reference to access it
|
Chris@16
|
428 typename const_pointer = const T*; // use channel_traits<T>::const_pointer to access it
|
Chris@16
|
429 static const bool is_mutable; // use channel_traits<T>::is_mutable to access it
|
Chris@16
|
430
|
Chris@16
|
431 static T min_value(); // use channel_traits<T>::min_value to access it
|
Chris@16
|
432 static T max_value(); // use channel_traits<T>::min_value to access it
|
Chris@16
|
433 };
|
Chris@16
|
434 \endcode
|
Chris@16
|
435 */
|
Chris@16
|
436 template <typename T>
|
Chris@16
|
437 struct ChannelConcept {
|
Chris@16
|
438 void constraints() {
|
Chris@16
|
439 gil_function_requires< boost::EqualityComparableConcept<T> >();
|
Chris@16
|
440
|
Chris@16
|
441 typedef typename channel_traits<T>::value_type v;
|
Chris@16
|
442 typedef typename channel_traits<T>::reference r;
|
Chris@16
|
443 typedef typename channel_traits<T>::pointer p;
|
Chris@16
|
444 typedef typename channel_traits<T>::const_reference cr;
|
Chris@16
|
445 typedef typename channel_traits<T>::const_pointer cp;
|
Chris@16
|
446
|
Chris@16
|
447 channel_traits<T>::min_value();
|
Chris@16
|
448 channel_traits<T>::max_value();
|
Chris@16
|
449 }
|
Chris@16
|
450
|
Chris@16
|
451 T c;
|
Chris@16
|
452 };
|
Chris@16
|
453
|
Chris@16
|
454 namespace detail {
|
Chris@16
|
455 // Preconditions: T models ChannelConcept
|
Chris@16
|
456 template <typename T>
|
Chris@16
|
457 struct ChannelIsMutableConcept {
|
Chris@16
|
458 void constraints() {
|
Chris@16
|
459 c=c;
|
Chris@16
|
460 using std::swap;
|
Chris@16
|
461 swap(c,c);
|
Chris@16
|
462 }
|
Chris@16
|
463 T c;
|
Chris@16
|
464 };
|
Chris@16
|
465 }
|
Chris@16
|
466
|
Chris@16
|
467 /// \brief A channel that allows for modifying its value
|
Chris@16
|
468 /// \ingroup ChannelConcept
|
Chris@16
|
469 /**
|
Chris@16
|
470 \code
|
Chris@16
|
471 concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
|
Chris@16
|
472 \endcode
|
Chris@16
|
473 */
|
Chris@16
|
474 template <typename T>
|
Chris@16
|
475 struct MutableChannelConcept {
|
Chris@16
|
476 void constraints() {
|
Chris@16
|
477 gil_function_requires<ChannelConcept<T> >();
|
Chris@16
|
478 gil_function_requires<detail::ChannelIsMutableConcept<T> >();
|
Chris@16
|
479 }
|
Chris@16
|
480 };
|
Chris@16
|
481
|
Chris@16
|
482 /// \brief A channel that supports default construction.
|
Chris@16
|
483 /// \ingroup ChannelConcept
|
Chris@16
|
484 /**
|
Chris@16
|
485 \code
|
Chris@16
|
486 concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
|
Chris@16
|
487 \endcode
|
Chris@16
|
488 */
|
Chris@16
|
489 template <typename T>
|
Chris@16
|
490 struct ChannelValueConcept {
|
Chris@16
|
491 void constraints() {
|
Chris@16
|
492 gil_function_requires<ChannelConcept<T> >();
|
Chris@16
|
493 gil_function_requires<Regular<T> >();
|
Chris@16
|
494 }
|
Chris@16
|
495 };
|
Chris@16
|
496
|
Chris@16
|
497
|
Chris@16
|
498 /// \brief Predicate metafunction returning whether two channels are compatible
|
Chris@16
|
499 /// \ingroup ChannelAlgorithm
|
Chris@16
|
500 ///
|
Chris@16
|
501 /// Channels are considered compatible if their value types (ignoring constness and references) are the same.
|
Chris@16
|
502 /**
|
Chris@16
|
503 Example:
|
Chris@16
|
504
|
Chris@16
|
505 \code
|
Chris@16
|
506 BOOST_STATIC_ASSERT((channels_are_compatible<bits8, const bits8&>::value));
|
Chris@16
|
507 \endcode
|
Chris@16
|
508 */
|
Chris@16
|
509 template <typename T1, typename T2> // Models GIL Pixel
|
Chris@16
|
510 struct channels_are_compatible
|
Chris@16
|
511 : public is_same<typename channel_traits<T1>::value_type, typename channel_traits<T2>::value_type> {};
|
Chris@16
|
512
|
Chris@16
|
513 /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
|
Chris@16
|
514 /// \ingroup ChannelConcept
|
Chris@16
|
515 /**
|
Chris@16
|
516 \code
|
Chris@16
|
517 concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2> {
|
Chris@16
|
518 where SameType<T1::value_type, T2::value_type>;
|
Chris@16
|
519 };
|
Chris@16
|
520 \endcode
|
Chris@16
|
521 */
|
Chris@16
|
522 template <typename T1, typename T2>
|
Chris@16
|
523 struct ChannelsCompatibleConcept {
|
Chris@16
|
524 void constraints() {
|
Chris@16
|
525 BOOST_STATIC_ASSERT((channels_are_compatible<T1,T2>::value));
|
Chris@16
|
526 }
|
Chris@16
|
527 };
|
Chris@16
|
528
|
Chris@16
|
529 /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels
|
Chris@16
|
530 ///
|
Chris@16
|
531 /// Convertibility is non-symmetric and implies that one channel can be converted to another. Conversion is explicit and often lossy operation.
|
Chris@16
|
532 /// \ingroup ChannelConcept
|
Chris@16
|
533 /**
|
Chris@16
|
534 \code
|
Chris@16
|
535 concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel> {
|
Chris@16
|
536 DstChannel channel_convert(const SrcChannel&);
|
Chris@16
|
537 };
|
Chris@16
|
538 \endcode
|
Chris@16
|
539 */
|
Chris@16
|
540 template <typename SrcChannel, typename DstChannel>
|
Chris@16
|
541 struct ChannelConvertibleConcept {
|
Chris@16
|
542 void constraints() {
|
Chris@16
|
543 gil_function_requires<ChannelConcept<SrcChannel> >();
|
Chris@16
|
544 gil_function_requires<MutableChannelConcept<DstChannel> >();
|
Chris@16
|
545 dst=channel_convert<DstChannel,SrcChannel>(src); ignore_unused_variable_warning(dst);
|
Chris@16
|
546 }
|
Chris@16
|
547 SrcChannel src;
|
Chris@16
|
548 DstChannel dst;
|
Chris@16
|
549 };
|
Chris@16
|
550
|
Chris@16
|
551
|
Chris@16
|
552
|
Chris@16
|
553
|
Chris@16
|
554
|
Chris@16
|
555 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
556 ///
|
Chris@16
|
557 /// COLOR BASE CONCEPTS
|
Chris@16
|
558 ///
|
Chris@16
|
559 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
560
|
Chris@16
|
561 /// \ingroup ColorBaseConcept
|
Chris@16
|
562 /// \brief A color base is a container of color elements (such as channels, channel references or channel pointers)
|
Chris@16
|
563 /**
|
Chris@16
|
564 The most common use of color base is in the implementation of a pixel, in which case the color
|
Chris@16
|
565 elements are channel values. The color base concept, however, can be used in other scenarios. For example, a planar pixel has channels that are not
|
Chris@16
|
566 contiguous in memory. Its reference is a proxy class that uses a color base whose elements are channel references. Its iterator uses a color base
|
Chris@16
|
567 whose elements are channel iterators.
|
Chris@16
|
568
|
Chris@16
|
569 A color base must have an associated layout (which consists of a color space, as well as an ordering of the channels).
|
Chris@16
|
570 There are two ways to index the elements of a color base: A physical index corresponds to the way they are ordered in memory, and
|
Chris@16
|
571 a semantic index corresponds to the way the elements are ordered in their color space.
|
Chris@16
|
572 For example, in the RGB color space the elements are ordered as {red_t, green_t, blue_t}. For a color base with a BGR layout, the first element
|
Chris@16
|
573 in physical ordering is the blue element, whereas the first semantic element is the red one.
|
Chris@16
|
574 Models of \p ColorBaseConcept are required to provide the \p at_c<K>(ColorBase) function, which allows for accessing the elements based on their
|
Chris@16
|
575 physical order. GIL provides a \p semantic_at_c<K>(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns
|
Chris@16
|
576 the corresponding semantic element.
|
Chris@16
|
577
|
Chris@16
|
578 \code
|
Chris@16
|
579 concept ColorBaseConcept<typename T> : CopyConstructible<T>, EqualityComparable<T> {
|
Chris@16
|
580 // a GIL layout (the color space and element permutation)
|
Chris@16
|
581 typename layout_t;
|
Chris@16
|
582
|
Chris@16
|
583 // The type of K-th element
|
Chris@16
|
584 template <int K> struct kth_element_type; where Metafunction<kth_element_type>;
|
Chris@16
|
585
|
Chris@16
|
586 // The result of at_c
|
Chris@16
|
587 template <int K> struct kth_element_const_reference_type; where Metafunction<kth_element_const_reference_type>;
|
Chris@16
|
588
|
Chris@16
|
589 template <int K> kth_element_const_reference_type<T,K>::type at_c(T);
|
Chris@16
|
590
|
Chris@16
|
591 // Copy-constructible and equality comparable with other compatible color bases
|
Chris@16
|
592 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
|
Chris@16
|
593 T::T(T2);
|
Chris@16
|
594 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
|
Chris@16
|
595 bool operator==(const T&, const T2&);
|
Chris@16
|
596 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
|
Chris@16
|
597 bool operator!=(const T&, const T2&);
|
Chris@16
|
598
|
Chris@16
|
599 };
|
Chris@16
|
600 \endcode
|
Chris@16
|
601 */
|
Chris@16
|
602
|
Chris@16
|
603 template <typename ColorBase>
|
Chris@16
|
604 struct ColorBaseConcept {
|
Chris@16
|
605 void constraints() {
|
Chris@16
|
606 gil_function_requires< CopyConstructible<ColorBase> >();
|
Chris@16
|
607 gil_function_requires< EqualityComparable<ColorBase> >();
|
Chris@16
|
608
|
Chris@16
|
609 typedef typename ColorBase::layout_t::color_space_t color_space_t;
|
Chris@16
|
610 gil_function_requires<ColorSpaceConcept<color_space_t> >();
|
Chris@16
|
611
|
Chris@16
|
612 typedef typename ColorBase::layout_t::channel_mapping_t channel_mapping_t;
|
Chris@16
|
613 // TODO: channel_mapping_t must be an MPL RandomAccessSequence
|
Chris@16
|
614
|
Chris@16
|
615 static const std::size_t num_elements = size<ColorBase>::value;
|
Chris@16
|
616
|
Chris@16
|
617 typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
|
Chris@16
|
618 typedef typename kth_element_const_reference_type<ColorBase,num_elements-1>::type CR;
|
Chris@16
|
619
|
Chris@16
|
620 #if !defined(_MSC_VER) || _MSC_VER > 1310
|
Chris@16
|
621 CR cr=at_c<num_elements-1>(cb); ignore_unused_variable_warning(cr);
|
Chris@16
|
622 #endif
|
Chris@16
|
623
|
Chris@16
|
624 // functions that work for every pixel (no need to require them)
|
Chris@16
|
625 semantic_at_c<0>(cb);
|
Chris@16
|
626 semantic_at_c<num_elements-1>(cb);
|
Chris@16
|
627 // also static_max(cb), static_min(cb), static_fill(cb,value), and all variations of static_for_each(), static_generate(), static_transform()
|
Chris@16
|
628 }
|
Chris@16
|
629
|
Chris@16
|
630 ColorBase cb;
|
Chris@16
|
631 };
|
Chris@16
|
632
|
Chris@16
|
633 /// \ingroup ColorBaseConcept
|
Chris@16
|
634 /// \brief Color base which allows for modifying its elements
|
Chris@16
|
635 /**
|
Chris@16
|
636
|
Chris@16
|
637 \code
|
Chris@16
|
638 concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T> {
|
Chris@16
|
639 template <int K> struct kth_element_reference_type; where Metafunction<kth_element_reference_type>;
|
Chris@16
|
640
|
Chris@16
|
641 template <int K> kth_element_reference_type<kth_element_type<T,K>::type>::type at_c(T);
|
Chris@16
|
642
|
Chris@16
|
643 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
|
Chris@16
|
644 T& operator=(T&, const T2&);
|
Chris@16
|
645 };
|
Chris@16
|
646 \endcode
|
Chris@16
|
647 */
|
Chris@16
|
648 template <typename ColorBase>
|
Chris@16
|
649 struct MutableColorBaseConcept {
|
Chris@16
|
650 void constraints() {
|
Chris@16
|
651 gil_function_requires< ColorBaseConcept<ColorBase> >();
|
Chris@16
|
652 gil_function_requires< Assignable<ColorBase> >();
|
Chris@16
|
653 gil_function_requires< Swappable<ColorBase> >();
|
Chris@16
|
654
|
Chris@16
|
655 typedef typename kth_element_reference_type<ColorBase, 0>::type CR;
|
Chris@16
|
656
|
Chris@16
|
657 #if !defined(_MSC_VER) || _MSC_VER > 1310
|
Chris@16
|
658 CR r=at_c<0>(cb);
|
Chris@16
|
659 at_c<0>(cb)=r;
|
Chris@16
|
660 #endif
|
Chris@16
|
661 }
|
Chris@16
|
662
|
Chris@16
|
663 ColorBase cb;
|
Chris@16
|
664 };
|
Chris@16
|
665
|
Chris@16
|
666 /// \ingroup ColorBaseConcept
|
Chris@16
|
667 /// \brief Color base that also has a default-constructor. Refines Regular
|
Chris@16
|
668 /**
|
Chris@16
|
669 \code
|
Chris@16
|
670 concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T> {
|
Chris@16
|
671 };
|
Chris@16
|
672 \endcode
|
Chris@16
|
673 */
|
Chris@16
|
674 template <typename ColorBase>
|
Chris@16
|
675 struct ColorBaseValueConcept {
|
Chris@16
|
676 void constraints() {
|
Chris@16
|
677 gil_function_requires< MutableColorBaseConcept<ColorBase> >();
|
Chris@16
|
678 gil_function_requires< Regular<ColorBase> >();
|
Chris@16
|
679 }
|
Chris@16
|
680 };
|
Chris@16
|
681
|
Chris@16
|
682 /// \ingroup ColorBaseConcept
|
Chris@16
|
683 /// \brief Color base whose elements all have the same type
|
Chris@16
|
684 /**
|
Chris@16
|
685 \code
|
Chris@16
|
686 concept HomogeneousColorBaseConcept<ColorBaseConcept CB> {
|
Chris@16
|
687 // For all K in [0 ... size<C1>::value-1):
|
Chris@16
|
688 // where SameType<kth_element_type<CB,K>::type, kth_element_type<CB,K+1>::type>;
|
Chris@16
|
689 kth_element_const_reference_type<CB,0>::type dynamic_at_c(const CB&, std::size_t n) const;
|
Chris@16
|
690 };
|
Chris@16
|
691 \endcode
|
Chris@16
|
692 */
|
Chris@16
|
693
|
Chris@16
|
694 template <typename ColorBase>
|
Chris@16
|
695 struct HomogeneousColorBaseConcept {
|
Chris@16
|
696 void constraints() {
|
Chris@16
|
697 gil_function_requires< ColorBaseConcept<ColorBase> >();
|
Chris@16
|
698
|
Chris@16
|
699 static const std::size_t num_elements = size<ColorBase>::value;
|
Chris@16
|
700
|
Chris@16
|
701 typedef typename kth_element_type<ColorBase,0>::type T0;
|
Chris@16
|
702 typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
|
Chris@16
|
703
|
Chris@16
|
704 BOOST_STATIC_ASSERT((is_same<T0,TN>::value)); // better than nothing
|
Chris@16
|
705 typedef typename kth_element_const_reference_type<ColorBase,0>::type CRef0;
|
Chris@16
|
706 CRef0 e0=dynamic_at_c(cb,0);
|
Chris@16
|
707 }
|
Chris@16
|
708 ColorBase cb;
|
Chris@16
|
709 };
|
Chris@16
|
710
|
Chris@16
|
711 /// \ingroup ColorBaseConcept
|
Chris@16
|
712 /// \brief Homogeneous color base that allows for modifying its elements
|
Chris@16
|
713 /**
|
Chris@16
|
714
|
Chris@16
|
715 \code
|
Chris@16
|
716 concept MutableHomogeneousColorBaseConcept<ColorBaseConcept CB> : HomogeneousColorBaseConcept<CB> {
|
Chris@16
|
717 kth_element_reference_type<CB,0>::type dynamic_at_c(CB&, std::size_t n);
|
Chris@16
|
718 };
|
Chris@16
|
719 \endcode
|
Chris@16
|
720 */
|
Chris@16
|
721
|
Chris@16
|
722 template <typename ColorBase>
|
Chris@16
|
723 struct MutableHomogeneousColorBaseConcept {
|
Chris@16
|
724 void constraints() {
|
Chris@16
|
725 gil_function_requires< ColorBaseConcept<ColorBase> >();
|
Chris@16
|
726 gil_function_requires< HomogeneousColorBaseConcept<ColorBase> >();
|
Chris@16
|
727 typedef typename kth_element_reference_type<ColorBase, 0>::type R0;
|
Chris@16
|
728 R0 x=dynamic_at_c(cb,0);
|
Chris@16
|
729 dynamic_at_c(cb,0) = dynamic_at_c(cb,0);
|
Chris@16
|
730 }
|
Chris@16
|
731 ColorBase cb;
|
Chris@16
|
732 };
|
Chris@16
|
733
|
Chris@16
|
734 /// \ingroup ColorBaseConcept
|
Chris@16
|
735 /// \brief Homogeneous color base that also has a default constructor. Refines Regular.
|
Chris@16
|
736 /**
|
Chris@16
|
737
|
Chris@16
|
738 \code
|
Chris@16
|
739 concept HomogeneousColorBaseValueConcept<typename T> : MutableHomogeneousColorBaseConcept<T>, Regular<T> {
|
Chris@16
|
740 };
|
Chris@16
|
741 \endcode
|
Chris@16
|
742 */
|
Chris@16
|
743
|
Chris@16
|
744 template <typename ColorBase>
|
Chris@16
|
745 struct HomogeneousColorBaseValueConcept {
|
Chris@16
|
746 void constraints() {
|
Chris@16
|
747 gil_function_requires< MutableHomogeneousColorBaseConcept<ColorBase> >();
|
Chris@16
|
748 gil_function_requires< Regular<ColorBase> >();
|
Chris@16
|
749 }
|
Chris@16
|
750 };
|
Chris@16
|
751
|
Chris@16
|
752
|
Chris@16
|
753 /// \ingroup ColorBaseConcept
|
Chris@16
|
754 /// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise.
|
Chris@16
|
755 /**
|
Chris@16
|
756
|
Chris@16
|
757 \code
|
Chris@16
|
758 concept ColorBasesCompatibleConcept<ColorBaseConcept C1, ColorBaseConcept C2> {
|
Chris@16
|
759 where SameType<C1::layout_t::color_space_t, C2::layout_t::color_space_t>;
|
Chris@16
|
760 // also, for all K in [0 ... size<C1>::value):
|
Chris@16
|
761 // where Convertible<kth_semantic_element_type<C1,K>::type, kth_semantic_element_type<C2,K>::type>;
|
Chris@16
|
762 // where Convertible<kth_semantic_element_type<C2,K>::type, kth_semantic_element_type<C1,K>::type>;
|
Chris@16
|
763 };
|
Chris@16
|
764 \endcode
|
Chris@16
|
765 */
|
Chris@16
|
766 template <typename ColorBase1, typename ColorBase2>
|
Chris@16
|
767 struct ColorBasesCompatibleConcept {
|
Chris@16
|
768 void constraints() {
|
Chris@16
|
769 BOOST_STATIC_ASSERT((is_same<typename ColorBase1::layout_t::color_space_t,
|
Chris@16
|
770 typename ColorBase2::layout_t::color_space_t>::value));
|
Chris@16
|
771 // typedef typename kth_semantic_element_type<ColorBase1,0>::type e1;
|
Chris@16
|
772 // typedef typename kth_semantic_element_type<ColorBase2,0>::type e2;
|
Chris@16
|
773 // "e1 is convertible to e2"
|
Chris@16
|
774 }
|
Chris@16
|
775 };
|
Chris@16
|
776
|
Chris@16
|
777
|
Chris@16
|
778
|
Chris@16
|
779
|
Chris@16
|
780
|
Chris@16
|
781
|
Chris@16
|
782
|
Chris@16
|
783
|
Chris@16
|
784
|
Chris@16
|
785
|
Chris@16
|
786
|
Chris@16
|
787
|
Chris@16
|
788
|
Chris@16
|
789
|
Chris@16
|
790
|
Chris@16
|
791
|
Chris@16
|
792
|
Chris@16
|
793
|
Chris@16
|
794
|
Chris@16
|
795
|
Chris@16
|
796
|
Chris@16
|
797
|
Chris@16
|
798 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
799 ///
|
Chris@16
|
800 /// PIXEL CONCEPTS
|
Chris@16
|
801 ///
|
Chris@16
|
802 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
803
|
Chris@16
|
804 /// \brief Concept for all pixel-based GIL constructs, such as pixels, iterators, locators, views and images whose value type is a pixel
|
Chris@16
|
805 /// \ingroup PixelBasedConcept
|
Chris@16
|
806 /**
|
Chris@16
|
807 \code
|
Chris@16
|
808 concept PixelBasedConcept<typename T> {
|
Chris@16
|
809 typename color_space_type<T>;
|
Chris@16
|
810 where Metafunction<color_space_type<T> >;
|
Chris@16
|
811 where ColorSpaceConcept<color_space_type<T>::type>;
|
Chris@16
|
812 typename channel_mapping_type<T>;
|
Chris@16
|
813 where Metafunction<channel_mapping_type<T> >;
|
Chris@16
|
814 where ChannelMappingConcept<channel_mapping_type<T>::type>;
|
Chris@16
|
815 typename is_planar<T>;
|
Chris@16
|
816 where Metafunction<is_planar<T> >;
|
Chris@16
|
817 where SameType<is_planar<T>::type, bool>;
|
Chris@16
|
818 };
|
Chris@16
|
819 \endcode
|
Chris@16
|
820 */
|
Chris@16
|
821 template <typename P>
|
Chris@16
|
822 struct PixelBasedConcept {
|
Chris@16
|
823 void constraints() {
|
Chris@16
|
824 typedef typename color_space_type<P>::type color_space_t;
|
Chris@16
|
825 gil_function_requires<ColorSpaceConcept<color_space_t> >();
|
Chris@16
|
826 typedef typename channel_mapping_type<P>::type channel_mapping_t;
|
Chris@16
|
827 gil_function_requires<ChannelMappingConcept<channel_mapping_t> >();
|
Chris@16
|
828
|
Chris@16
|
829 static const bool planar = is_planar<P>::type::value; ignore_unused_variable_warning(planar);
|
Chris@16
|
830
|
Chris@16
|
831
|
Chris@16
|
832 // This is not part of the concept, but should still work
|
Chris@16
|
833 static const std::size_t nc = num_channels<P>::value;
|
Chris@16
|
834 ignore_unused_variable_warning(nc);
|
Chris@16
|
835 }
|
Chris@16
|
836 };
|
Chris@16
|
837
|
Chris@16
|
838 /// \brief Concept for homogeneous pixel-based GIL constructs
|
Chris@16
|
839 /// \ingroup PixelBasedConcept
|
Chris@16
|
840 /**
|
Chris@16
|
841 \code
|
Chris@16
|
842 concept HomogeneousPixelBasedConcept<PixelBasedConcept T> {
|
Chris@16
|
843 typename channel_type<T>;
|
Chris@16
|
844 where Metafunction<channel_type<T> >;
|
Chris@16
|
845 where ChannelConcept<channel_type<T>::type>;
|
Chris@16
|
846 };
|
Chris@16
|
847 \endcode
|
Chris@16
|
848 */
|
Chris@16
|
849 template <typename P>
|
Chris@16
|
850 struct HomogeneousPixelBasedConcept {
|
Chris@16
|
851 void constraints() {
|
Chris@16
|
852 gil_function_requires<PixelBasedConcept<P> >();
|
Chris@16
|
853 typedef typename channel_type<P>::type channel_t;
|
Chris@16
|
854 gil_function_requires<ChannelConcept<channel_t> >();
|
Chris@16
|
855 }
|
Chris@16
|
856 };
|
Chris@16
|
857
|
Chris@16
|
858
|
Chris@16
|
859 /// \brief Pixel concept - A color base whose elements are channels
|
Chris@16
|
860 /// \ingroup PixelConcept
|
Chris@16
|
861 /**
|
Chris@16
|
862 \code
|
Chris@16
|
863 concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P> {
|
Chris@16
|
864 where is_pixel<P>::type::value==true;
|
Chris@16
|
865 // where for each K [0..size<P>::value-1]:
|
Chris@16
|
866 // ChannelConcept<kth_element_type<P,K> >;
|
Chris@16
|
867
|
Chris@16
|
868 typename P::value_type; where PixelValueConcept<value_type>;
|
Chris@16
|
869 typename P::reference; where PixelConcept<reference>;
|
Chris@16
|
870 typename P::const_reference; where PixelConcept<const_reference>;
|
Chris@16
|
871 static const bool P::is_mutable;
|
Chris@16
|
872
|
Chris@16
|
873 template <PixelConcept P2> where { PixelConcept<P,P2> }
|
Chris@16
|
874 P::P(P2);
|
Chris@16
|
875 template <PixelConcept P2> where { PixelConcept<P,P2> }
|
Chris@16
|
876 bool operator==(const P&, const P2&);
|
Chris@16
|
877 template <PixelConcept P2> where { PixelConcept<P,P2> }
|
Chris@16
|
878 bool operator!=(const P&, const P2&);
|
Chris@16
|
879 };
|
Chris@16
|
880 \endcode
|
Chris@16
|
881 */
|
Chris@16
|
882
|
Chris@16
|
883 template <typename P>
|
Chris@16
|
884 struct PixelConcept {
|
Chris@16
|
885 void constraints() {
|
Chris@16
|
886 gil_function_requires<ColorBaseConcept<P> >();
|
Chris@16
|
887 gil_function_requires<PixelBasedConcept<P> >();
|
Chris@16
|
888
|
Chris@16
|
889 BOOST_STATIC_ASSERT((is_pixel<P>::value));
|
Chris@16
|
890 static const bool is_mutable = P::is_mutable; ignore_unused_variable_warning(is_mutable);
|
Chris@16
|
891
|
Chris@16
|
892 typedef typename P::value_type value_type;
|
Chris@16
|
893 // gil_function_requires<PixelValueConcept<value_type> >();
|
Chris@16
|
894
|
Chris@16
|
895 typedef typename P::reference reference;
|
Chris@16
|
896 gil_function_requires<PixelConcept<typename remove_const_and_reference<reference>::type> >();
|
Chris@16
|
897
|
Chris@16
|
898 typedef typename P::const_reference const_reference;
|
Chris@16
|
899 gil_function_requires<PixelConcept<typename remove_const_and_reference<const_reference>::type> >();
|
Chris@16
|
900 }
|
Chris@16
|
901 };
|
Chris@16
|
902
|
Chris@16
|
903
|
Chris@16
|
904 /// \brief Pixel concept that allows for changing its channels
|
Chris@16
|
905 /// \ingroup PixelConcept
|
Chris@16
|
906 /**
|
Chris@16
|
907 \code
|
Chris@16
|
908 concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P> {
|
Chris@16
|
909 where is_mutable==true;
|
Chris@16
|
910 };
|
Chris@16
|
911 \endcode
|
Chris@16
|
912 */
|
Chris@16
|
913 template <typename P>
|
Chris@16
|
914 struct MutablePixelConcept {
|
Chris@16
|
915 void constraints() {
|
Chris@16
|
916 gil_function_requires<PixelConcept<P> >();
|
Chris@16
|
917 BOOST_STATIC_ASSERT(P::is_mutable);
|
Chris@16
|
918 }
|
Chris@16
|
919 };
|
Chris@16
|
920 /// \brief Homogeneous pixel concept
|
Chris@16
|
921 /// \ingroup PixelConcept
|
Chris@16
|
922 /**
|
Chris@16
|
923 \code
|
Chris@16
|
924 concept HomogeneousPixelConcept<PixelConcept P> : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P> {
|
Chris@16
|
925 P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const { return dynamic_at_c(p,i); }
|
Chris@16
|
926 };
|
Chris@16
|
927 \endcode
|
Chris@16
|
928 */
|
Chris@16
|
929 template <typename P>
|
Chris@16
|
930 struct HomogeneousPixelConcept {
|
Chris@16
|
931 void constraints() {
|
Chris@16
|
932 gil_function_requires<PixelConcept<P> >();
|
Chris@16
|
933 gil_function_requires<HomogeneousColorBaseConcept<P> >();
|
Chris@16
|
934 gil_function_requires<HomogeneousPixelBasedConcept<P> >();
|
Chris@16
|
935 p[0];
|
Chris@16
|
936 }
|
Chris@16
|
937 P p;
|
Chris@16
|
938 };
|
Chris@16
|
939
|
Chris@16
|
940 /// \brief Homogeneous pixel concept that allows for changing its channels
|
Chris@16
|
941 /// \ingroup PixelConcept
|
Chris@16
|
942 /**
|
Chris@16
|
943 \code
|
Chris@16
|
944 concept MutableHomogeneousPixelConcept<HomogeneousPixelConcept P> : MutableHomogeneousColorBaseConcept<P> {
|
Chris@16
|
945 P::template element_reference_type<P>::type operator[](P p, std::size_t i) { return dynamic_at_c(p,i); }
|
Chris@16
|
946 };
|
Chris@16
|
947 \endcode
|
Chris@16
|
948 */
|
Chris@16
|
949 template <typename P>
|
Chris@16
|
950 struct MutableHomogeneousPixelConcept {
|
Chris@16
|
951 void constraints() {
|
Chris@16
|
952 gil_function_requires<HomogeneousPixelConcept<P> >();
|
Chris@16
|
953 gil_function_requires<MutableHomogeneousColorBaseConcept<P> >();
|
Chris@16
|
954 p[0]=p[0];
|
Chris@16
|
955 }
|
Chris@16
|
956 P p;
|
Chris@16
|
957 };
|
Chris@16
|
958
|
Chris@16
|
959 /// \brief Pixel concept that is a Regular type
|
Chris@16
|
960 /// \ingroup PixelConcept
|
Chris@16
|
961 /**
|
Chris@16
|
962 \code
|
Chris@16
|
963 concept PixelValueConcept<PixelConcept P> : Regular<P> {
|
Chris@16
|
964 where SameType<value_type,P>;
|
Chris@16
|
965 };
|
Chris@16
|
966 \endcode
|
Chris@16
|
967 */
|
Chris@16
|
968 template <typename P>
|
Chris@16
|
969 struct PixelValueConcept {
|
Chris@16
|
970 void constraints() {
|
Chris@16
|
971 gil_function_requires<PixelConcept<P> >();
|
Chris@16
|
972 gil_function_requires<Regular<P> >();
|
Chris@16
|
973 }
|
Chris@16
|
974 };
|
Chris@16
|
975
|
Chris@16
|
976 /// \brief Homogeneous pixel concept that is a Regular type
|
Chris@16
|
977 /// \ingroup PixelConcept
|
Chris@16
|
978 /**
|
Chris@16
|
979 \code
|
Chris@16
|
980 concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P> {
|
Chris@16
|
981 where SameType<value_type,P>;
|
Chris@16
|
982 };
|
Chris@16
|
983 \endcode
|
Chris@16
|
984 */
|
Chris@16
|
985 template <typename P>
|
Chris@16
|
986 struct HomogeneousPixelValueConcept {
|
Chris@16
|
987 void constraints() {
|
Chris@16
|
988 gil_function_requires<HomogeneousPixelConcept<P> >();
|
Chris@16
|
989 gil_function_requires<Regular<P> >();
|
Chris@16
|
990 BOOST_STATIC_ASSERT((is_same<P, typename P::value_type>::value));
|
Chris@16
|
991 }
|
Chris@16
|
992 };
|
Chris@16
|
993
|
Chris@16
|
994 namespace detail {
|
Chris@16
|
995 template <typename P1, typename P2, int K>
|
Chris@16
|
996 struct channels_are_pairwise_compatible : public
|
Chris@16
|
997 mpl::and_<channels_are_pairwise_compatible<P1,P2,K-1>,
|
Chris@16
|
998 channels_are_compatible<typename kth_semantic_element_reference_type<P1,K>::type,
|
Chris@16
|
999 typename kth_semantic_element_reference_type<P2,K>::type> > {};
|
Chris@16
|
1000
|
Chris@16
|
1001 template <typename P1, typename P2>
|
Chris@16
|
1002 struct channels_are_pairwise_compatible<P1,P2,-1> : public mpl::true_ {};
|
Chris@16
|
1003 }
|
Chris@16
|
1004
|
Chris@16
|
1005 /// \brief Returns whether two pixels are compatible
|
Chris@16
|
1006 ///
|
Chris@16
|
1007 /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another.
|
Chris@16
|
1008 /// \ingroup PixelAlgorithm
|
Chris@16
|
1009 template <typename P1, typename P2> // Models GIL Pixel
|
Chris@16
|
1010 struct pixels_are_compatible
|
Chris@16
|
1011 : public mpl::and_<typename color_spaces_are_compatible<typename color_space_type<P1>::type,
|
Chris@16
|
1012 typename color_space_type<P2>::type>::type,
|
Chris@16
|
1013 detail::channels_are_pairwise_compatible<P1,P2,num_channels<P1>::value-1> > {};
|
Chris@16
|
1014
|
Chris@16
|
1015 /// \brief Concept for pixel compatibility
|
Chris@16
|
1016 /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another.
|
Chris@16
|
1017 /// \ingroup PixelConcept
|
Chris@16
|
1018 /**
|
Chris@16
|
1019 \code
|
Chris@16
|
1020 concept PixelsCompatibleConcept<PixelConcept P1, PixelConcept P2> : ColorBasesCompatibleConcept<P1,P2> {
|
Chris@16
|
1021 // where for each K [0..size<P1>::value):
|
Chris@16
|
1022 // ChannelsCompatibleConcept<kth_semantic_element_type<P1,K>::type, kth_semantic_element_type<P2,K>::type>;
|
Chris@16
|
1023 };
|
Chris@16
|
1024 \endcode
|
Chris@16
|
1025 */
|
Chris@16
|
1026 template <typename P1, typename P2> // precondition: P1 and P2 model PixelConcept
|
Chris@16
|
1027 struct PixelsCompatibleConcept {
|
Chris@16
|
1028 void constraints() {
|
Chris@16
|
1029 BOOST_STATIC_ASSERT((pixels_are_compatible<P1,P2>::value));
|
Chris@16
|
1030 }
|
Chris@16
|
1031 };
|
Chris@16
|
1032
|
Chris@16
|
1033 /// \brief Pixel convertible concept
|
Chris@16
|
1034 ///
|
Chris@16
|
1035 /// Convertibility is non-symmetric and implies that one pixel can be converted to another, approximating the color. Conversion is explicit and sometimes lossy.
|
Chris@16
|
1036 /// \ingroup PixelConcept
|
Chris@16
|
1037 /**
|
Chris@16
|
1038 \code
|
Chris@16
|
1039 template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
|
Chris@16
|
1040 concept PixelConvertibleConcept {
|
Chris@16
|
1041 void color_convert(const SrcPixel&, DstPixel&);
|
Chris@16
|
1042 };
|
Chris@16
|
1043 \endcode
|
Chris@16
|
1044 */
|
Chris@16
|
1045 template <typename SrcP, typename DstP>
|
Chris@16
|
1046 struct PixelConvertibleConcept {
|
Chris@16
|
1047 void constraints() {
|
Chris@16
|
1048 gil_function_requires<PixelConcept<SrcP> >();
|
Chris@16
|
1049 gil_function_requires<MutablePixelConcept<DstP> >();
|
Chris@16
|
1050 color_convert(src,dst);
|
Chris@16
|
1051 }
|
Chris@16
|
1052 SrcP src;
|
Chris@16
|
1053 DstP dst;
|
Chris@16
|
1054 };
|
Chris@16
|
1055
|
Chris@16
|
1056 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
1057 ///
|
Chris@16
|
1058 /// DEREFERENCE ADAPTOR CONCEPTS
|
Chris@16
|
1059 ///
|
Chris@16
|
1060 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
1061
|
Chris@16
|
1062 /// \ingroup PixelDereferenceAdaptorConcept
|
Chris@16
|
1063
|
Chris@16
|
1064 /// \brief Represents a unary function object that can be invoked upon dereferencing a pixel iterator.
|
Chris@16
|
1065 ///
|
Chris@16
|
1066 /// This can perform an arbitrary computation, such as color conversion or table lookup
|
Chris@16
|
1067 /**
|
Chris@16
|
1068 \code
|
Chris@16
|
1069 concept PixelDereferenceAdaptorConcept<boost::UnaryFunctionConcept D>
|
Chris@16
|
1070 : DefaultConstructibleConcept<D>, CopyConstructibleConcept<D>, AssignableConcept<D> {
|
Chris@16
|
1071 typename const_t; where PixelDereferenceAdaptorConcept<const_t>;
|
Chris@16
|
1072 typename value_type; where PixelValueConcept<value_type>;
|
Chris@16
|
1073 typename reference; // may be mutable
|
Chris@16
|
1074 typename const_reference; // must not be mutable
|
Chris@16
|
1075 static const bool D::is_mutable;
|
Chris@16
|
1076
|
Chris@16
|
1077 where Convertible<value_type,result_type>;
|
Chris@16
|
1078 };
|
Chris@16
|
1079 \endcode
|
Chris@16
|
1080 */
|
Chris@16
|
1081
|
Chris@16
|
1082 template <typename D>
|
Chris@16
|
1083 struct PixelDereferenceAdaptorConcept {
|
Chris@16
|
1084 void constraints() {
|
Chris@16
|
1085 gil_function_requires< boost::UnaryFunctionConcept<D,
|
Chris@16
|
1086 typename remove_const_and_reference<typename D::result_type>::type,
|
Chris@16
|
1087 typename D::argument_type> >();
|
Chris@16
|
1088 gil_function_requires< boost::DefaultConstructibleConcept<D> >();
|
Chris@16
|
1089 gil_function_requires< boost::CopyConstructibleConcept<D> >();
|
Chris@16
|
1090 gil_function_requires< boost::AssignableConcept<D> >();
|
Chris@16
|
1091
|
Chris@16
|
1092 gil_function_requires<PixelConcept<typename remove_const_and_reference<typename D::result_type>::type> >();
|
Chris@16
|
1093
|
Chris@16
|
1094 typedef typename D::const_t const_t;
|
Chris@16
|
1095 gil_function_requires<PixelDereferenceAdaptorConcept<const_t> >();
|
Chris@16
|
1096 typedef typename D::value_type value_type;
|
Chris@16
|
1097 gil_function_requires<PixelValueConcept<value_type> >();
|
Chris@16
|
1098 typedef typename D::reference reference; // == PixelConcept (if you remove const and reference)
|
Chris@16
|
1099 typedef typename D::const_reference const_reference; // == PixelConcept (if you remove const and reference)
|
Chris@16
|
1100
|
Chris@16
|
1101 const bool is_mutable=D::is_mutable; ignore_unused_variable_warning(is_mutable);
|
Chris@16
|
1102 }
|
Chris@16
|
1103 D d;
|
Chris@16
|
1104 };
|
Chris@16
|
1105
|
Chris@16
|
1106 template <typename P>
|
Chris@16
|
1107 struct PixelDereferenceAdaptorArchetype : public std::unary_function<P, P> {
|
Chris@16
|
1108 typedef PixelDereferenceAdaptorArchetype const_t;
|
Chris@16
|
1109 typedef typename remove_reference<P>::type value_type;
|
Chris@16
|
1110 typedef typename add_reference<P>::type reference;
|
Chris@16
|
1111 typedef reference const_reference;
|
Chris@16
|
1112 static const bool is_mutable=false;
|
Chris@16
|
1113 P operator()(P x) const { throw; }
|
Chris@16
|
1114 };
|
Chris@16
|
1115
|
Chris@16
|
1116 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
1117 ///
|
Chris@16
|
1118 /// Pixel ITERATOR CONCEPTS
|
Chris@16
|
1119 ///
|
Chris@16
|
1120 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
1121
|
Chris@16
|
1122 /// \brief Concept for iterators, locators and views that can define a type just like the given iterator/locator/view, except it supports runtime specified step along the X navigation
|
Chris@16
|
1123 /// \ingroup PixelIteratorConcept
|
Chris@16
|
1124 /**
|
Chris@16
|
1125 \code
|
Chris@16
|
1126 concept HasDynamicXStepTypeConcept<typename T> {
|
Chris@16
|
1127 typename dynamic_x_step_type<T>;
|
Chris@16
|
1128 where Metafunction<dynamic_x_step_type<T> >;
|
Chris@16
|
1129 };
|
Chris@16
|
1130 \endcode
|
Chris@16
|
1131 */
|
Chris@16
|
1132 template <typename T>
|
Chris@16
|
1133 struct HasDynamicXStepTypeConcept {
|
Chris@16
|
1134 void constraints() {
|
Chris@16
|
1135 typedef typename dynamic_x_step_type<T>::type type;
|
Chris@16
|
1136 }
|
Chris@16
|
1137 };
|
Chris@16
|
1138
|
Chris@16
|
1139 /// \brief Concept for locators and views that can define a type just like the given locator or view, except it supports runtime specified step along the Y navigation
|
Chris@16
|
1140 /// \ingroup PixelLocatorConcept
|
Chris@16
|
1141 /**
|
Chris@16
|
1142 \code
|
Chris@16
|
1143 concept HasDynamicYStepTypeConcept<typename T> {
|
Chris@16
|
1144 typename dynamic_y_step_type<T>;
|
Chris@16
|
1145 where Metafunction<dynamic_y_step_type<T> >;
|
Chris@16
|
1146 };
|
Chris@16
|
1147 \endcode
|
Chris@16
|
1148 */
|
Chris@16
|
1149 template <typename T>
|
Chris@16
|
1150 struct HasDynamicYStepTypeConcept {
|
Chris@16
|
1151 void constraints() {
|
Chris@16
|
1152 typedef typename dynamic_y_step_type<T>::type type;
|
Chris@16
|
1153 }
|
Chris@16
|
1154 };
|
Chris@16
|
1155
|
Chris@16
|
1156
|
Chris@16
|
1157 /// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped
|
Chris@16
|
1158 /// \ingroup PixelLocatorConcept
|
Chris@16
|
1159 /**
|
Chris@16
|
1160 \code
|
Chris@16
|
1161 concept HasTransposedTypeConcept<typename T> {
|
Chris@16
|
1162 typename transposed_type<T>;
|
Chris@16
|
1163 where Metafunction<transposed_type<T> >;
|
Chris@16
|
1164 };
|
Chris@16
|
1165 \endcode
|
Chris@16
|
1166 */
|
Chris@16
|
1167 template <typename T>
|
Chris@16
|
1168 struct HasTransposedTypeConcept {
|
Chris@16
|
1169 void constraints() {
|
Chris@16
|
1170 typedef typename transposed_type<T>::type type;
|
Chris@16
|
1171 }
|
Chris@16
|
1172 };
|
Chris@16
|
1173
|
Chris@16
|
1174 /// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept
|
Chris@16
|
1175 /// \ingroup PixelIteratorConcept
|
Chris@16
|
1176 /// \brief STL iterator over pixels
|
Chris@16
|
1177
|
Chris@16
|
1178 /// \ingroup PixelIteratorConceptPixelIterator
|
Chris@16
|
1179 /// \brief An STL random access traversal iterator over a model of PixelConcept.
|
Chris@16
|
1180 /**
|
Chris@16
|
1181 GIL's iterators must also provide the following metafunctions:
|
Chris@16
|
1182 - \p const_iterator_type<Iterator>: Returns a read-only equivalent of \p Iterator
|
Chris@16
|
1183 - \p iterator_is_mutable<Iterator>: Returns whether the given iterator is read-only or mutable
|
Chris@16
|
1184 - \p is_iterator_adaptor<Iterator>: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors.
|
Chris@16
|
1185
|
Chris@16
|
1186 \code
|
Chris@16
|
1187 concept PixelIteratorConcept<typename Iterator> : boost_concepts::RandomAccessTraversalConcept<Iterator>, PixelBasedConcept<Iterator> {
|
Chris@16
|
1188 where PixelValueConcept<value_type>;
|
Chris@16
|
1189 typename const_iterator_type<It>::type;
|
Chris@16
|
1190 where PixelIteratorConcept<const_iterator_type<It>::type>;
|
Chris@16
|
1191 static const bool iterator_is_mutable<It>::type::value;
|
Chris@16
|
1192 static const bool is_iterator_adaptor<It>::type::value; // is it an iterator adaptor
|
Chris@16
|
1193 };
|
Chris@16
|
1194 \endcode
|
Chris@16
|
1195 */
|
Chris@16
|
1196 template <typename Iterator>
|
Chris@16
|
1197 struct PixelIteratorConcept {
|
Chris@16
|
1198 void constraints() {
|
Chris@16
|
1199 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
|
Chris@16
|
1200 gil_function_requires<PixelBasedConcept<Iterator> >();
|
Chris@16
|
1201
|
Chris@16
|
1202 typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
Chris@16
|
1203 gil_function_requires<PixelValueConcept<value_type> >();
|
Chris@16
|
1204
|
Chris@16
|
1205 typedef typename const_iterator_type<Iterator>::type const_t;
|
Chris@16
|
1206 static const bool is_mut = iterator_is_mutable<Iterator>::type::value; ignore_unused_variable_warning(is_mut);
|
Chris@16
|
1207
|
Chris@16
|
1208 const_t const_it(it); ignore_unused_variable_warning(const_it); // immutable iterator must be constructible from (possibly mutable) iterator
|
Chris@16
|
1209
|
Chris@16
|
1210 check_base(typename is_iterator_adaptor<Iterator>::type());
|
Chris@16
|
1211 }
|
Chris@16
|
1212 void check_base(mpl::false_) {}
|
Chris@16
|
1213 void check_base(mpl::true_) {
|
Chris@16
|
1214 typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
|
Chris@16
|
1215 gil_function_requires<PixelIteratorConcept<base_t> >();
|
Chris@16
|
1216 }
|
Chris@16
|
1217
|
Chris@16
|
1218 Iterator it;
|
Chris@16
|
1219 };
|
Chris@16
|
1220
|
Chris@16
|
1221 namespace detail {
|
Chris@16
|
1222 template <typename Iterator> // Preconditions: Iterator Models PixelIteratorConcept
|
Chris@16
|
1223 struct PixelIteratorIsMutableConcept {
|
Chris@16
|
1224 void constraints() {
|
Chris@16
|
1225 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<Iterator> >();
|
Chris@16
|
1226 typedef typename remove_reference<typename std::iterator_traits<Iterator>::reference>::type ref;
|
Chris@16
|
1227 typedef typename element_type<ref>::type channel_t;
|
Chris@16
|
1228 gil_function_requires<detail::ChannelIsMutableConcept<channel_t> >();
|
Chris@16
|
1229 }
|
Chris@16
|
1230 };
|
Chris@16
|
1231 }
|
Chris@16
|
1232
|
Chris@16
|
1233 /// \brief Pixel iterator that allows for changing its pixel
|
Chris@16
|
1234 /// \ingroup PixelIteratorConceptPixelIterator
|
Chris@16
|
1235 /**
|
Chris@16
|
1236 \code
|
Chris@16
|
1237 concept MutablePixelIteratorConcept<PixelIteratorConcept Iterator> : MutableRandomAccessIteratorConcept<Iterator> {};
|
Chris@16
|
1238
|
Chris@16
|
1239 \endcode
|
Chris@16
|
1240 */
|
Chris@16
|
1241 template <typename Iterator>
|
Chris@16
|
1242 struct MutablePixelIteratorConcept {
|
Chris@16
|
1243 void constraints() {
|
Chris@16
|
1244 gil_function_requires<PixelIteratorConcept<Iterator> >();
|
Chris@16
|
1245 gil_function_requires<detail::PixelIteratorIsMutableConcept<Iterator> >();
|
Chris@16
|
1246 }
|
Chris@16
|
1247 };
|
Chris@16
|
1248
|
Chris@16
|
1249 namespace detail {
|
Chris@16
|
1250 // Iterators that can be used as the base of memory_based_step_iterator require some additional functions
|
Chris@16
|
1251 template <typename Iterator> // Preconditions: Iterator Models boost_concepts::RandomAccessTraversalConcept
|
Chris@16
|
1252 struct RandomAccessIteratorIsMemoryBasedConcept {
|
Chris@16
|
1253 void constraints() {
|
Chris@16
|
1254 std::ptrdiff_t bs=memunit_step(it); ignore_unused_variable_warning(bs);
|
Chris@16
|
1255 it=memunit_advanced(it,3);
|
Chris@16
|
1256 std::ptrdiff_t bd=memunit_distance(it,it); ignore_unused_variable_warning(bd);
|
Chris@16
|
1257 memunit_advance(it,3);
|
Chris@16
|
1258 // for performace you may also provide a customized implementation of memunit_advanced_ref
|
Chris@16
|
1259 }
|
Chris@16
|
1260 Iterator it;
|
Chris@16
|
1261 };
|
Chris@16
|
1262 }
|
Chris@16
|
1263
|
Chris@16
|
1264 /// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept
|
Chris@16
|
1265 /// \ingroup PixelIteratorConcept
|
Chris@16
|
1266 /// \brief Iterator that advances by a specified step
|
Chris@16
|
1267
|
Chris@16
|
1268 /// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits)
|
Chris@16
|
1269 /// \ingroup PixelIteratorConceptStepIterator
|
Chris@16
|
1270 /**
|
Chris@16
|
1271 \code
|
Chris@16
|
1272 concept MemoryBasedIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator> {
|
Chris@16
|
1273 typename byte_to_memunit<Iterator>; where metafunction<byte_to_memunit<Iterator> >;
|
Chris@16
|
1274 std::ptrdiff_t memunit_step(const Iterator&);
|
Chris@16
|
1275 std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&);
|
Chris@16
|
1276 void memunit_advance(Iterator&, std::ptrdiff_t diff);
|
Chris@16
|
1277 Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; }
|
Chris@16
|
1278 Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); }
|
Chris@16
|
1279 };
|
Chris@16
|
1280 \endcode
|
Chris@16
|
1281 */
|
Chris@16
|
1282 template <typename Iterator>
|
Chris@16
|
1283 struct MemoryBasedIteratorConcept {
|
Chris@16
|
1284 void constraints() {
|
Chris@16
|
1285 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
|
Chris@16
|
1286 gil_function_requires<detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator> >();
|
Chris@16
|
1287 }
|
Chris@16
|
1288 };
|
Chris@16
|
1289
|
Chris@16
|
1290 /// \brief Step iterator concept
|
Chris@16
|
1291 ///
|
Chris@16
|
1292 /// Step iterators are iterators that have a set_step method
|
Chris@16
|
1293 /// \ingroup PixelIteratorConceptStepIterator
|
Chris@16
|
1294 /**
|
Chris@16
|
1295 \code
|
Chris@16
|
1296 concept StepIteratorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
|
Chris@16
|
1297 template <Integral D> void Iterator::set_step(D step);
|
Chris@16
|
1298 };
|
Chris@16
|
1299 \endcode
|
Chris@16
|
1300 */
|
Chris@16
|
1301 template <typename Iterator>
|
Chris@16
|
1302 struct StepIteratorConcept {
|
Chris@16
|
1303 void constraints() {
|
Chris@16
|
1304 gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
|
Chris@16
|
1305 it.set_step(0);
|
Chris@16
|
1306 }
|
Chris@16
|
1307 Iterator it;
|
Chris@16
|
1308 };
|
Chris@16
|
1309
|
Chris@16
|
1310
|
Chris@16
|
1311 /// \brief Step iterator that allows for modifying its current value
|
Chris@16
|
1312 ///
|
Chris@16
|
1313 /// \ingroup PixelIteratorConceptStepIterator
|
Chris@16
|
1314 /**
|
Chris@16
|
1315 \code
|
Chris@16
|
1316 concept MutableStepIteratorConcept<Mutable_ForwardIteratorConcept Iterator> : StepIteratorConcept<Iterator> {};
|
Chris@16
|
1317 \endcode
|
Chris@16
|
1318 */
|
Chris@16
|
1319 template <typename Iterator>
|
Chris@16
|
1320 struct MutableStepIteratorConcept {
|
Chris@16
|
1321 void constraints() {
|
Chris@16
|
1322 gil_function_requires<StepIteratorConcept<Iterator> >();
|
Chris@16
|
1323 gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
|
Chris@16
|
1324 }
|
Chris@16
|
1325 };
|
Chris@16
|
1326
|
Chris@16
|
1327 /// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept
|
Chris@16
|
1328 /// \ingroup PixelIteratorConcept
|
Chris@16
|
1329 /// \brief Adaptor over another iterator
|
Chris@16
|
1330
|
Chris@16
|
1331 /// \ingroup PixelIteratorConceptIteratorAdaptor
|
Chris@16
|
1332 /// \brief Iterator adaptor is a forward iterator adapting another forward iterator.
|
Chris@16
|
1333 /**
|
Chris@16
|
1334 In addition to GIL iterator requirements, GIL iterator adaptors must provide the following metafunctions:
|
Chris@16
|
1335 - \p is_iterator_adaptor<Iterator>: Returns \p mpl::true_
|
Chris@16
|
1336 - \p iterator_adaptor_get_base<Iterator>: Returns the base iterator type
|
Chris@16
|
1337 - \p iterator_adaptor_rebind<Iterator,NewBase>: Replaces the base iterator with the new one
|
Chris@16
|
1338
|
Chris@16
|
1339 The adaptee can be obtained from the iterator via the "base()" method.
|
Chris@16
|
1340
|
Chris@16
|
1341 \code
|
Chris@16
|
1342 concept IteratorAdaptorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
|
Chris@16
|
1343 where SameType<is_iterator_adaptor<Iterator>::type, mpl::true_>;
|
Chris@16
|
1344
|
Chris@16
|
1345 typename iterator_adaptor_get_base<Iterator>;
|
Chris@16
|
1346 where Metafunction<iterator_adaptor_get_base<Iterator> >;
|
Chris@16
|
1347 where boost_concepts::ForwardTraversalConcept<iterator_adaptor_get_base<Iterator>::type>;
|
Chris@16
|
1348
|
Chris@16
|
1349 typename another_iterator;
|
Chris@16
|
1350 typename iterator_adaptor_rebind<Iterator,another_iterator>::type;
|
Chris@16
|
1351 where boost_concepts::ForwardTraversalConcept<another_iterator>;
|
Chris@16
|
1352 where IteratorAdaptorConcept<iterator_adaptor_rebind<Iterator,another_iterator>::type>;
|
Chris@16
|
1353
|
Chris@16
|
1354 const iterator_adaptor_get_base<Iterator>::type& Iterator::base() const;
|
Chris@16
|
1355 };
|
Chris@16
|
1356 \endcode
|
Chris@16
|
1357 */
|
Chris@16
|
1358 template <typename Iterator>
|
Chris@16
|
1359 struct IteratorAdaptorConcept {
|
Chris@16
|
1360 void constraints() {
|
Chris@16
|
1361 gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
|
Chris@16
|
1362
|
Chris@16
|
1363 typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
|
Chris@16
|
1364 gil_function_requires<boost_concepts::ForwardTraversalConcept<base_t> >();
|
Chris@16
|
1365
|
Chris@16
|
1366 BOOST_STATIC_ASSERT(is_iterator_adaptor<Iterator>::value);
|
Chris@16
|
1367 typedef typename iterator_adaptor_rebind<Iterator, void*>::type rebind_t;
|
Chris@16
|
1368
|
Chris@16
|
1369 base_t base=it.base(); ignore_unused_variable_warning(base);
|
Chris@16
|
1370 }
|
Chris@16
|
1371 Iterator it;
|
Chris@16
|
1372 };
|
Chris@16
|
1373
|
Chris@16
|
1374 /// \brief Iterator adaptor that is mutable
|
Chris@16
|
1375 /// \ingroup PixelIteratorConceptIteratorAdaptor
|
Chris@16
|
1376 /**
|
Chris@16
|
1377 \code
|
Chris@16
|
1378 concept MutableIteratorAdaptorConcept<Mutable_ForwardIteratorConcept Iterator> : IteratorAdaptorConcept<Iterator> {};
|
Chris@16
|
1379 \endcode
|
Chris@16
|
1380 */
|
Chris@16
|
1381 template <typename Iterator>
|
Chris@16
|
1382 struct MutableIteratorAdaptorConcept {
|
Chris@16
|
1383 void constraints() {
|
Chris@16
|
1384 gil_function_requires<IteratorAdaptorConcept<Iterator> >();
|
Chris@16
|
1385 gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
|
Chris@16
|
1386 }
|
Chris@16
|
1387 };
|
Chris@16
|
1388
|
Chris@16
|
1389 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
1390 ///
|
Chris@16
|
1391 /// LOCATOR CONCEPTS
|
Chris@16
|
1392 ///
|
Chris@16
|
1393 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
1394
|
Chris@16
|
1395 /// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
|
Chris@16
|
1396 /// \ingroup PixelLocatorConcept
|
Chris@16
|
1397 /// \brief N-dimensional locator
|
Chris@16
|
1398
|
Chris@16
|
1399 /// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
|
Chris@16
|
1400 /// \ingroup PixelLocatorConcept
|
Chris@16
|
1401 /// \brief 2-dimensional locator
|
Chris@16
|
1402
|
Chris@16
|
1403 /// \defgroup PixelLocator2DConcept PixelLocatorConcept
|
Chris@16
|
1404 /// \ingroup PixelLocatorConcept
|
Chris@16
|
1405 /// \brief 2-dimensional locator over pixel data
|
Chris@16
|
1406
|
Chris@16
|
1407 /// \ingroup LocatorNDConcept
|
Chris@16
|
1408 /// \brief N-dimensional locator over immutable values
|
Chris@16
|
1409 /**
|
Chris@16
|
1410 \code
|
Chris@16
|
1411 concept RandomAccessNDLocatorConcept<Regular Loc> {
|
Chris@16
|
1412 typename value_type; // value over which the locator navigates
|
Chris@16
|
1413 typename reference; // result of dereferencing
|
Chris@16
|
1414 typename difference_type; where PointNDConcept<difference_type>; // return value of operator-.
|
Chris@16
|
1415 typename const_t; // same as Loc, but operating over immutable values
|
Chris@16
|
1416 typename cached_location_t; // type to store relative location (for efficient repeated access)
|
Chris@16
|
1417 typename point_t = difference_type;
|
Chris@16
|
1418
|
Chris@16
|
1419 static const size_t num_dimensions; // dimensionality of the locator
|
Chris@16
|
1420 where num_dimensions = point_t::num_dimensions;
|
Chris@16
|
1421
|
Chris@16
|
1422 // The difference_type and iterator type along each dimension. The iterators may only differ in
|
Chris@16
|
1423 // difference_type. Their value_type must be the same as Loc::value_type
|
Chris@16
|
1424 template <size_t D> struct axis {
|
Chris@16
|
1425 typename coord_t = point_t::axis<D>::coord_t;
|
Chris@16
|
1426 typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
|
Chris@16
|
1427 where iterator::value_type == value_type;
|
Chris@16
|
1428 };
|
Chris@16
|
1429
|
Chris@16
|
1430 // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing
|
Chris@16
|
1431 template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
|
Chris@16
|
1432 typename type; where RandomAccessNDLocatorConcept<type>;
|
Chris@16
|
1433 static type make(const Loc& loc, const Deref& deref);
|
Chris@16
|
1434 };
|
Chris@16
|
1435
|
Chris@16
|
1436 Loc& operator+=(Loc&, const difference_type&);
|
Chris@16
|
1437 Loc& operator-=(Loc&, const difference_type&);
|
Chris@16
|
1438 Loc operator+(const Loc&, const difference_type&);
|
Chris@16
|
1439 Loc operator-(const Loc&, const difference_type&);
|
Chris@16
|
1440
|
Chris@16
|
1441 reference operator*(const Loc&);
|
Chris@16
|
1442 reference operator[](const Loc&, const difference_type&);
|
Chris@16
|
1443
|
Chris@16
|
1444 // Storing relative location for faster repeated access and accessing it
|
Chris@16
|
1445 cached_location_t Loc::cache_location(const difference_type&) const;
|
Chris@16
|
1446 reference operator[](const Loc&,const cached_location_t&);
|
Chris@16
|
1447
|
Chris@16
|
1448 // Accessing iterators along a given dimension at the current location or at a given offset
|
Chris@16
|
1449 template <size_t D> axis<D>::iterator& Loc::axis_iterator();
|
Chris@16
|
1450 template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
|
Chris@16
|
1451 template <size_t D> axis<D>::iterator Loc::axis_iterator(const difference_type&) const;
|
Chris@16
|
1452 };
|
Chris@16
|
1453 \endcode
|
Chris@16
|
1454 */
|
Chris@16
|
1455 template <typename Loc>
|
Chris@16
|
1456 struct RandomAccessNDLocatorConcept {
|
Chris@16
|
1457 void constraints() {
|
Chris@16
|
1458 gil_function_requires< Regular<Loc> >();
|
Chris@16
|
1459
|
Chris@16
|
1460 typedef typename Loc::value_type value_type;
|
Chris@16
|
1461 typedef typename Loc::reference reference; // result of dereferencing
|
Chris@16
|
1462 typedef typename Loc::difference_type difference_type; // result of operator-(pixel_locator, pixel_locator)
|
Chris@16
|
1463 typedef typename Loc::cached_location_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access)
|
Chris@16
|
1464 typedef typename Loc::const_t const_t; // same as this type, but over const values
|
Chris@16
|
1465 typedef typename Loc::point_t point_t; // same as difference_type
|
Chris@16
|
1466 static const std::size_t N=Loc::num_dimensions; ignore_unused_variable_warning(N);
|
Chris@16
|
1467
|
Chris@16
|
1468 typedef typename Loc::template axis<0>::iterator first_it_type;
|
Chris@16
|
1469 typedef typename Loc::template axis<N-1>::iterator last_it_type;
|
Chris@16
|
1470 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type> >();
|
Chris@16
|
1471 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type> >();
|
Chris@16
|
1472
|
Chris@16
|
1473 // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
|
Chris@16
|
1474 gil_function_requires<PointNDConcept<point_t> >();
|
Chris@16
|
1475 BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
|
Chris@16
|
1476 BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
|
Chris@16
|
1477 BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
|
Chris@16
|
1478
|
Chris@16
|
1479 difference_type d;
|
Chris@16
|
1480 loc+=d;
|
Chris@16
|
1481 loc-=d;
|
Chris@16
|
1482 loc=loc+d;
|
Chris@16
|
1483 loc=loc-d;
|
Chris@16
|
1484 reference r1=loc[d]; ignore_unused_variable_warning(r1);
|
Chris@16
|
1485 reference r2=*loc; ignore_unused_variable_warning(r2);
|
Chris@16
|
1486 cached_location_t cl=loc.cache_location(d); ignore_unused_variable_warning(cl);
|
Chris@16
|
1487 reference r3=loc[d]; ignore_unused_variable_warning(r3);
|
Chris@16
|
1488
|
Chris@16
|
1489 first_it_type fi=loc.template axis_iterator<0>();
|
Chris@16
|
1490 fi=loc.template axis_iterator<0>(d);
|
Chris@16
|
1491 last_it_type li=loc.template axis_iterator<N-1>();
|
Chris@16
|
1492 li=loc.template axis_iterator<N-1>(d);
|
Chris@16
|
1493
|
Chris@16
|
1494 typedef PixelDereferenceAdaptorArchetype<typename Loc::value_type> deref_t;
|
Chris@16
|
1495 typedef typename Loc::template add_deref<deref_t>::type dtype;
|
Chris@16
|
1496 //gil_function_requires<RandomAccessNDLocatorConcept<dtype> >(); // infinite recursion
|
Chris@16
|
1497 }
|
Chris@16
|
1498 Loc loc;
|
Chris@16
|
1499 };
|
Chris@16
|
1500
|
Chris@16
|
1501 /// \ingroup Locator2DConcept
|
Chris@16
|
1502 /// \brief 2-dimensional locator over immutable values
|
Chris@16
|
1503 /**
|
Chris@16
|
1504 \code
|
Chris@16
|
1505 concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc> {
|
Chris@16
|
1506 where num_dimensions==2;
|
Chris@16
|
1507 where Point2DConcept<point_t>;
|
Chris@16
|
1508
|
Chris@16
|
1509 typename x_iterator = axis<0>::iterator;
|
Chris@16
|
1510 typename y_iterator = axis<1>::iterator;
|
Chris@16
|
1511 typename x_coord_t = axis<0>::coord_t;
|
Chris@16
|
1512 typename y_coord_t = axis<1>::coord_t;
|
Chris@16
|
1513
|
Chris@16
|
1514 // Only available to locators that have dynamic step in Y
|
Chris@16
|
1515 //Loc::Loc(const Loc& loc, y_coord_t);
|
Chris@16
|
1516
|
Chris@16
|
1517 // Only available to locators that have dynamic step in X and Y
|
Chris@16
|
1518 //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);
|
Chris@16
|
1519
|
Chris@16
|
1520 x_iterator& Loc::x();
|
Chris@16
|
1521 x_iterator const& Loc::x() const;
|
Chris@16
|
1522 y_iterator& Loc::y();
|
Chris@16
|
1523 y_iterator const& Loc::y() const;
|
Chris@16
|
1524
|
Chris@16
|
1525 x_iterator Loc::x_at(const difference_type&) const;
|
Chris@16
|
1526 y_iterator Loc::y_at(const difference_type&) const;
|
Chris@16
|
1527 Loc Loc::xy_at(const difference_type&) const;
|
Chris@16
|
1528
|
Chris@16
|
1529 // x/y versions of all methods that can take difference type
|
Chris@16
|
1530 x_iterator Loc::x_at(x_coord_t, y_coord_t) const;
|
Chris@16
|
1531 y_iterator Loc::y_at(x_coord_t, y_coord_t) const;
|
Chris@16
|
1532 Loc Loc::xy_at(x_coord_t, y_coord_t) const;
|
Chris@16
|
1533 reference operator()(const Loc&, x_coord_t, y_coord_t);
|
Chris@16
|
1534 cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;
|
Chris@16
|
1535
|
Chris@16
|
1536 bool Loc::is_1d_traversable(x_coord_t width) const;
|
Chris@16
|
1537 y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
|
Chris@16
|
1538 };
|
Chris@16
|
1539 \endcode
|
Chris@16
|
1540 */
|
Chris@16
|
1541 template <typename Loc>
|
Chris@16
|
1542 struct RandomAccess2DLocatorConcept {
|
Chris@16
|
1543 void constraints() {
|
Chris@16
|
1544 gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
|
Chris@16
|
1545 BOOST_STATIC_ASSERT(Loc::num_dimensions==2);
|
Chris@16
|
1546
|
Chris@16
|
1547 typedef typename dynamic_x_step_type<Loc>::type dynamic_x_step_t;
|
Chris@16
|
1548 typedef typename dynamic_y_step_type<Loc>::type dynamic_y_step_t;
|
Chris@16
|
1549 typedef typename transposed_type<Loc>::type transposed_t;
|
Chris@16
|
1550
|
Chris@16
|
1551 typedef typename Loc::cached_location_t cached_location_t;
|
Chris@16
|
1552 gil_function_requires<Point2DConcept<typename Loc::point_t> >();
|
Chris@16
|
1553
|
Chris@16
|
1554 typedef typename Loc::x_iterator x_iterator;
|
Chris@16
|
1555 typedef typename Loc::y_iterator y_iterator;
|
Chris@16
|
1556 typedef typename Loc::x_coord_t x_coord_t;
|
Chris@16
|
1557 typedef typename Loc::y_coord_t y_coord_t;
|
Chris@16
|
1558
|
Chris@16
|
1559 x_coord_t xd=0; ignore_unused_variable_warning(xd);
|
Chris@16
|
1560 y_coord_t yd=0; ignore_unused_variable_warning(yd);
|
Chris@16
|
1561
|
Chris@16
|
1562 typename Loc::difference_type d;
|
Chris@16
|
1563 typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r);
|
Chris@16
|
1564
|
Chris@16
|
1565 dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
|
Chris@16
|
1566 dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
|
Chris@16
|
1567
|
Chris@16
|
1568 typedef typename dynamic_y_step_type<typename dynamic_x_step_type<transposed_t>::type>::type dynamic_xy_step_transposed_t;
|
Chris@16
|
1569 dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
|
Chris@16
|
1570
|
Chris@16
|
1571 bool is_contiguous=loc.is_1d_traversable(xd); ignore_unused_variable_warning(is_contiguous);
|
Chris@16
|
1572 loc.y_distance_to(loc, xd);
|
Chris@16
|
1573
|
Chris@16
|
1574 loc=loc.xy_at(d);
|
Chris@16
|
1575 loc=loc.xy_at(xd,yd);
|
Chris@16
|
1576
|
Chris@16
|
1577 x_iterator xit=loc.x_at(d);
|
Chris@16
|
1578 xit=loc.x_at(xd,yd);
|
Chris@16
|
1579 xit=loc.x();
|
Chris@16
|
1580
|
Chris@16
|
1581 y_iterator yit=loc.y_at(d);
|
Chris@16
|
1582 yit=loc.y_at(xd,yd);
|
Chris@16
|
1583 yit=loc.y();
|
Chris@16
|
1584
|
Chris@16
|
1585 cached_location_t cl=loc.cache_location(xd,yd); ignore_unused_variable_warning(cl);
|
Chris@16
|
1586 }
|
Chris@16
|
1587 Loc loc;
|
Chris@16
|
1588 };
|
Chris@16
|
1589
|
Chris@16
|
1590 /// \ingroup PixelLocator2DConcept
|
Chris@16
|
1591 /// \brief GIL's 2-dimensional locator over immutable GIL pixels
|
Chris@16
|
1592 /**
|
Chris@16
|
1593 \code
|
Chris@16
|
1594 concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc> {
|
Chris@16
|
1595 where PixelValueConcept<value_type>;
|
Chris@16
|
1596 where PixelIteratorConcept<x_iterator>;
|
Chris@16
|
1597 where PixelIteratorConcept<y_iterator>;
|
Chris@16
|
1598 where x_coord_t == y_coord_t;
|
Chris@16
|
1599
|
Chris@16
|
1600 typename coord_t = x_coord_t;
|
Chris@16
|
1601 };
|
Chris@16
|
1602 \endcode
|
Chris@16
|
1603 */
|
Chris@16
|
1604 template <typename Loc>
|
Chris@16
|
1605 struct PixelLocatorConcept {
|
Chris@16
|
1606 void constraints() {
|
Chris@16
|
1607 gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
|
Chris@16
|
1608 gil_function_requires< PixelIteratorConcept<typename Loc::x_iterator> >();
|
Chris@16
|
1609 gil_function_requires< PixelIteratorConcept<typename Loc::y_iterator> >();
|
Chris@16
|
1610 typedef typename Loc::coord_t coord_t;
|
Chris@16
|
1611 BOOST_STATIC_ASSERT((is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value));
|
Chris@16
|
1612 }
|
Chris@16
|
1613 Loc loc;
|
Chris@16
|
1614 };
|
Chris@16
|
1615
|
Chris@16
|
1616 namespace detail {
|
Chris@16
|
1617 template <typename Loc> // preconditions: Loc Models RandomAccessNDLocatorConcept
|
Chris@16
|
1618 struct RandomAccessNDLocatorIsMutableConcept {
|
Chris@16
|
1619 void constraints() {
|
Chris@16
|
1620 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename Loc::template axis<0>::iterator> >();
|
Chris@16
|
1621 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename Loc::template axis<Loc::num_dimensions-1>::iterator> >();
|
Chris@16
|
1622
|
Chris@16
|
1623 typename Loc::difference_type d; initialize_it(d);
|
Chris@16
|
1624 typename Loc::value_type v;initialize_it(v);
|
Chris@16
|
1625 typename Loc::cached_location_t cl=loc.cache_location(d);
|
Chris@16
|
1626 *loc=v;
|
Chris@16
|
1627 loc[d]=v;
|
Chris@16
|
1628 loc[cl]=v;
|
Chris@16
|
1629 }
|
Chris@16
|
1630 Loc loc;
|
Chris@16
|
1631 };
|
Chris@16
|
1632
|
Chris@16
|
1633 template <typename Loc> // preconditions: Loc Models RandomAccess2DLocatorConcept
|
Chris@16
|
1634 struct RandomAccess2DLocatorIsMutableConcept {
|
Chris@16
|
1635 void constraints() {
|
Chris@16
|
1636 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
|
Chris@16
|
1637 typename Loc::x_coord_t xd=0; ignore_unused_variable_warning(xd);
|
Chris@16
|
1638 typename Loc::y_coord_t yd=0; ignore_unused_variable_warning(yd);
|
Chris@16
|
1639 typename Loc::value_type v; initialize_it(v);
|
Chris@16
|
1640 loc(xd,yd)=v;
|
Chris@16
|
1641 }
|
Chris@16
|
1642 Loc loc;
|
Chris@16
|
1643 };
|
Chris@16
|
1644 }
|
Chris@16
|
1645
|
Chris@16
|
1646 /// \ingroup LocatorNDConcept
|
Chris@16
|
1647 /// \brief N-dimensional locator over mutable pixels
|
Chris@16
|
1648 /**
|
Chris@16
|
1649 \code
|
Chris@16
|
1650 concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc> {
|
Chris@16
|
1651 where Mutable<reference>;
|
Chris@16
|
1652 };
|
Chris@16
|
1653 \endcode
|
Chris@16
|
1654 */
|
Chris@16
|
1655 template <typename Loc>
|
Chris@16
|
1656 struct MutableRandomAccessNDLocatorConcept {
|
Chris@16
|
1657 void constraints() {
|
Chris@16
|
1658 gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
|
Chris@16
|
1659 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
|
Chris@16
|
1660 }
|
Chris@16
|
1661 };
|
Chris@16
|
1662
|
Chris@16
|
1663 /// \ingroup Locator2DConcept
|
Chris@16
|
1664 /// \brief 2-dimensional locator over mutable pixels
|
Chris@16
|
1665 /**
|
Chris@16
|
1666 \code
|
Chris@16
|
1667 concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc> : MutableRandomAccessNDLocatorConcept<Loc> {};
|
Chris@16
|
1668 \endcode
|
Chris@16
|
1669 */
|
Chris@16
|
1670 template <typename Loc>
|
Chris@16
|
1671 struct MutableRandomAccess2DLocatorConcept {
|
Chris@16
|
1672 void constraints() {
|
Chris@16
|
1673 gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
|
Chris@16
|
1674 gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
|
Chris@16
|
1675 }
|
Chris@16
|
1676 };
|
Chris@16
|
1677
|
Chris@16
|
1678 /// \ingroup PixelLocator2DConcept
|
Chris@16
|
1679 /// \brief GIL's 2-dimensional locator over mutable GIL pixels
|
Chris@16
|
1680 /**
|
Chris@16
|
1681 \code
|
Chris@16
|
1682 concept MutablePixelLocatorConcept<PixelLocatorConcept Loc> : MutableRandomAccess2DLocatorConcept<Loc> {};
|
Chris@16
|
1683 \endcode
|
Chris@16
|
1684 */
|
Chris@16
|
1685 template <typename Loc>
|
Chris@16
|
1686 struct MutablePixelLocatorConcept {
|
Chris@16
|
1687 void constraints() {
|
Chris@16
|
1688 gil_function_requires<PixelLocatorConcept<Loc> >();
|
Chris@16
|
1689 gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
|
Chris@16
|
1690 }
|
Chris@16
|
1691 };
|
Chris@16
|
1692
|
Chris@16
|
1693 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
1694 ///
|
Chris@16
|
1695 /// IMAGE VIEW CONCEPTS
|
Chris@16
|
1696 ///
|
Chris@16
|
1697 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
1698
|
Chris@16
|
1699 /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
|
Chris@16
|
1700 /// \ingroup ImageViewConcept
|
Chris@16
|
1701 /// \brief N-dimensional range
|
Chris@16
|
1702
|
Chris@16
|
1703 /// \defgroup ImageView2DConcept ImageView2DConcept
|
Chris@16
|
1704 /// \ingroup ImageViewConcept
|
Chris@16
|
1705 /// \brief 2-dimensional range
|
Chris@16
|
1706
|
Chris@16
|
1707 /// \defgroup PixelImageViewConcept ImageViewConcept
|
Chris@16
|
1708 /// \ingroup ImageViewConcept
|
Chris@16
|
1709 /// \brief 2-dimensional range over pixel data
|
Chris@16
|
1710
|
Chris@16
|
1711 /// \ingroup ImageViewNDConcept
|
Chris@16
|
1712 /// \brief N-dimensional view over immutable values
|
Chris@16
|
1713 /**
|
Chris@16
|
1714 \code
|
Chris@16
|
1715 concept RandomAccessNDImageViewConcept<Regular View> {
|
Chris@16
|
1716 typename value_type;
|
Chris@16
|
1717 typename reference; // result of dereferencing
|
Chris@16
|
1718 typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
|
Chris@16
|
1719 typename const_t; where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
|
Chris@16
|
1720 typename point_t; where PointNDConcept<point_t>; // N-dimensional point
|
Chris@16
|
1721 typename locator; where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
|
Chris@16
|
1722 typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
|
Chris@16
|
1723 typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
|
Chris@16
|
1724 typename size_type; // the return value of size()
|
Chris@16
|
1725
|
Chris@16
|
1726 // Equivalent to RandomAccessNDLocatorConcept::axis
|
Chris@16
|
1727 template <size_t D> struct axis {
|
Chris@16
|
1728 typename coord_t = point_t::axis<D>::coord_t;
|
Chris@16
|
1729 typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
|
Chris@16
|
1730 where SameType<coord_t, iterator::difference_type>;
|
Chris@16
|
1731 where SameType<iterator::value_type,value_type>;
|
Chris@16
|
1732 };
|
Chris@16
|
1733
|
Chris@16
|
1734 // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
|
Chris@16
|
1735 template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
|
Chris@16
|
1736 typename type; where RandomAccessNDImageViewConcept<type>;
|
Chris@16
|
1737 static type make(const View& v, const Deref& deref);
|
Chris@16
|
1738 };
|
Chris@16
|
1739
|
Chris@16
|
1740 static const size_t num_dimensions = point_t::num_dimensions;
|
Chris@16
|
1741
|
Chris@16
|
1742 // Create from a locator at the top-left corner and dimensions
|
Chris@16
|
1743 View::View(const locator&, const point_type&);
|
Chris@16
|
1744
|
Chris@16
|
1745 size_type View::size() const; // total number of elements
|
Chris@16
|
1746 reference operator[](View, const difference_type&) const; // 1-dimensional reference
|
Chris@16
|
1747 iterator View::begin() const;
|
Chris@16
|
1748 iterator View::end() const;
|
Chris@16
|
1749 reverse_iterator View::rbegin() const;
|
Chris@16
|
1750 reverse_iterator View::rend() const;
|
Chris@16
|
1751 iterator View::at(const point_t&);
|
Chris@16
|
1752 point_t View::dimensions() const; // number of elements along each dimension
|
Chris@16
|
1753 bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
|
Chris@16
|
1754
|
Chris@16
|
1755 // iterator along a given dimension starting at a given point
|
Chris@16
|
1756 template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;
|
Chris@16
|
1757
|
Chris@16
|
1758 reference operator()(View,const point_t&) const;
|
Chris@16
|
1759 };
|
Chris@16
|
1760 \endcode
|
Chris@16
|
1761 */
|
Chris@16
|
1762 template <typename View>
|
Chris@16
|
1763 struct RandomAccessNDImageViewConcept {
|
Chris@16
|
1764 void constraints() {
|
Chris@16
|
1765 gil_function_requires< Regular<View> >();
|
Chris@16
|
1766
|
Chris@16
|
1767 typedef typename View::value_type value_type;
|
Chris@16
|
1768 typedef typename View::reference reference; // result of dereferencing
|
Chris@16
|
1769 typedef typename View::difference_type difference_type; // result of operator-(1d_iterator,1d_iterator)
|
Chris@16
|
1770 typedef typename View::const_t const_t; // same as this type, but over const values
|
Chris@16
|
1771 typedef typename View::point_t point_t; // N-dimensional point
|
Chris@16
|
1772 typedef typename View::locator locator; // N-dimensional locator
|
Chris@16
|
1773 typedef typename View::iterator iterator;
|
Chris@16
|
1774 typedef typename View::reverse_iterator reverse_iterator;
|
Chris@16
|
1775 typedef typename View::size_type size_type;
|
Chris@16
|
1776 static const std::size_t N=View::num_dimensions;
|
Chris@16
|
1777
|
Chris@16
|
1778 gil_function_requires<RandomAccessNDLocatorConcept<locator> >();
|
Chris@16
|
1779 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator> >();
|
Chris@16
|
1780 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator> >();
|
Chris@16
|
1781
|
Chris@16
|
1782 typedef typename View::template axis<0>::iterator first_it_type;
|
Chris@16
|
1783 typedef typename View::template axis<N-1>::iterator last_it_type;
|
Chris@16
|
1784 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type> >();
|
Chris@16
|
1785 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type> >();
|
Chris@16
|
1786
|
Chris@16
|
1787 // BOOST_STATIC_ASSERT((typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
|
Chris@16
|
1788 // BOOST_STATIC_ASSERT((typename std::iterator_traits< last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
|
Chris@16
|
1789
|
Chris@16
|
1790 // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
|
Chris@16
|
1791 gil_function_requires<PointNDConcept<point_t> >();
|
Chris@16
|
1792 BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
|
Chris@16
|
1793 BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
|
Chris@16
|
1794 BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
|
Chris@16
|
1795
|
Chris@16
|
1796 point_t p;
|
Chris@16
|
1797 locator lc;
|
Chris@16
|
1798 iterator it;
|
Chris@16
|
1799 reverse_iterator rit;
|
Chris@16
|
1800 difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
|
Chris@16
|
1801
|
Chris@16
|
1802 View(p,lc); // view must be constructible from a locator and a point
|
Chris@16
|
1803
|
Chris@16
|
1804 p=view.dimensions();
|
Chris@16
|
1805 lc=view.pixels();
|
Chris@16
|
1806 size_type sz=view.size(); ignore_unused_variable_warning(sz);
|
Chris@16
|
1807 bool is_contiguous=view.is_1d_traversable(); ignore_unused_variable_warning(is_contiguous);
|
Chris@16
|
1808
|
Chris@16
|
1809 it=view.begin();
|
Chris@16
|
1810 it=view.end();
|
Chris@16
|
1811 rit=view.rbegin();
|
Chris@16
|
1812 rit=view.rend();
|
Chris@16
|
1813
|
Chris@16
|
1814 reference r1=view[d]; ignore_unused_variable_warning(r1); // 1D access
|
Chris@16
|
1815 reference r2=view(p); ignore_unused_variable_warning(r2); // 2D access
|
Chris@16
|
1816
|
Chris@16
|
1817 // get 1-D iterator of any dimension at a given pixel location
|
Chris@16
|
1818 first_it_type fi=view.template axis_iterator<0>(p); ignore_unused_variable_warning(fi);
|
Chris@16
|
1819 last_it_type li=view.template axis_iterator<N-1>(p); ignore_unused_variable_warning(li);
|
Chris@16
|
1820
|
Chris@16
|
1821 typedef PixelDereferenceAdaptorArchetype<typename View::value_type> deref_t;
|
Chris@16
|
1822 typedef typename View::template add_deref<deref_t>::type dtype;
|
Chris@16
|
1823 }
|
Chris@16
|
1824 View view;
|
Chris@16
|
1825 };
|
Chris@16
|
1826
|
Chris@16
|
1827 /// \ingroup ImageView2DConcept
|
Chris@16
|
1828 /// \brief 2-dimensional view over immutable values
|
Chris@16
|
1829 /**
|
Chris@16
|
1830 \code
|
Chris@16
|
1831 concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
|
Chris@16
|
1832 where num_dimensions==2;
|
Chris@16
|
1833
|
Chris@16
|
1834 typename x_iterator = axis<0>::iterator;
|
Chris@16
|
1835 typename y_iterator = axis<1>::iterator;
|
Chris@16
|
1836 typename x_coord_t = axis<0>::coord_t;
|
Chris@16
|
1837 typename y_coord_t = axis<1>::coord_t;
|
Chris@16
|
1838 typename xy_locator = locator;
|
Chris@16
|
1839
|
Chris@16
|
1840 x_coord_t View::width() const;
|
Chris@16
|
1841 y_coord_t View::height() const;
|
Chris@16
|
1842
|
Chris@16
|
1843 // X-navigation
|
Chris@16
|
1844 x_iterator View::x_at(const point_t&) const;
|
Chris@16
|
1845 x_iterator View::row_begin(y_coord_t) const;
|
Chris@16
|
1846 x_iterator View::row_end (y_coord_t) const;
|
Chris@16
|
1847
|
Chris@16
|
1848 // Y-navigation
|
Chris@16
|
1849 y_iterator View::y_at(const point_t&) const;
|
Chris@16
|
1850 y_iterator View::col_begin(x_coord_t) const;
|
Chris@16
|
1851 y_iterator View::col_end (x_coord_t) const;
|
Chris@16
|
1852
|
Chris@16
|
1853 // navigating in 2D
|
Chris@16
|
1854 xy_locator View::xy_at(const point_t&) const;
|
Chris@16
|
1855
|
Chris@16
|
1856 // (x,y) versions of all methods taking point_t
|
Chris@16
|
1857 View::View(x_coord_t,y_coord_t,const locator&);
|
Chris@16
|
1858 iterator View::at(x_coord_t,y_coord_t) const;
|
Chris@16
|
1859 reference operator()(View,x_coord_t,y_coord_t) const;
|
Chris@16
|
1860 xy_locator View::xy_at(x_coord_t,y_coord_t) const;
|
Chris@16
|
1861 x_iterator View::x_at(x_coord_t,y_coord_t) const;
|
Chris@16
|
1862 y_iterator View::y_at(x_coord_t,y_coord_t) const;
|
Chris@16
|
1863 };
|
Chris@16
|
1864 \endcode
|
Chris@16
|
1865 */
|
Chris@16
|
1866 template <typename View>
|
Chris@16
|
1867 struct RandomAccess2DImageViewConcept {
|
Chris@16
|
1868 void constraints() {
|
Chris@16
|
1869 gil_function_requires<RandomAccessNDImageViewConcept<View> >();
|
Chris@16
|
1870 BOOST_STATIC_ASSERT(View::num_dimensions==2);
|
Chris@16
|
1871
|
Chris@16
|
1872 // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
|
Chris@16
|
1873 gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator> >();
|
Chris@16
|
1874
|
Chris@16
|
1875 typedef typename dynamic_x_step_type<View>::type dynamic_x_step_t;
|
Chris@16
|
1876 typedef typename dynamic_y_step_type<View>::type dynamic_y_step_t;
|
Chris@16
|
1877 typedef typename transposed_type<View>::type transposed_t;
|
Chris@16
|
1878
|
Chris@16
|
1879 typedef typename View::x_iterator x_iterator;
|
Chris@16
|
1880 typedef typename View::y_iterator y_iterator;
|
Chris@16
|
1881 typedef typename View::x_coord_t x_coord_t;
|
Chris@16
|
1882 typedef typename View::y_coord_t y_coord_t;
|
Chris@16
|
1883 typedef typename View::xy_locator xy_locator;
|
Chris@16
|
1884
|
Chris@16
|
1885 x_coord_t xd=0; ignore_unused_variable_warning(xd);
|
Chris@16
|
1886 y_coord_t yd=0; ignore_unused_variable_warning(yd);
|
Chris@16
|
1887 x_iterator xit;
|
Chris@16
|
1888 y_iterator yit;
|
Chris@16
|
1889 typename View::point_t d;
|
Chris@16
|
1890
|
Chris@16
|
1891 View(xd,yd,xy_locator()); // constructible with width, height, 2d_locator
|
Chris@16
|
1892
|
Chris@16
|
1893 xy_locator lc=view.xy_at(xd,yd);
|
Chris@16
|
1894 lc=view.xy_at(d);
|
Chris@16
|
1895
|
Chris@16
|
1896 typename View::reference r=view(xd,yd); ignore_unused_variable_warning(r);
|
Chris@16
|
1897 xd=view.width();
|
Chris@16
|
1898 yd=view.height();
|
Chris@16
|
1899
|
Chris@16
|
1900 xit=view.x_at(d);
|
Chris@16
|
1901 xit=view.x_at(xd,yd);
|
Chris@16
|
1902 xit=view.row_begin(xd);
|
Chris@16
|
1903 xit=view.row_end(xd);
|
Chris@16
|
1904
|
Chris@16
|
1905 yit=view.y_at(d);
|
Chris@16
|
1906 yit=view.y_at(xd,yd);
|
Chris@16
|
1907 yit=view.col_begin(xd);
|
Chris@16
|
1908 yit=view.col_end(xd);
|
Chris@16
|
1909 }
|
Chris@16
|
1910 View view;
|
Chris@16
|
1911 };
|
Chris@16
|
1912
|
Chris@16
|
1913
|
Chris@16
|
1914 /// \ingroup PixelImageViewConcept
|
Chris@16
|
1915 /// \brief GIL's 2-dimensional view over immutable GIL pixels
|
Chris@16
|
1916 /**
|
Chris@16
|
1917 \code
|
Chris@16
|
1918 concept ImageViewConcept<RandomAccess2DImageViewConcept View> {
|
Chris@16
|
1919 where PixelValueConcept<value_type>;
|
Chris@16
|
1920 where PixelIteratorConcept<x_iterator>;
|
Chris@16
|
1921 where PixelIteratorConcept<y_iterator>;
|
Chris@16
|
1922 where x_coord_t == y_coord_t;
|
Chris@16
|
1923
|
Chris@16
|
1924 typename coord_t = x_coord_t;
|
Chris@16
|
1925
|
Chris@16
|
1926 std::size_t View::num_channels() const;
|
Chris@16
|
1927 };
|
Chris@16
|
1928 \endcode
|
Chris@16
|
1929 */
|
Chris@16
|
1930 template <typename View>
|
Chris@16
|
1931 struct ImageViewConcept {
|
Chris@16
|
1932 void constraints() {
|
Chris@16
|
1933 gil_function_requires<RandomAccess2DImageViewConcept<View> >();
|
Chris@16
|
1934
|
Chris@16
|
1935 // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
|
Chris@16
|
1936 gil_function_requires<PixelLocatorConcept<typename View::xy_locator> >();
|
Chris@16
|
1937
|
Chris@16
|
1938 BOOST_STATIC_ASSERT((is_same<typename View::x_coord_t, typename View::y_coord_t>::value));
|
Chris@16
|
1939
|
Chris@16
|
1940 typedef typename View::coord_t coord_t; // 1D difference type (same for all dimensions)
|
Chris@16
|
1941 std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
|
Chris@16
|
1942 }
|
Chris@16
|
1943 View view;
|
Chris@16
|
1944 };
|
Chris@16
|
1945
|
Chris@16
|
1946
|
Chris@16
|
1947 namespace detail {
|
Chris@16
|
1948 template <typename View> // Preconditions: View Models RandomAccessNDImageViewConcept
|
Chris@16
|
1949 struct RandomAccessNDImageViewIsMutableConcept {
|
Chris@16
|
1950 void constraints() {
|
Chris@16
|
1951 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator> >();
|
Chris@16
|
1952
|
Chris@16
|
1953 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator> >();
|
Chris@16
|
1954 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::reverse_iterator> >();
|
Chris@16
|
1955 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::template axis<0>::iterator> >();
|
Chris@16
|
1956 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::template axis<View::num_dimensions-1>::iterator> >();
|
Chris@16
|
1957
|
Chris@16
|
1958 typename View::difference_type diff; initialize_it(diff); ignore_unused_variable_warning(diff);
|
Chris@16
|
1959 typename View::point_t pt;
|
Chris@16
|
1960 typename View::value_type v; initialize_it(v);
|
Chris@16
|
1961
|
Chris@16
|
1962 view[diff]=v;
|
Chris@16
|
1963 view(pt)=v;
|
Chris@16
|
1964 }
|
Chris@16
|
1965 View view;
|
Chris@16
|
1966 };
|
Chris@16
|
1967
|
Chris@16
|
1968 template <typename View> // preconditions: View Models RandomAccessNDImageViewConcept
|
Chris@16
|
1969 struct RandomAccess2DImageViewIsMutableConcept {
|
Chris@16
|
1970 void constraints() {
|
Chris@16
|
1971 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
|
Chris@16
|
1972 typename View::x_coord_t xd=0; ignore_unused_variable_warning(xd);
|
Chris@16
|
1973 typename View::y_coord_t yd=0; ignore_unused_variable_warning(yd);
|
Chris@16
|
1974 typename View::value_type v; initialize_it(v);
|
Chris@16
|
1975 view(xd,yd)=v;
|
Chris@16
|
1976 }
|
Chris@16
|
1977 View view;
|
Chris@16
|
1978 };
|
Chris@16
|
1979
|
Chris@16
|
1980 template <typename View> // preconditions: View Models ImageViewConcept
|
Chris@16
|
1981 struct PixelImageViewIsMutableConcept {
|
Chris@16
|
1982 void constraints() {
|
Chris@16
|
1983 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
|
Chris@16
|
1984 }
|
Chris@16
|
1985 };
|
Chris@16
|
1986 }
|
Chris@16
|
1987
|
Chris@16
|
1988 /// \ingroup ImageViewNDConcept
|
Chris@16
|
1989 /// \brief N-dimensional view over mutable values
|
Chris@16
|
1990 /**
|
Chris@16
|
1991 \code
|
Chris@16
|
1992 concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View> {
|
Chris@16
|
1993 where Mutable<reference>;
|
Chris@16
|
1994 };
|
Chris@16
|
1995 \endcode
|
Chris@16
|
1996 */
|
Chris@16
|
1997 template <typename View>
|
Chris@16
|
1998 struct MutableRandomAccessNDImageViewConcept {
|
Chris@16
|
1999 void constraints() {
|
Chris@16
|
2000 gil_function_requires<RandomAccessNDImageViewConcept<View> >();
|
Chris@16
|
2001 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
|
Chris@16
|
2002 }
|
Chris@16
|
2003 };
|
Chris@16
|
2004
|
Chris@16
|
2005 /// \ingroup ImageView2DConcept
|
Chris@16
|
2006 /// \brief 2-dimensional view over mutable values
|
Chris@16
|
2007 /**
|
Chris@16
|
2008 \code
|
Chris@16
|
2009 concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View> : MutableRandomAccessNDImageViewConcept<View> {};
|
Chris@16
|
2010 \endcode
|
Chris@16
|
2011 */
|
Chris@16
|
2012 template <typename View>
|
Chris@16
|
2013 struct MutableRandomAccess2DImageViewConcept {
|
Chris@16
|
2014 void constraints() {
|
Chris@16
|
2015 gil_function_requires<RandomAccess2DImageViewConcept<View> >();
|
Chris@16
|
2016 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
|
Chris@16
|
2017 }
|
Chris@16
|
2018 };
|
Chris@16
|
2019
|
Chris@16
|
2020 /// \ingroup PixelImageViewConcept
|
Chris@16
|
2021 /// \brief GIL's 2-dimensional view over mutable GIL pixels
|
Chris@16
|
2022 /**
|
Chris@16
|
2023 \code
|
Chris@16
|
2024 concept MutableImageViewConcept<ImageViewConcept View> : MutableRandomAccess2DImageViewConcept<View> {};
|
Chris@16
|
2025 \endcode
|
Chris@16
|
2026 */
|
Chris@16
|
2027 template <typename View>
|
Chris@16
|
2028 struct MutableImageViewConcept {
|
Chris@16
|
2029 void constraints() {
|
Chris@16
|
2030 gil_function_requires<ImageViewConcept<View> >();
|
Chris@16
|
2031 gil_function_requires<detail::PixelImageViewIsMutableConcept<View> >();
|
Chris@16
|
2032 }
|
Chris@16
|
2033 };
|
Chris@16
|
2034
|
Chris@16
|
2035 /// \brief Returns whether two views are compatible
|
Chris@16
|
2036 ///
|
Chris@16
|
2037 /// Views are compatible if their pixels are compatible. Compatible views can be assigned and copy constructed from one another.
|
Chris@16
|
2038 template <typename V1, typename V2> // Model ImageViewConcept
|
Chris@16
|
2039 struct views_are_compatible : public pixels_are_compatible<typename V1::value_type, typename V2::value_type> {};
|
Chris@16
|
2040
|
Chris@16
|
2041 /// \brief Views are compatible if they have the same color spaces and compatible channel values. Constness and layout are not important for compatibility
|
Chris@16
|
2042 /// \ingroup ImageViewConcept
|
Chris@16
|
2043 /**
|
Chris@16
|
2044 \code
|
Chris@16
|
2045 concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2> {
|
Chris@16
|
2046 where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
|
Chris@16
|
2047 };
|
Chris@16
|
2048 \endcode
|
Chris@16
|
2049 */
|
Chris@16
|
2050 template <typename V1, typename V2>
|
Chris@16
|
2051 struct ViewsCompatibleConcept {
|
Chris@16
|
2052 void constraints() {
|
Chris@16
|
2053 BOOST_STATIC_ASSERT((views_are_compatible<V1,V2>::value));
|
Chris@16
|
2054 }
|
Chris@16
|
2055 };
|
Chris@16
|
2056
|
Chris@16
|
2057
|
Chris@16
|
2058 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2059 ///
|
Chris@16
|
2060 /// IMAGE CONCEPTS
|
Chris@16
|
2061 ///
|
Chris@16
|
2062 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2063
|
Chris@16
|
2064
|
Chris@16
|
2065 /// \ingroup ImageConcept
|
Chris@16
|
2066 /// \brief N-dimensional container of values
|
Chris@16
|
2067 /**
|
Chris@16
|
2068 \code
|
Chris@16
|
2069 concept RandomAccessNDImageConcept<typename Img> : Regular<Img> {
|
Chris@16
|
2070 typename view_t; where MutableRandomAccessNDImageViewConcept<view_t>;
|
Chris@16
|
2071 typename const_view_t = view_t::const_t;
|
Chris@16
|
2072 typename point_t = view_t::point_t;
|
Chris@16
|
2073 typename value_type = view_t::value_type;
|
Chris@16
|
2074 typename allocator_type;
|
Chris@16
|
2075
|
Chris@16
|
2076 Img::Img(point_t dims, std::size_t alignment=1);
|
Chris@16
|
2077 Img::Img(point_t dims, value_type fill_value, std::size_t alignment);
|
Chris@16
|
2078
|
Chris@16
|
2079 void Img::recreate(point_t new_dims, std::size_t alignment=1);
|
Chris@16
|
2080 void Img::recreate(point_t new_dims, value_type fill_value, std::size_t alignment);
|
Chris@16
|
2081
|
Chris@16
|
2082 const point_t& Img::dimensions() const;
|
Chris@16
|
2083 const const_view_t& const_view(const Img&);
|
Chris@16
|
2084 const view_t& view(Img&);
|
Chris@16
|
2085 };
|
Chris@16
|
2086 \endcode
|
Chris@16
|
2087 */
|
Chris@16
|
2088 template <typename Img>
|
Chris@16
|
2089 struct RandomAccessNDImageConcept {
|
Chris@16
|
2090 void constraints() {
|
Chris@16
|
2091 gil_function_requires<Regular<Img> >();
|
Chris@16
|
2092
|
Chris@16
|
2093 typedef typename Img::view_t view_t;
|
Chris@16
|
2094 gil_function_requires<MutableRandomAccessNDImageViewConcept<view_t> >();
|
Chris@16
|
2095
|
Chris@16
|
2096 typedef typename Img::const_view_t const_view_t;
|
Chris@16
|
2097 typedef typename Img::value_type pixel_t;
|
Chris@16
|
2098
|
Chris@16
|
2099 typedef typename Img::point_t point_t;
|
Chris@16
|
2100 gil_function_requires<PointNDConcept<point_t> >();
|
Chris@16
|
2101
|
Chris@16
|
2102 const_view_t cv = const_view(img); ignore_unused_variable_warning(cv);
|
Chris@16
|
2103 view_t v = view(img); ignore_unused_variable_warning(v);
|
Chris@16
|
2104
|
Chris@16
|
2105 pixel_t fill_value;
|
Chris@16
|
2106 point_t pt=img.dimensions();
|
Chris@16
|
2107 Img im1(pt);
|
Chris@16
|
2108 Img im2(pt,1);
|
Chris@16
|
2109 Img im3(pt,fill_value,1);
|
Chris@16
|
2110 img.recreate(pt);
|
Chris@16
|
2111 img.recreate(pt,1);
|
Chris@16
|
2112 img.recreate(pt,fill_value,1);
|
Chris@16
|
2113 }
|
Chris@16
|
2114 Img img;
|
Chris@16
|
2115 };
|
Chris@16
|
2116
|
Chris@16
|
2117
|
Chris@16
|
2118 /// \ingroup ImageConcept
|
Chris@16
|
2119 /// \brief 2-dimensional container of values
|
Chris@16
|
2120 /**
|
Chris@16
|
2121 \code
|
Chris@16
|
2122 concept RandomAccess2DImageConcept<RandomAccessNDImageConcept Img> {
|
Chris@16
|
2123 typename x_coord_t = const_view_t::x_coord_t;
|
Chris@16
|
2124 typename y_coord_t = const_view_t::y_coord_t;
|
Chris@16
|
2125
|
Chris@16
|
2126 Img::Img(x_coord_t width, y_coord_t height, std::size_t alignment=1);
|
Chris@16
|
2127 Img::Img(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
|
Chris@16
|
2128
|
Chris@16
|
2129 x_coord_t Img::width() const;
|
Chris@16
|
2130 y_coord_t Img::height() const;
|
Chris@16
|
2131
|
Chris@16
|
2132 void Img::recreate(x_coord_t width, y_coord_t height, std::size_t alignment=1);
|
Chris@16
|
2133 void Img::recreate(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
|
Chris@16
|
2134 };
|
Chris@16
|
2135 \endcode
|
Chris@16
|
2136 */
|
Chris@16
|
2137 template <typename Img>
|
Chris@16
|
2138 struct RandomAccess2DImageConcept {
|
Chris@16
|
2139 void constraints() {
|
Chris@16
|
2140 gil_function_requires<RandomAccessNDImageConcept<Img> >();
|
Chris@16
|
2141 typedef typename Img::x_coord_t x_coord_t;
|
Chris@16
|
2142 typedef typename Img::y_coord_t y_coord_t;
|
Chris@16
|
2143 typedef typename Img::value_type value_t;
|
Chris@16
|
2144
|
Chris@16
|
2145 gil_function_requires<MutableRandomAccess2DImageViewConcept<typename Img::view_t> >();
|
Chris@16
|
2146
|
Chris@16
|
2147 x_coord_t w=img.width();
|
Chris@16
|
2148 y_coord_t h=img.height();
|
Chris@16
|
2149 value_t fill_value;
|
Chris@16
|
2150 Img im1(w,h);
|
Chris@16
|
2151 Img im2(w,h,1);
|
Chris@16
|
2152 Img im3(w,h,fill_value,1);
|
Chris@16
|
2153 img.recreate(w,h);
|
Chris@16
|
2154 img.recreate(w,h,1);
|
Chris@16
|
2155 img.recreate(w,h,fill_value,1);
|
Chris@16
|
2156 }
|
Chris@16
|
2157 Img img;
|
Chris@16
|
2158 };
|
Chris@16
|
2159
|
Chris@16
|
2160 /// \ingroup ImageConcept
|
Chris@16
|
2161 /// \brief 2-dimensional image whose value type models PixelValueConcept
|
Chris@16
|
2162 /**
|
Chris@16
|
2163 \code
|
Chris@16
|
2164 concept ImageConcept<RandomAccess2DImageConcept Img> {
|
Chris@16
|
2165 where MutableImageViewConcept<view_t>;
|
Chris@16
|
2166 typename coord_t = view_t::coord_t;
|
Chris@16
|
2167 };
|
Chris@16
|
2168 \endcode
|
Chris@16
|
2169 */
|
Chris@16
|
2170 template <typename Img>
|
Chris@16
|
2171 struct ImageConcept {
|
Chris@16
|
2172 void constraints() {
|
Chris@16
|
2173 gil_function_requires<RandomAccess2DImageConcept<Img> >();
|
Chris@16
|
2174 gil_function_requires<MutableImageViewConcept<typename Img::view_t> >();
|
Chris@16
|
2175 typedef typename Img::coord_t coord_t;
|
Chris@16
|
2176 BOOST_STATIC_ASSERT(num_channels<Img>::value == mpl::size<typename color_space_type<Img>::type>::value);
|
Chris@16
|
2177
|
Chris@16
|
2178 BOOST_STATIC_ASSERT((is_same<coord_t, typename Img::x_coord_t>::value));
|
Chris@16
|
2179 BOOST_STATIC_ASSERT((is_same<coord_t, typename Img::y_coord_t>::value));
|
Chris@16
|
2180 }
|
Chris@16
|
2181 Img img;
|
Chris@16
|
2182 };
|
Chris@16
|
2183
|
Chris@16
|
2184
|
Chris@16
|
2185 } } // namespace boost::gil
|
Chris@16
|
2186
|
Chris@16
|
2187 #endif
|