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