2 Copyright 2005-2007 Adobe Systems Incorporated
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).
8 See http://opensource.adobe.com/gil for most recent version including documentation.
11 /*************************************************************************************************/
16 ////////////////////////////////////////////////////////////////////////////////////////
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
23 ////////////////////////////////////////////////////////////////////////////////////////
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>
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;
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;
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);
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);
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);
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);
80 template <typename B, typename C, typename L, bool M> struct bit_aligned_pixel_reference;
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);
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);
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;
99 void initialize_it(T& x) {}
100 } // namespace detail
102 template <typename T>
103 struct remove_const_and_reference : public remove_const<typename remove_reference<T>::type> {};
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>(); }
109 #define GIL_CLASS_REQUIRE(T,NS,C)
110 template <typename C> void gil_function_requires() {}
113 /// \ingroup BasicConcepts
116 auto concept DefaultConstructible<typename T> {
121 template <typename T>
122 struct DefaultConstructible {
124 function_requires<boost::DefaultConstructibleConcept<T> >();
128 /// \ingroup BasicConcepts
130 \codeauto concept CopyConstructible<typename T> {
136 template <typename T>
137 struct CopyConstructible {
139 function_requires<boost::CopyConstructibleConcept<T> >();
143 /// \ingroup BasicConcepts
146 auto concept Assignable<typename T, typename U = T> {
147 typename result_type;
148 result_type operator=(T&, U);
152 template <typename T>
155 function_requires<boost::AssignableConcept<T> >();
158 /// \ingroup BasicConcepts
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); }
167 template <typename T>
168 struct EqualityComparable {
170 function_requires<boost::EqualityComparableConcept<T> >();
174 /// \ingroup BasicConcepts
177 concept SameType<typename T, typename U>;// unspecified
181 template <typename T, typename U>
184 BOOST_STATIC_ASSERT((boost::is_same<T,U>::value_core));
188 /// \ingroup BasicConcepts
191 auto concept Swappable<typename T> {
196 template <typename T>
205 /// \ingroup BasicConcepts
208 auto concept Regular<typename T> : DefaultConstructible<T>, CopyConstructible<T>, EqualityComparable<T>,
209 Assignable<T>, Swappable<T> {};
213 template <typename T>
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> >();
224 /// \ingroup BasicConcepts
227 auto concept Metafunction<typename T> {
232 template <typename T>
233 struct Metafunction {
235 typedef typename T::type type;
238 ////////////////////////////////////////////////////////////////////////////////////////
242 ////////////////////////////////////////////////////////////////////////////////////////
244 /// \brief N-dimensional point concept
245 /// \ingroup PointConcept
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>;
252 const size_t num_dimensions;
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();
261 template <typename P>
262 struct PointNDConcept {
264 gil_function_requires< Regular<P> >();
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;
275 value_type v=point[0]; ignore_unused_variable_warning(v);
281 /// \brief 2-dimensional point concept
282 /// \ingroup PointConcept
285 concept Point2DConcept<typename T> : PointNDConcept<T> {
286 where num_dimensions == 2;
287 where SameType<axis<0>::type, axis<1>::type>;
289 typename value_type = axis<0>::type;
291 const value_type& operator[](const T&, size_t i);
292 value_type& operator[]( T&, size_t i);
299 template <typename P>
300 struct Point2DConcept {
302 gil_function_requires< PointNDConcept<P> >();
303 BOOST_STATIC_ASSERT(P::num_dimensions == 2);
310 ////////////////////////////////////////////////////////////////////////////////////////
312 // ITERATOR MUTABILITY CONCEPTS
314 // Taken from boost's concept_check.hpp. Isolating mutability to result in faster compile time
316 ////////////////////////////////////////////////////////////////////////////////////////
319 template <class TT> // Preconditions: TT Models boost_concepts::ForwardTraversalConcept
320 struct ForwardIteratorIsMutableConcept {
322 *i++ = *i; // require postincrement and assignment
327 template <class TT> // Preconditions: TT Models boost::BidirectionalIteratorConcept
328 struct BidirectionalIteratorIsMutableConcept {
330 gil_function_requires< ForwardIteratorIsMutableConcept<TT> >();
331 *i-- = *i; // require postdecrement and assignment
336 template <class TT> // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept
337 struct RandomAccessIteratorIsMutableConcept {
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
345 } // namespace detail
347 ////////////////////////////////////////////////////////////////////////////////////////
349 // COLOR SPACE CONCEPTS
351 ////////////////////////////////////////////////////////////////////////////////////////
353 /// \brief Color space type concept
354 /// \ingroup ColorSpaceAndLayoutConcept
357 concept ColorSpaceConcept<MPLRandomAccessSequence Cs> {
358 // An MPL Random Access Sequence, whose elements are color tags
362 template <typename Cs>
363 struct ColorSpaceConcept {
365 // An MPL Random Access Sequence, whose elements are color tags
369 template <typename ColorSpace1, typename ColorSpace2> // Models ColorSpaceConcept
370 struct color_spaces_are_compatible : public is_same<ColorSpace1,ColorSpace2> {};
372 /// \brief Two color spaces are compatible if they are the same
373 /// \ingroup ColorSpaceAndLayoutConcept
376 concept ColorSpacesCompatibleConcept<ColorSpaceConcept Cs1, ColorSpaceConcept Cs2> {
377 where SameType<Cs1,Cs2>;
381 template <typename Cs1, typename Cs2>
382 struct ColorSpacesCompatibleConcept {
384 BOOST_STATIC_ASSERT((color_spaces_are_compatible<Cs1,Cs2>::value));
388 /// \brief Channel mapping concept
389 /// \ingroup ColorSpaceAndLayoutConcept
392 concept ChannelMappingConcept<MPLRandomAccessSequence CM> {
393 // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
397 template <typename CM>
398 struct ChannelMappingConcept {
400 // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
406 ////////////////////////////////////////////////////////////////////////////////////////
410 ////////////////////////////////////////////////////////////////////////////////////////
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.
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.
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.
420 Channels have a traits class, \p channel_traits, which defines their associated types as well as their operating ranges.
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
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
436 template <typename T>
437 struct ChannelConcept {
439 gil_function_requires< boost::EqualityComparableConcept<T> >();
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;
447 channel_traits<T>::min_value();
448 channel_traits<T>::max_value();
455 // Preconditions: T models ChannelConcept
456 template <typename T>
457 struct ChannelIsMutableConcept {
467 /// \brief A channel that allows for modifying its value
468 /// \ingroup ChannelConcept
471 concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
474 template <typename T>
475 struct MutableChannelConcept {
477 gil_function_requires<ChannelConcept<T> >();
478 gil_function_requires<detail::ChannelIsMutableConcept<T> >();
482 /// \brief A channel that supports default construction.
483 /// \ingroup ChannelConcept
486 concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
489 template <typename T>
490 struct ChannelValueConcept {
492 gil_function_requires<ChannelConcept<T> >();
493 gil_function_requires<Regular<T> >();
498 /// \brief Predicate metafunction returning whether two channels are compatible
499 /// \ingroup ChannelAlgorithm
501 /// Channels are considered compatible if their value types (ignoring constness and references) are the same.
506 BOOST_STATIC_ASSERT((channels_are_compatible<bits8, const bits8&>::value));
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> {};
513 /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
514 /// \ingroup ChannelConcept
517 concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2> {
518 where SameType<T1::value_type, T2::value_type>;
522 template <typename T1, typename T2>
523 struct ChannelsCompatibleConcept {
525 BOOST_STATIC_ASSERT((channels_are_compatible<T1,T2>::value));
529 /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels
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
535 concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel> {
536 DstChannel channel_convert(const SrcChannel&);
540 template <typename SrcChannel, typename DstChannel>
541 struct ChannelConvertibleConcept {
543 gil_function_requires<ChannelConcept<SrcChannel> >();
544 gil_function_requires<MutableChannelConcept<DstChannel> >();
545 dst=channel_convert<DstChannel,SrcChannel>(src); ignore_unused_variable_warning(dst);
555 ////////////////////////////////////////////////////////////////////////////////////////
557 /// COLOR BASE CONCEPTS
559 ////////////////////////////////////////////////////////////////////////////////////////
561 /// \ingroup ColorBaseConcept
562 /// \brief A color base is a container of color elements (such as channels, channel references or channel pointers)
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.
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.
579 concept ColorBaseConcept<typename T> : CopyConstructible<T>, EqualityComparable<T> {
580 // a GIL layout (the color space and element permutation)
583 // The type of K-th element
584 template <int K> struct kth_element_type; where Metafunction<kth_element_type>;
586 // The result of at_c
587 template <int K> struct kth_element_const_reference_type; where Metafunction<kth_element_const_reference_type>;
589 template <int K> kth_element_const_reference_type<T,K>::type at_c(T);
591 // Copy-constructible and equality comparable with other compatible color bases
592 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<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&);
603 template <typename ColorBase>
604 struct ColorBaseConcept {
606 gil_function_requires< CopyConstructible<ColorBase> >();
607 gil_function_requires< EqualityComparable<ColorBase> >();
609 typedef typename ColorBase::layout_t::color_space_t color_space_t;
610 gil_function_requires<ColorSpaceConcept<color_space_t> >();
612 typedef typename ColorBase::layout_t::channel_mapping_t channel_mapping_t;
613 // TODO: channel_mapping_t must be an MPL RandomAccessSequence
615 static const std::size_t num_elements = size<ColorBase>::value;
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;
620 #if !defined(_MSC_VER) || _MSC_VER > 1310
621 CR cr=at_c<num_elements-1>(cb); ignore_unused_variable_warning(cr);
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()
633 /// \ingroup ColorBaseConcept
634 /// \brief Color base which allows for modifying its elements
638 concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T> {
639 template <int K> struct kth_element_reference_type; where Metafunction<kth_element_reference_type>;
641 template <int K> kth_element_reference_type<kth_element_type<T,K>::type>::type at_c(T);
643 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
644 T& operator=(T&, const T2&);
648 template <typename ColorBase>
649 struct MutableColorBaseConcept {
651 gil_function_requires< ColorBaseConcept<ColorBase> >();
652 gil_function_requires< Assignable<ColorBase> >();
653 gil_function_requires< Swappable<ColorBase> >();
655 typedef typename kth_element_reference_type<ColorBase, 0>::type CR;
657 #if !defined(_MSC_VER) || _MSC_VER > 1310
666 /// \ingroup ColorBaseConcept
667 /// \brief Color base that also has a default-constructor. Refines Regular
670 concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T> {
674 template <typename ColorBase>
675 struct ColorBaseValueConcept {
677 gil_function_requires< MutableColorBaseConcept<ColorBase> >();
678 gil_function_requires< Regular<ColorBase> >();
682 /// \ingroup ColorBaseConcept
683 /// \brief Color base whose elements all have the same type
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;
694 template <typename ColorBase>
695 struct HomogeneousColorBaseConcept {
697 gil_function_requires< ColorBaseConcept<ColorBase> >();
699 static const std::size_t num_elements = size<ColorBase>::value;
701 typedef typename kth_element_type<ColorBase,0>::type T0;
702 typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
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);
711 /// \ingroup ColorBaseConcept
712 /// \brief Homogeneous color base that allows for modifying its elements
716 concept MutableHomogeneousColorBaseConcept<ColorBaseConcept CB> : HomogeneousColorBaseConcept<CB> {
717 kth_element_reference_type<CB,0>::type dynamic_at_c(CB&, std::size_t n);
722 template <typename ColorBase>
723 struct MutableHomogeneousColorBaseConcept {
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);
734 /// \ingroup ColorBaseConcept
735 /// \brief Homogeneous color base that also has a default constructor. Refines Regular.
739 concept HomogeneousColorBaseValueConcept<typename T> : MutableHomogeneousColorBaseConcept<T>, Regular<T> {
744 template <typename ColorBase>
745 struct HomogeneousColorBaseValueConcept {
747 gil_function_requires< MutableHomogeneousColorBaseConcept<ColorBase> >();
748 gil_function_requires< Regular<ColorBase> >();
753 /// \ingroup ColorBaseConcept
754 /// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise.
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>;
766 template <typename ColorBase1, typename ColorBase2>
767 struct ColorBasesCompatibleConcept {
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"
798 ////////////////////////////////////////////////////////////////////////////////////////
802 ////////////////////////////////////////////////////////////////////////////////////////
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
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>;
821 template <typename P>
822 struct PixelBasedConcept {
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> >();
829 static const bool planar = is_planar<P>::type::value; ignore_unused_variable_warning(planar);
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);
838 /// \brief Concept for homogeneous pixel-based GIL constructs
839 /// \ingroup PixelBasedConcept
842 concept HomogeneousPixelBasedConcept<PixelBasedConcept T> {
843 typename channel_type<T>;
844 where Metafunction<channel_type<T> >;
845 where ChannelConcept<channel_type<T>::type>;
849 template <typename P>
850 struct HomogeneousPixelBasedConcept {
852 gil_function_requires<PixelBasedConcept<P> >();
853 typedef typename channel_type<P>::type channel_t;
854 gil_function_requires<ChannelConcept<channel_t> >();
859 /// \brief Pixel concept - A color base whose elements are channels
860 /// \ingroup PixelConcept
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> >;
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;
873 template <PixelConcept P2> where { PixelConcept<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&);
883 template <typename P>
884 struct PixelConcept {
886 gil_function_requires<ColorBaseConcept<P> >();
887 gil_function_requires<PixelBasedConcept<P> >();
889 BOOST_STATIC_ASSERT((is_pixel<P>::value));
890 static const bool is_mutable = P::is_mutable; ignore_unused_variable_warning(is_mutable);
892 typedef typename P::value_type value_type;
893 // gil_function_requires<PixelValueConcept<value_type> >();
895 typedef typename P::reference reference;
896 gil_function_requires<PixelConcept<typename remove_const_and_reference<reference>::type> >();
898 typedef typename P::const_reference const_reference;
899 gil_function_requires<PixelConcept<typename remove_const_and_reference<const_reference>::type> >();
904 /// \brief Pixel concept that allows for changing its channels
905 /// \ingroup PixelConcept
908 concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P> {
909 where is_mutable==true;
913 template <typename P>
914 struct MutablePixelConcept {
916 gil_function_requires<PixelConcept<P> >();
917 BOOST_STATIC_ASSERT(P::is_mutable);
920 /// \brief Homogeneous pixel concept
921 /// \ingroup PixelConcept
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); }
929 template <typename P>
930 struct HomogeneousPixelConcept {
932 gil_function_requires<PixelConcept<P> >();
933 gil_function_requires<HomogeneousColorBaseConcept<P> >();
934 gil_function_requires<HomogeneousPixelBasedConcept<P> >();
940 /// \brief Homogeneous pixel concept that allows for changing its channels
941 /// \ingroup PixelConcept
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); }
949 template <typename P>
950 struct MutableHomogeneousPixelConcept {
952 gil_function_requires<HomogeneousPixelConcept<P> >();
953 gil_function_requires<MutableHomogeneousColorBaseConcept<P> >();
959 /// \brief Pixel concept that is a Regular type
960 /// \ingroup PixelConcept
963 concept PixelValueConcept<PixelConcept P> : Regular<P> {
964 where SameType<value_type,P>;
968 template <typename P>
969 struct PixelValueConcept {
971 gil_function_requires<PixelConcept<P> >();
972 gil_function_requires<Regular<P> >();
976 /// \brief Homogeneous pixel concept that is a Regular type
977 /// \ingroup PixelConcept
980 concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P> {
981 where SameType<value_type,P>;
985 template <typename P>
986 struct HomogeneousPixelValueConcept {
988 gil_function_requires<HomogeneousPixelConcept<P> >();
989 gil_function_requires<Regular<P> >();
990 BOOST_STATIC_ASSERT((is_same<P, typename P::value_type>::value));
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> > {};
1001 template <typename P1, typename P2>
1002 struct channels_are_pairwise_compatible<P1,P2,-1> : public mpl::true_ {};
1005 /// \brief Returns whether two pixels are compatible
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> > {};
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
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>;
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));
1033 /// \brief Pixel convertible concept
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
1039 template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
1040 concept PixelConvertibleConcept {
1041 void color_convert(const SrcPixel&, DstPixel&);
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);
1056 ////////////////////////////////////////////////////////////////////////////////////////
1058 /// DEREFERENCE ADAPTOR CONCEPTS
1060 ////////////////////////////////////////////////////////////////////////////////////////
1062 /// \ingroup PixelDereferenceAdaptorConcept
1064 /// \brief Represents a unary function object that can be invoked upon dereferencing a pixel iterator.
1066 /// This can perform an arbitrary computation, such as color conversion or table lookup
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;
1077 where Convertible<value_type,result_type>;
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> >();
1092 gil_function_requires<PixelConcept<typename remove_const_and_reference<typename D::result_type>::type> >();
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)
1101 const bool is_mutable=D::is_mutable; ignore_unused_variable_warning(is_mutable);
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; }
1116 ////////////////////////////////////////////////////////////////////////////////////////
1118 /// Pixel ITERATOR CONCEPTS
1120 ////////////////////////////////////////////////////////////////////////////////////////
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
1126 concept HasDynamicXStepTypeConcept<typename T> {
1127 typename dynamic_x_step_type<T>;
1128 where Metafunction<dynamic_x_step_type<T> >;
1132 template <typename T>
1133 struct HasDynamicXStepTypeConcept {
1134 void constraints() {
1135 typedef typename dynamic_x_step_type<T>::type type;
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
1143 concept HasDynamicYStepTypeConcept<typename T> {
1144 typename dynamic_y_step_type<T>;
1145 where Metafunction<dynamic_y_step_type<T> >;
1149 template <typename T>
1150 struct HasDynamicYStepTypeConcept {
1151 void constraints() {
1152 typedef typename dynamic_y_step_type<T>::type type;
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
1161 concept HasTransposedTypeConcept<typename T> {
1162 typename transposed_type<T>;
1163 where Metafunction<transposed_type<T> >;
1167 template <typename T>
1168 struct HasTransposedTypeConcept {
1169 void constraints() {
1170 typedef typename transposed_type<T>::type type;
1174 /// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept
1175 /// \ingroup PixelIteratorConcept
1176 /// \brief STL iterator over pixels
1178 /// \ingroup PixelIteratorConceptPixelIterator
1179 /// \brief An STL random access traversal iterator over a model of PixelConcept.
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.
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
1196 template <typename Iterator>
1197 struct PixelIteratorConcept {
1198 void constraints() {
1199 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
1200 gil_function_requires<PixelBasedConcept<Iterator> >();
1202 typedef typename std::iterator_traits<Iterator>::value_type value_type;
1203 gil_function_requires<PixelValueConcept<value_type> >();
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);
1208 const_t const_it(it); ignore_unused_variable_warning(const_it); // immutable iterator must be constructible from (possibly mutable) iterator
1210 check_base(typename is_iterator_adaptor<Iterator>::type());
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> >();
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> >();
1233 /// \brief Pixel iterator that allows for changing its pixel
1234 /// \ingroup PixelIteratorConceptPixelIterator
1237 concept MutablePixelIteratorConcept<PixelIteratorConcept Iterator> : MutableRandomAccessIteratorConcept<Iterator> {};
1241 template <typename Iterator>
1242 struct MutablePixelIteratorConcept {
1243 void constraints() {
1244 gil_function_requires<PixelIteratorConcept<Iterator> >();
1245 gil_function_requires<detail::PixelIteratorIsMutableConcept<Iterator> >();
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
1264 /// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept
1265 /// \ingroup PixelIteratorConcept
1266 /// \brief Iterator that advances by a specified step
1268 /// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits)
1269 /// \ingroup PixelIteratorConceptStepIterator
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); }
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> >();
1290 /// \brief Step iterator concept
1292 /// Step iterators are iterators that have a set_step method
1293 /// \ingroup PixelIteratorConceptStepIterator
1296 concept StepIteratorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
1297 template <Integral D> void Iterator::set_step(D step);
1301 template <typename Iterator>
1302 struct StepIteratorConcept {
1303 void constraints() {
1304 gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
1311 /// \brief Step iterator that allows for modifying its current value
1313 /// \ingroup PixelIteratorConceptStepIterator
1316 concept MutableStepIteratorConcept<Mutable_ForwardIteratorConcept Iterator> : StepIteratorConcept<Iterator> {};
1319 template <typename Iterator>
1320 struct MutableStepIteratorConcept {
1321 void constraints() {
1322 gil_function_requires<StepIteratorConcept<Iterator> >();
1323 gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
1327 /// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept
1328 /// \ingroup PixelIteratorConcept
1329 /// \brief Adaptor over another iterator
1331 /// \ingroup PixelIteratorConceptIteratorAdaptor
1332 /// \brief Iterator adaptor is a forward iterator adapting another forward iterator.
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
1339 The adaptee can be obtained from the iterator via the "base()" method.
1342 concept IteratorAdaptorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
1343 where SameType<is_iterator_adaptor<Iterator>::type, mpl::true_>;
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>;
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>;
1354 const iterator_adaptor_get_base<Iterator>::type& Iterator::base() const;
1358 template <typename Iterator>
1359 struct IteratorAdaptorConcept {
1360 void constraints() {
1361 gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
1363 typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
1364 gil_function_requires<boost_concepts::ForwardTraversalConcept<base_t> >();
1366 BOOST_STATIC_ASSERT(is_iterator_adaptor<Iterator>::value);
1367 typedef typename iterator_adaptor_rebind<Iterator, void*>::type rebind_t;
1369 base_t base=it.base(); ignore_unused_variable_warning(base);
1374 /// \brief Iterator adaptor that is mutable
1375 /// \ingroup PixelIteratorConceptIteratorAdaptor
1378 concept MutableIteratorAdaptorConcept<Mutable_ForwardIteratorConcept Iterator> : IteratorAdaptorConcept<Iterator> {};
1381 template <typename Iterator>
1382 struct MutableIteratorAdaptorConcept {
1383 void constraints() {
1384 gil_function_requires<IteratorAdaptorConcept<Iterator> >();
1385 gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
1389 ////////////////////////////////////////////////////////////////////////////////////////
1391 /// LOCATOR CONCEPTS
1393 ////////////////////////////////////////////////////////////////////////////////////////
1395 /// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
1396 /// \ingroup PixelLocatorConcept
1397 /// \brief N-dimensional locator
1399 /// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
1400 /// \ingroup PixelLocatorConcept
1401 /// \brief 2-dimensional locator
1403 /// \defgroup PixelLocator2DConcept PixelLocatorConcept
1404 /// \ingroup PixelLocatorConcept
1405 /// \brief 2-dimensional locator over pixel data
1407 /// \ingroup LocatorNDConcept
1408 /// \brief N-dimensional locator over immutable values
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;
1419 static const size_t num_dimensions; // dimensionality of the locator
1420 where num_dimensions = point_t::num_dimensions;
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;
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);
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&);
1441 reference operator*(const Loc&);
1442 reference operator[](const Loc&, const difference_type&);
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&);
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;
1455 template <typename Loc>
1456 struct RandomAccessNDLocatorConcept {
1457 void constraints() {
1458 gil_function_requires< Regular<Loc> >();
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);
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> >();
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));
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);
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);
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
1501 /// \ingroup Locator2DConcept
1502 /// \brief 2-dimensional locator over immutable values
1505 concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc> {
1506 where num_dimensions==2;
1507 where Point2DConcept<point_t>;
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;
1514 // Only available to locators that have dynamic step in Y
1515 //Loc::Loc(const Loc& loc, y_coord_t);
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);
1520 x_iterator& Loc::x();
1521 x_iterator const& Loc::x() const;
1522 y_iterator& Loc::y();
1523 y_iterator const& Loc::y() const;
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;
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;
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;
1541 template <typename Loc>
1542 struct RandomAccess2DLocatorConcept {
1543 void constraints() {
1544 gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
1545 BOOST_STATIC_ASSERT(Loc::num_dimensions==2);
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;
1551 typedef typename Loc::cached_location_t cached_location_t;
1552 gil_function_requires<Point2DConcept<typename Loc::point_t> >();
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;
1559 x_coord_t xd=0; ignore_unused_variable_warning(xd);
1560 y_coord_t yd=0; ignore_unused_variable_warning(yd);
1562 typename Loc::difference_type d;
1563 typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r);
1565 dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
1566 dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
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);
1571 bool is_contiguous=loc.is_1d_traversable(xd); ignore_unused_variable_warning(is_contiguous);
1572 loc.y_distance_to(loc, xd);
1575 loc=loc.xy_at(xd,yd);
1577 x_iterator xit=loc.x_at(d);
1578 xit=loc.x_at(xd,yd);
1581 y_iterator yit=loc.y_at(d);
1582 yit=loc.y_at(xd,yd);
1585 cached_location_t cl=loc.cache_location(xd,yd); ignore_unused_variable_warning(cl);
1590 /// \ingroup PixelLocator2DConcept
1591 /// \brief GIL's 2-dimensional locator over immutable GIL pixels
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;
1600 typename coord_t = x_coord_t;
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));
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> >();
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);
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);
1646 /// \ingroup LocatorNDConcept
1647 /// \brief N-dimensional locator over mutable pixels
1650 concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc> {
1651 where Mutable<reference>;
1655 template <typename Loc>
1656 struct MutableRandomAccessNDLocatorConcept {
1657 void constraints() {
1658 gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
1659 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
1663 /// \ingroup Locator2DConcept
1664 /// \brief 2-dimensional locator over mutable pixels
1667 concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc> : MutableRandomAccessNDLocatorConcept<Loc> {};
1670 template <typename Loc>
1671 struct MutableRandomAccess2DLocatorConcept {
1672 void constraints() {
1673 gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
1674 gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
1678 /// \ingroup PixelLocator2DConcept
1679 /// \brief GIL's 2-dimensional locator over mutable GIL pixels
1682 concept MutablePixelLocatorConcept<PixelLocatorConcept Loc> : MutableRandomAccess2DLocatorConcept<Loc> {};
1685 template <typename Loc>
1686 struct MutablePixelLocatorConcept {
1687 void constraints() {
1688 gil_function_requires<PixelLocatorConcept<Loc> >();
1689 gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
1693 ////////////////////////////////////////////////////////////////////////////////////////
1695 /// IMAGE VIEW CONCEPTS
1697 ////////////////////////////////////////////////////////////////////////////////////////
1699 /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
1700 /// \ingroup ImageViewConcept
1701 /// \brief N-dimensional range
1703 /// \defgroup ImageView2DConcept ImageView2DConcept
1704 /// \ingroup ImageViewConcept
1705 /// \brief 2-dimensional range
1707 /// \defgroup PixelImageViewConcept ImageViewConcept
1708 /// \ingroup ImageViewConcept
1709 /// \brief 2-dimensional range over pixel data
1711 /// \ingroup ImageViewNDConcept
1712 /// \brief N-dimensional view over immutable values
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()
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>;
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);
1740 static const size_t num_dimensions = point_t::num_dimensions;
1742 // Create from a locator at the top-left corner and dimensions
1743 View::View(const locator&, const point_type&);
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?
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;
1758 reference operator()(View,const point_t&) const;
1762 template <typename View>
1763 struct RandomAccessNDImageViewConcept {
1764 void constraints() {
1765 gil_function_requires< Regular<View> >();
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;
1778 gil_function_requires<RandomAccessNDLocatorConcept<locator> >();
1779 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator> >();
1780 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator> >();
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> >();
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));
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));
1799 reverse_iterator rit;
1800 difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
1802 View(p,lc); // view must be constructible from a locator and a point
1804 p=view.dimensions();
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);
1814 reference r1=view[d]; ignore_unused_variable_warning(r1); // 1D access
1815 reference r2=view(p); ignore_unused_variable_warning(r2); // 2D access
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);
1821 typedef PixelDereferenceAdaptorArchetype<typename View::value_type> deref_t;
1822 typedef typename View::template add_deref<deref_t>::type dtype;
1827 /// \ingroup ImageView2DConcept
1828 /// \brief 2-dimensional view over immutable values
1831 concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
1832 where num_dimensions==2;
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;
1840 x_coord_t View::width() const;
1841 y_coord_t View::height() const;
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;
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;
1854 xy_locator View::xy_at(const point_t&) const;
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;
1866 template <typename View>
1867 struct RandomAccess2DImageViewConcept {
1868 void constraints() {
1869 gil_function_requires<RandomAccessNDImageViewConcept<View> >();
1870 BOOST_STATIC_ASSERT(View::num_dimensions==2);
1872 // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
1873 gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator> >();
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;
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;
1885 x_coord_t xd=0; ignore_unused_variable_warning(xd);
1886 y_coord_t yd=0; ignore_unused_variable_warning(yd);
1889 typename View::point_t d;
1891 View(xd,yd,xy_locator()); // constructible with width, height, 2d_locator
1893 xy_locator lc=view.xy_at(xd,yd);
1896 typename View::reference r=view(xd,yd); ignore_unused_variable_warning(r);
1901 xit=view.x_at(xd,yd);
1902 xit=view.row_begin(xd);
1903 xit=view.row_end(xd);
1906 yit=view.y_at(xd,yd);
1907 yit=view.col_begin(xd);
1908 yit=view.col_end(xd);
1914 /// \ingroup PixelImageViewConcept
1915 /// \brief GIL's 2-dimensional view over immutable GIL pixels
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;
1924 typename coord_t = x_coord_t;
1926 std::size_t View::num_channels() const;
1930 template <typename View>
1931 struct ImageViewConcept {
1932 void constraints() {
1933 gil_function_requires<RandomAccess2DImageViewConcept<View> >();
1935 // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
1936 gil_function_requires<PixelLocatorConcept<typename View::xy_locator> >();
1938 BOOST_STATIC_ASSERT((is_same<typename View::x_coord_t, typename View::y_coord_t>::value));
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);
1948 template <typename View> // Preconditions: View Models RandomAccessNDImageViewConcept
1949 struct RandomAccessNDImageViewIsMutableConcept {
1950 void constraints() {
1951 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator> >();
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> >();
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);
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);
1980 template <typename View> // preconditions: View Models ImageViewConcept
1981 struct PixelImageViewIsMutableConcept {
1982 void constraints() {
1983 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
1988 /// \ingroup ImageViewNDConcept
1989 /// \brief N-dimensional view over mutable values
1992 concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View> {
1993 where Mutable<reference>;
1997 template <typename View>
1998 struct MutableRandomAccessNDImageViewConcept {
1999 void constraints() {
2000 gil_function_requires<RandomAccessNDImageViewConcept<View> >();
2001 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
2005 /// \ingroup ImageView2DConcept
2006 /// \brief 2-dimensional view over mutable values
2009 concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View> : MutableRandomAccessNDImageViewConcept<View> {};
2012 template <typename View>
2013 struct MutableRandomAccess2DImageViewConcept {
2014 void constraints() {
2015 gil_function_requires<RandomAccess2DImageViewConcept<View> >();
2016 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
2020 /// \ingroup PixelImageViewConcept
2021 /// \brief GIL's 2-dimensional view over mutable GIL pixels
2024 concept MutableImageViewConcept<ImageViewConcept View> : MutableRandomAccess2DImageViewConcept<View> {};
2027 template <typename View>
2028 struct MutableImageViewConcept {
2029 void constraints() {
2030 gil_function_requires<ImageViewConcept<View> >();
2031 gil_function_requires<detail::PixelImageViewIsMutableConcept<View> >();
2035 /// \brief Returns whether two views are compatible
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> {};
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
2045 concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2> {
2046 where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
2050 template <typename V1, typename V2>
2051 struct ViewsCompatibleConcept {
2052 void constraints() {
2053 BOOST_STATIC_ASSERT((views_are_compatible<V1,V2>::value));
2058 ////////////////////////////////////////////////////////////////////////////////////////
2062 ////////////////////////////////////////////////////////////////////////////////////////
2065 /// \ingroup ImageConcept
2066 /// \brief N-dimensional container of values
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;
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);
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);
2082 const point_t& Img::dimensions() const;
2083 const const_view_t& const_view(const Img&);
2084 const view_t& view(Img&);
2088 template <typename Img>
2089 struct RandomAccessNDImageConcept {
2090 void constraints() {
2091 gil_function_requires<Regular<Img> >();
2093 typedef typename Img::view_t view_t;
2094 gil_function_requires<MutableRandomAccessNDImageViewConcept<view_t> >();
2096 typedef typename Img::const_view_t const_view_t;
2097 typedef typename Img::value_type pixel_t;
2099 typedef typename Img::point_t point_t;
2100 gil_function_requires<PointNDConcept<point_t> >();
2102 const_view_t cv = const_view(img); ignore_unused_variable_warning(cv);
2103 view_t v = view(img); ignore_unused_variable_warning(v);
2106 point_t pt=img.dimensions();
2109 Img im3(pt,fill_value,1);
2112 img.recreate(pt,fill_value,1);
2118 /// \ingroup ImageConcept
2119 /// \brief 2-dimensional container of values
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;
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);
2129 x_coord_t Img::width() const;
2130 y_coord_t Img::height() const;
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);
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;
2145 gil_function_requires<MutableRandomAccess2DImageViewConcept<typename Img::view_t> >();
2147 x_coord_t w=img.width();
2148 y_coord_t h=img.height();
2152 Img im3(w,h,fill_value,1);
2154 img.recreate(w,h,1);
2155 img.recreate(w,h,fill_value,1);
2160 /// \ingroup ImageConcept
2161 /// \brief 2-dimensional image whose value type models PixelValueConcept
2164 concept ImageConcept<RandomAccess2DImageConcept Img> {
2165 where MutableImageViewConcept<view_t>;
2166 typename coord_t = view_t::coord_t;
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);
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));
2185 } } // namespace boost::gil