Modules | Alphabetical List | Class List | Directories | File List | GIL Home Page # gil_concept.hpp Go to the documentation of this file.
    00001 /*
    00002     Copyright 2005-2007 Adobe Systems Incorporated
    00003
    00004     Use, modification and distribution are subject to the Boost Software License,
    00005     Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    00006     http://www.boost.org/LICENSE_1_0.txt).
    00007
    00008     See http://opensource.adobe.com/gil for most recent version including documentation.
    00009 */
    00010
    00011 /*************************************************************************************************/
    00012
    00013 #ifndef GIL_CONCEPT_H
    00014 #define GIL_CONCEPT_H
    00015
    00024
    00025 #include <functional>
    00026 #include "gil_config.hpp"
    00027 #include <boost/type_traits.hpp>
    00028 #include <boost/utility/enable_if.hpp>
    00029 #include <boost/concept_check.hpp>
    00030 #include <boost/iterator/iterator_concepts.hpp>
    00031 #include <boost/mpl/and.hpp>
    00032 #include <boost/mpl/size.hpp>
    00033
    00034 namespace boost { namespace gil {
    00035 template <typename T> struct channel_traits;
    00036 template <typename P> struct is_pixel;
    00037 template <typename dstT, typename srcT>
    00038 typename channel_traits<dstT>::value_type channel_convert(srcT val);
    00039 template <typename T> class point2;
    00040 template <std::size_t K, typename T> const T& axis_value(const point2<T>& p);
    00041 template <std::size_t K, typename T>       T& axis_value(      point2<T>& p);
    00042 template <typename ColorBase, int K> struct kth_element_type;
    00043 template <typename ColorBase, int K> struct kth_element_reference_type;
    00044 template <typename ColorBase, int K> struct kth_element_const_reference_type;
    00045 template <typename ColorBase, int K> struct kth_semantic_element_reference_type;
    00046 template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type;
    00047 template <typename ColorBase> struct size;
    00048 template <typename ColorBase> struct element_type;
    00049 template <typename T> struct channel_type;
    00050 template <typename T> struct color_space_type;
    00051 template <typename T> struct channel_mapping_type;
    00052 template <typename T> struct is_planar;
    00053 template <typename T> struct num_channels;
    00054
    00055 template <typename It> struct const_iterator_type;
    00056 template <typename It> struct iterator_is_mutable;
    00057 template <typename It> struct is_iterator_adaptor;
    00058 template <typename It, typename NewBaseIt> struct iterator_adaptor_rebind;
    00059 template <typename It> struct iterator_adaptor_get_base;
    00060
    00061
    00062 // forward-declare at_c
    00063 namespace detail { template <typename Element, typename Layout, int K> struct homogeneous_color_base; }
    00064 template <int K, typename E, typename L, int N>
    00065 typename add_reference<E>::type                           at_c(      detail::homogeneous_color_base<E,L,N>& p);
    00066
    00067 template <int K, typename E, typename L, int N>
    00068 typename add_reference<typename add_const<E>::type>::type at_c(const detail::homogeneous_color_base<E,L,N>& p);
    00069
    00070 #if !defined(_MSC_VER)  || _MSC_VER > 1310
    00071 template <typename P, typename C, typename L> struct packed_pixel;
    00072 template <int K, typename P, typename C, typename L>
    00073 typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type
    00074 at_c(packed_pixel<P,C,L>& p);
    00075
    00076 template <int K, typename P, typename C, typename L>
    00077 typename kth_element_const_reference_type<packed_pixel<P,C,L>,K>::type
    00078 at_c(const packed_pixel<P,C,L>& p);
    00079
    00080 template <typename B, typename C, typename L, bool M> struct bit_aligned_pixel_reference;
    00081
    00082 template <int K, typename B, typename C, typename L, bool M> inline
    00083 typename kth_element_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>::type
    00084 at_c(const bit_aligned_pixel_reference<B,C,L,M>& p);
    00085 #endif
    00086
    00087 // Forward-declare semantic_at_c
    00088 template <int K, typename ColorBase>
    00089 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
    00090 template <int K, typename ColorBase>
    00091 typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
    00092
    00093 template <typename T> struct dynamic_x_step_type;
    00094 template <typename T> struct dynamic_y_step_type;
    00095 template <typename T> struct transposed_type;
    00096
    00097 namespace detail {
    00098 template <typename T>
    00099 void initialize_it(T& x) {}
    00100 } // namespace detail
    00101
    00102 template <typename T>
    00103 struct remove_const_and_reference : public remove_const<typename remove_reference<T>::type> {};
    00104
    00105 #ifdef BOOST_GIL_USE_CONCEPT_CHECK
    00106     #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept);
    00107     template <typename C> void gil_function_requires() { function_requires<C>(); }
    00108 #else
    00109     #define GIL_CLASS_REQUIRE(T,NS,C)
    00110     template <typename C> void gil_function_requires() {}
    00111 #endif
    00112
    00114
    00121 template <typename T>
    00122 struct DefaultConstructible {
    00123     void constraints() {
    00124         function_requires<boost::DefaultConstructibleConcept<T> >();
    00125     }
    00126 };
    00127
    00129
    00136 template <typename T>
    00137 struct CopyConstructible {
    00138     void constraints() {
    00139         function_requires<boost::CopyConstructibleConcept<T> >();
    00140     }
    00141 };
    00142
    00144
    00152 template <typename T>
    00153 struct Assignable {
    00154     void constraints() {
    00155         function_requires<boost::AssignableConcept<T> >();
    00156     }
    00157 };
    00159
    00167 template <typename T>
    00168 struct EqualityComparable {
    00169     void constraints() {
    00170         function_requires<boost::EqualityComparableConcept<T> >();
    00171     }
    00172 };
    00173
    00175
    00181 template <typename T, typename U>
    00182 struct SameType {
    00183     void constraints() {
    00184         BOOST_STATIC_ASSERT((boost::is_same<T,U>::value_core));
    00185     }
    00186 };
    00187
    00189
    00196 template <typename T>
    00197 struct Swappable {
    00198     void constraints() {
    00199         using std::swap;
    00200         swap(x,y);
    00201     }
    00202     T x,y;
    00203 };
    00204
    00206
    00213 template <typename T>
    00214 struct Regular {
    00215     void constraints() {
    00216         gil_function_requires< boost::DefaultConstructibleConcept<T> >();
    00217         gil_function_requires< boost::CopyConstructibleConcept<T> >();
    00218         gil_function_requires< boost::EqualityComparableConcept<T> >(); // ==, !=
    00219         gil_function_requires< boost::AssignableConcept<T> >();
    00220         gil_function_requires< Swappable<T> >();
    00221     }
    00222 };
    00223
    00225
    00232 template <typename T>
    00233 struct Metafunction {
    00234     void constraints() {
    00235         typedef typename T::type type;
    00236     }
    00237 };
    00239 //
    00240 //          POINT CONCEPTS
    00241 //
    00243
    00246
    00261 template <typename P>
    00262 struct PointNDConcept {
    00263     void constraints() {
    00264         gil_function_requires< Regular<P> >();
    00265
    00266         typedef typename P::value_type value_type;
    00267         static const std::size_t N=P::num_dimensions; ignore_unused_variable_warning(N);
    00268         typedef typename P::template axis<0>::coord_t FT;
    00269         typedef typename P::template axis<N-1>::coord_t LT;
    00270         FT ft=gil::axis_value<0>(point);
    00271         axis_value<0>(point)=ft;
    00272         LT lt=axis_value<N-1>(point);
    00273         axis_value<N-1>(point)=lt;
    00274
    00275         value_type v=point[0];  ignore_unused_variable_warning(v);
    00276         point[0]=point[0];
    00277     }
    00278     P point;
    00279 };
    00280
    00283
    00299 template <typename P>
    00300 struct Point2DConcept {
    00301     void constraints() {
    00302         gil_function_requires< PointNDConcept<P> >();
    00303         BOOST_STATIC_ASSERT(P::num_dimensions == 2);
    00304         point.x=point.y;
    00305         point[0]=point[1];
    00306     }
    00307     P point;
    00308 };
    00309
    00311 //
    00312 //          ITERATOR MUTABILITY CONCEPTS
    00313 //
    00314 // Taken from boost's concept_check.hpp. Isolating mutability to result in faster compile time
    00315 //
    00317
    00318 namespace detail {
    00319     template <class TT> // Preconditions: TT Models boost_concepts::ForwardTraversalConcept
    00320     struct ForwardIteratorIsMutableConcept {
    00321         void constraints() {
    00322             *i++ = *i;         // require postincrement and assignment
    00323         }
    00324         TT i;
    00325     };
    00326
    00327     template <class TT> // Preconditions: TT Models boost::BidirectionalIteratorConcept
    00328     struct BidirectionalIteratorIsMutableConcept {
    00329         void constraints() {
    00330             gil_function_requires< ForwardIteratorIsMutableConcept<TT> >();
    00331             *i-- = *i;                  // require postdecrement and assignment
    00332         }
    00333         TT i;
    00334     };
    00335
    00336     template <class TT> // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept
    00337     struct RandomAccessIteratorIsMutableConcept {
    00338         void constraints() {
    00339             gil_function_requires< BidirectionalIteratorIsMutableConcept<TT> >();
    00340             typename std::iterator_traits<TT>::difference_type n=0; ignore_unused_variable_warning(n);
    00341             i[n] = *i;                  // require element access and assignment
    00342         }
    00343         TT i;
    00344     };
    00345 }   // namespace detail
    00346
    00348 //
    00349 //         COLOR SPACE CONCEPTS
    00350 //
    00352
    00355
    00362 template <typename Cs>
    00363 struct ColorSpaceConcept {
    00364     void constraints() {
    00365         // An MPL Random Access Sequence, whose elements are color tags
    00366     }
    00367 };
    00368
    00369 template <typename ColorSpace1, typename ColorSpace2>  // Models ColorSpaceConcept
    00370 struct color_spaces_are_compatible : public is_same<ColorSpace1,ColorSpace2> {};
    00371
    00374
    00381 template <typename Cs1, typename Cs2>
    00382 struct ColorSpacesCompatibleConcept {
    00383     void constraints() {
    00384         BOOST_STATIC_ASSERT((color_spaces_are_compatible<Cs1,Cs2>::value));
    00385     }
    00386 };
    00387
    00390
    00397 template <typename CM>
    00398 struct ChannelMappingConcept {
    00399     void constraints() {
    00400         // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
    00401     }
    00402 };
    00403
    00404
    00405
    00411
    00414
    00436 template <typename T>
    00437 struct ChannelConcept {
    00438     void constraints() {
    00439         gil_function_requires< boost::EqualityComparableConcept<T> >();
    00440
    00441         typedef typename channel_traits<T>::value_type v;
    00442         typedef typename channel_traits<T>::reference r;
    00443         typedef typename channel_traits<T>::pointer p;
    00444         typedef typename channel_traits<T>::const_reference cr;
    00445         typedef typename channel_traits<T>::const_pointer cp;
    00446
    00447         channel_traits<T>::min_value();
    00448         channel_traits<T>::max_value();
    00449     }
    00450
    00451      T c;
    00452 };
    00453
    00454 namespace detail {
    00455     // Preconditions: T models ChannelConcept
    00456     template <typename T>
    00457     struct ChannelIsMutableConcept {
    00458         void constraints() {
    00459             c=c;
    00460             using std::swap;
    00461             swap(c,c);
    00462         }
    00463         T c;
    00464     };
    00465 }
    00466
    00469
    00474 template <typename T>
    00475 struct MutableChannelConcept {
    00476     void constraints() {
    00477         gil_function_requires<ChannelConcept<T> >();
    00478         gil_function_requires<detail::ChannelIsMutableConcept<T> >();
    00479     }
    00480 };
    00481
    00484
    00489 template <typename T>
    00490 struct ChannelValueConcept {
    00491     void constraints() {
    00492         gil_function_requires<ChannelConcept<T> >();
    00493         gil_function_requires<Regular<T> >();
    00494     }
    00495 };
    00496
    00497
    00502
    00509 template <typename T1, typename T2>  // Models GIL Pixel
    00510 struct channels_are_compatible
    00511     : public is_same<typename channel_traits<T1>::value_type, typename channel_traits<T2>::value_type> {};
    00512
    00515
    00522 template <typename T1, typename T2>
    00523 struct ChannelsCompatibleConcept {
    00524     void constraints() {
    00525         BOOST_STATIC_ASSERT((channels_are_compatible<T1,T2>::value));
    00526     }
    00527 };
    00528
    00533
    00540 template <typename SrcChannel, typename DstChannel>
    00541 struct ChannelConvertibleConcept {
    00542     void constraints() {
    00543         gil_function_requires<ChannelConcept<SrcChannel> >();
    00544         gil_function_requires<MutableChannelConcept<DstChannel> >();
    00545         dst=channel_convert<DstChannel,SrcChannel>(src); ignore_unused_variable_warning(dst);
    00546     }
    00547     SrcChannel src;
    00548     DstChannel dst;
    00549 };
    00550
    00551
    00552
    00553
    00554
    00560
    00563
    00603 template <typename ColorBase>
    00604 struct ColorBaseConcept {
    00605     void constraints() {
    00606         gil_function_requires< CopyConstructible<ColorBase> >();
    00607         gil_function_requires< EqualityComparable<ColorBase> >();
    00608
    00609         typedef typename ColorBase::layout_t::color_space_t color_space_t;
    00610         gil_function_requires<ColorSpaceConcept<color_space_t> >();
    00611
    00612         typedef typename ColorBase::layout_t::channel_mapping_t channel_mapping_t;
    00613         // TODO: channel_mapping_t must be an MPL RandomAccessSequence
    00614
    00615         static const std::size_t num_elements = size<ColorBase>::value;
    00616
    00617         typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
    00618         typedef typename kth_element_const_reference_type<ColorBase,num_elements-1>::type CR;
    00619
    00620 #if !defined(_MSC_VER) || _MSC_VER > 1310
    00621         CR cr=at_c<num_elements-1>(cb);  ignore_unused_variable_warning(cr);
    00622 #endif
    00623
    00624         // functions that work for every pixel (no need to require them)
    00625         semantic_at_c<0>(cb);
    00626         semantic_at_c<num_elements-1>(cb);
    00627         // also static_max(cb), static_min(cb), static_fill(cb,value), and all variations of static_for_each(), static_generate(), static_transform()
    00628     }
    00629
    00630     ColorBase cb;
    00631 };
    00632
    00635
    00648 template <typename ColorBase>
    00649 struct MutableColorBaseConcept {
    00650     void constraints() {
    00651         gil_function_requires< ColorBaseConcept<ColorBase> >();
    00652         gil_function_requires< Assignable<ColorBase> >();
    00653         gil_function_requires< Swappable<ColorBase> >();
    00654
    00655         typedef typename kth_element_reference_type<ColorBase, 0>::type CR;
    00656
    00657 #if !defined(_MSC_VER) || _MSC_VER > 1310
    00658         CR r=at_c<0>(cb);
    00659         at_c<0>(cb)=r;
    00660 #endif
    00661     }
    00662
    00663     ColorBase cb;
    00664 };
    00665
    00668
    00674 template <typename ColorBase>
    00675 struct ColorBaseValueConcept {
    00676     void constraints() {
    00677         gil_function_requires< MutableColorBaseConcept<ColorBase> >();
    00678         gil_function_requires< Regular<ColorBase> >();
    00679     }
    00680 };
    00681
    00684
    00694 template <typename ColorBase>
    00695 struct HomogeneousColorBaseConcept {
    00696     void constraints() {
    00697         gil_function_requires< ColorBaseConcept<ColorBase> >();
    00698
    00699         static const std::size_t num_elements = size<ColorBase>::value;
    00700
    00701         typedef typename kth_element_type<ColorBase,0>::type T0;
    00702         typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
    00703
    00704         BOOST_STATIC_ASSERT((is_same<T0,TN>::value));   // better than nothing
    00705         typedef typename kth_element_const_reference_type<ColorBase,0>::type CRef0;
    00706         CRef0 e0=dynamic_at_c(cb,0);
    00707     }
    00708     ColorBase cb;
    00709 };
    00710
    00713
    00722 template <typename ColorBase>
    00723 struct MutableHomogeneousColorBaseConcept {
    00724     void constraints() {
    00725         gil_function_requires< ColorBaseConcept<ColorBase> >();
    00726         gil_function_requires< HomogeneousColorBaseConcept<ColorBase> >();
    00727         typedef typename kth_element_reference_type<ColorBase, 0>::type R0;
    00728         R0 x=dynamic_at_c(cb,0);
    00729         dynamic_at_c(cb,0) = dynamic_at_c(cb,0);
    00730     }
    00731     ColorBase cb;
    00732 };
    00733
    00736
    00744 template <typename ColorBase>
    00745 struct HomogeneousColorBaseValueConcept {
    00746     void constraints() {
    00747         gil_function_requires< MutableHomogeneousColorBaseConcept<ColorBase> >();
    00748         gil_function_requires< Regular<ColorBase> >();
    00749     }
    00750 };
    00751
    00752
    00755
    00766 template <typename ColorBase1, typename ColorBase2>
    00767 struct ColorBasesCompatibleConcept {
    00768     void constraints() {
    00769         BOOST_STATIC_ASSERT((is_same<typename ColorBase1::layout_t::color_space_t,
    00770                                      typename ColorBase2::layout_t::color_space_t>::value));
    00771 //        typedef typename kth_semantic_element_type<ColorBase1,0>::type e1;
    00772 //        typedef typename kth_semantic_element_type<ColorBase2,0>::type e2;
    00773 //        "e1 is convertible to e2"
    00774     }
    00775 };
    00776
    00777
    00778
    00779
    00780
    00781
    00782
    00783
    00784
    00785
    00786
    00787
    00788
    00789
    00790
    00791
    00792
    00793
    00794
    00795
    00796
    00797
    00803
    00806
    00821 template <typename P>
    00822 struct PixelBasedConcept {
    00823     void constraints() {
    00824         typedef typename color_space_type<P>::type color_space_t;
    00825         gil_function_requires<ColorSpaceConcept<color_space_t> >();
    00826         typedef typename channel_mapping_type<P>::type channel_mapping_t;
    00827         gil_function_requires<ChannelMappingConcept<channel_mapping_t> >();
    00828
    00829         static const bool planar = is_planar<P>::type::value;   ignore_unused_variable_warning(planar);
    00830
    00831
    00832         // This is not part of the concept, but should still work
    00833         static const std::size_t nc = num_channels<P>::value;
    00834         ignore_unused_variable_warning(nc);
    00835     }
    00836 };
    00837
    00840
    00849 template <typename P>
    00850 struct HomogeneousPixelBasedConcept {
    00851     void constraints() {
    00852         gil_function_requires<PixelBasedConcept<P> >();
    00853         typedef typename channel_type<P>::type channel_t;
    00854         gil_function_requires<ChannelConcept<channel_t> >();
    00855     }
    00856 };
    00857
    00858
    00861
    00883 template <typename P>
    00884 struct PixelConcept {
    00885     void constraints() {
    00886         gil_function_requires<ColorBaseConcept<P> >();
    00887         gil_function_requires<PixelBasedConcept<P> >();
    00888
    00889         BOOST_STATIC_ASSERT((is_pixel<P>::value));
    00890         static const bool is_mutable = P::is_mutable; ignore_unused_variable_warning(is_mutable);
    00891
    00892         typedef typename P::value_type      value_type;
    00893 //      gil_function_requires<PixelValueConcept<value_type> >();
    00894
    00895         typedef typename P::reference       reference;
    00896         gil_function_requires<PixelConcept<typename remove_const_and_reference<reference>::type> >();
    00897
    00898         typedef typename P::const_reference const_reference;
    00899         gil_function_requires<PixelConcept<typename remove_const_and_reference<const_reference>::type> >();
    00900     }
    00901 };
    00902
    00903
    00906
    00913 template <typename P>
    00914 struct MutablePixelConcept {
    00915     void constraints() {
    00916         gil_function_requires<PixelConcept<P> >();
    00917         BOOST_STATIC_ASSERT(P::is_mutable);
    00918     }
    00919 };
    00922
    00929 template <typename P>
    00930 struct HomogeneousPixelConcept {
    00931     void constraints() {
    00932         gil_function_requires<PixelConcept<P> >();
    00933         gil_function_requires<HomogeneousColorBaseConcept<P> >();
    00934         gil_function_requires<HomogeneousPixelBasedConcept<P> >();
    00935         p[0];
    00936     }
    00937     P p;
    00938 };
    00939
    00942
    00949 template <typename P>
    00950 struct MutableHomogeneousPixelConcept {
    00951     void constraints() {
    00952         gil_function_requires<HomogeneousPixelConcept<P> >();
    00953         gil_function_requires<MutableHomogeneousColorBaseConcept<P> >();
    00954         p[0]=p[0];
    00955     }
    00956     P p;
    00957 };
    00958
    00961
    00968 template <typename P>
    00969 struct PixelValueConcept {
    00970     void constraints() {
    00971         gil_function_requires<PixelConcept<P> >();
    00972         gil_function_requires<Regular<P> >();
    00973     }
    00974 };
    00975
    00978
    00985 template <typename P>
    00986 struct HomogeneousPixelValueConcept {
    00987     void constraints() {
    00988         gil_function_requires<HomogeneousPixelConcept<P> >();
    00989         gil_function_requires<Regular<P> >();
    00990         BOOST_STATIC_ASSERT((is_same<P, typename P::value_type>::value));
    00991     }
    00992 };
    00993
    00994 namespace detail {
    00995     template <typename P1, typename P2, int K>
    00996     struct channels_are_pairwise_compatible : public
    00997         mpl::and_<channels_are_pairwise_compatible<P1,P2,K-1>,
    00998                          channels_are_compatible<typename kth_semantic_element_reference_type<P1,K>::type,
    00999                                                  typename kth_semantic_element_reference_type<P2,K>::type> > {};
    01000
    01001     template <typename P1, typename P2>
    01002     struct channels_are_pairwise_compatible<P1,P2,-1> : public mpl::true_ {};
    01003 }
    01004
    01009 template <typename P1, typename P2>  // Models GIL Pixel
    01010 struct pixels_are_compatible
    01011     : public mpl::and_<typename color_spaces_are_compatible<typename color_space_type<P1>::type,
    01012                                                             typename color_space_type<P2>::type>::type,
    01013                        detail::channels_are_pairwise_compatible<P1,P2,num_channels<P1>::value-1> > {};
    01014
    01018
    01026 template <typename P1, typename P2> // precondition: P1 and P2 model PixelConcept
    01027 struct PixelsCompatibleConcept {
    01028     void constraints() {
    01029         BOOST_STATIC_ASSERT((pixels_are_compatible<P1,P2>::value));
    01030     }
    01031 };
    01032
    01037
    01045 template <typename SrcP, typename DstP>
    01046 struct PixelConvertibleConcept {
    01047     void constraints() {
    01048         gil_function_requires<PixelConcept<SrcP> >();
    01049         gil_function_requires<MutablePixelConcept<DstP> >();
    01050         color_convert(src,dst);
    01051     }
    01052     SrcP src;
    01053     DstP dst;
    01054 };
    01055
    01061
    01063
    01067
    01082 template <typename D>
    01083 struct PixelDereferenceAdaptorConcept {
    01084     void constraints() {
    01085         gil_function_requires< boost::UnaryFunctionConcept<D,
    01086             typename remove_const_and_reference<typename D::result_type>::type,
    01087             typename D::argument_type> >();
    01088         gil_function_requires< boost::DefaultConstructibleConcept<D> >();
    01089         gil_function_requires< boost::CopyConstructibleConcept<D> >();
    01090         gil_function_requires< boost::AssignableConcept<D> >();
    01091
    01092         gil_function_requires<PixelConcept<typename remove_const_and_reference<typename D::result_type>::type> >();
    01093
    01094         typedef typename D::const_t const_t;
    01095         gil_function_requires<PixelDereferenceAdaptorConcept<const_t> >();
    01096         typedef typename D::value_type value_type;
    01097         gil_function_requires<PixelValueConcept<value_type> >();
    01098         typedef typename D::reference reference;                // == PixelConcept (if you remove const and reference)
    01099         typedef typename D::const_reference const_reference;    // == PixelConcept (if you remove const and reference)
    01100
    01101         const bool is_mutable=D::is_mutable; ignore_unused_variable_warning(is_mutable);
    01102     }
    01103     D d;
    01104 };
    01105
    01106 template <typename P>
    01107 struct PixelDereferenceAdaptorArchetype : public std::unary_function<P, P> {
    01108     typedef PixelDereferenceAdaptorArchetype const_t;
    01109     typedef typename remove_reference<P>::type value_type;
    01110     typedef typename add_reference<P>::type reference;
    01111     typedef reference const_reference;
    01112     static const bool is_mutable=false;
    01113     P operator()(P x) const { throw; }
    01114 };
    01115
    01121
    01124
    01132 template <typename T>
    01133 struct HasDynamicXStepTypeConcept {
    01134     void constraints() {
    01135         typedef typename dynamic_x_step_type<T>::type type;
    01136     }
    01137 };
    01138
    01141
    01149 template <typename T>
    01150 struct HasDynamicYStepTypeConcept {
    01151     void constraints() {
    01152         typedef typename dynamic_y_step_type<T>::type type;
    01153     }
    01154 };
    01155
    01156
    01159
    01167 template <typename T>
    01168 struct HasTransposedTypeConcept {
    01169     void constraints() {
    01170         typedef typename transposed_type<T>::type type;
    01171     }
    01172 };
    01173
    01177
    01180
    01196 template <typename Iterator>
    01197 struct PixelIteratorConcept {
    01198     void constraints() {
    01199         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
    01200         gil_function_requires<PixelBasedConcept<Iterator> >();
    01201
    01202         typedef typename std::iterator_traits<Iterator>::value_type value_type;
    01203         gil_function_requires<PixelValueConcept<value_type> >();
    01204
    01205         typedef typename const_iterator_type<Iterator>::type const_t;
    01206         static const bool is_mut = iterator_is_mutable<Iterator>::type::value; ignore_unused_variable_warning(is_mut);
    01207
    01208         const_t const_it(it);  ignore_unused_variable_warning(const_it);  // immutable iterator must be constructible from (possibly mutable) iterator
    01209
    01210         check_base(typename is_iterator_adaptor<Iterator>::type());
    01211     }
    01212     void check_base(mpl::false_) {}
    01213     void check_base(mpl::true_) {
    01214         typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
    01215         gil_function_requires<PixelIteratorConcept<base_t> >();
    01216     }
    01217
    01218     Iterator it;
    01219 };
    01220
    01221 namespace detail {
    01222     template <typename Iterator>  // Preconditions: Iterator Models PixelIteratorConcept
    01223     struct PixelIteratorIsMutableConcept {
    01224         void constraints() {
    01225             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<Iterator> >();
    01226             typedef typename remove_reference<typename std::iterator_traits<Iterator>::reference>::type ref;
    01227             typedef typename element_type<ref>::type channel_t;
    01228             gil_function_requires<detail::ChannelIsMutableConcept<channel_t> >();
    01229         }
    01230     };
    01231 }
    01232
    01235
    01241 template <typename Iterator>
    01242 struct MutablePixelIteratorConcept {
    01243     void constraints() {
    01244         gil_function_requires<PixelIteratorConcept<Iterator> >();
    01245         gil_function_requires<detail::PixelIteratorIsMutableConcept<Iterator> >();
    01246     }
    01247 };
    01248
    01249 namespace detail {
    01250     // Iterators that can be used as the base of memory_based_step_iterator require some additional functions
    01251     template <typename Iterator>  // Preconditions: Iterator Models boost_concepts::RandomAccessTraversalConcept
    01252     struct RandomAccessIteratorIsMemoryBasedConcept {
    01253         void constraints() {
    01254             std::ptrdiff_t bs=memunit_step(it);  ignore_unused_variable_warning(bs);
    01255             it=memunit_advanced(it,3);
    01256             std::ptrdiff_t bd=memunit_distance(it,it);  ignore_unused_variable_warning(bd);
    01257             memunit_advance(it,3);
    01258             // for performace you may also provide a customized implementation of memunit_advanced_ref
    01259         }
    01260         Iterator it;
    01261     };
    01262 }
    01263
    01267
    01270
    01282 template <typename Iterator>
    01283 struct MemoryBasedIteratorConcept {
    01284     void constraints() {
    01285         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
    01286         gil_function_requires<detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator> >();
    01287     }
    01288 };
    01289
    01294
    01301 template <typename Iterator>
    01302 struct StepIteratorConcept {
    01303     void constraints() {
    01304         gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
    01305         it.set_step(0);
    01306     }
    01307     Iterator it;
    01308 };
    01309
    01310
    01314
    01319 template <typename Iterator>
    01320 struct MutableStepIteratorConcept {
    01321     void constraints() {
    01322         gil_function_requires<StepIteratorConcept<Iterator> >();
    01323         gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
    01324     }
    01325 };
    01326
    01330
    01333
    01358 template <typename Iterator>
    01359 struct IteratorAdaptorConcept {
    01360     void constraints() {
    01361         gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
    01362
    01363         typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
    01364         gil_function_requires<boost_concepts::ForwardTraversalConcept<base_t> >();
    01365
    01366         BOOST_STATIC_ASSERT(is_iterator_adaptor<Iterator>::value);
    01367         typedef typename iterator_adaptor_rebind<Iterator, void*>::type rebind_t;
    01368
    01369         base_t base=it.base();  ignore_unused_variable_warning(base);
    01370     }
    01371     Iterator it;
    01372 };
    01373
    01376
    01381 template <typename Iterator>
    01382 struct MutableIteratorAdaptorConcept {
    01383     void constraints() {
    01384         gil_function_requires<IteratorAdaptorConcept<Iterator> >();
    01385         gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
    01386     }
    01387 };
    01388
    01394
    01398
    01402
    01406
    01409
    01455 template <typename Loc>
    01456 struct RandomAccessNDLocatorConcept {
    01457     void constraints() {
    01458         gil_function_requires< Regular<Loc> >();
    01459
    01460         typedef typename Loc::value_type        value_type;
    01461         typedef typename Loc::reference         reference;          // result of dereferencing
    01462         typedef typename Loc::difference_type   difference_type;    // result of operator-(pixel_locator, pixel_locator)
    01463         typedef typename Loc::cached_location_t cached_location_t;  // type used to store relative location (to allow for more efficient repeated access)
    01464         typedef typename Loc::const_t           const_t;         // same as this type, but over const values
    01465         typedef typename Loc::point_t           point_t;         // same as difference_type
    01466         static const std::size_t N=Loc::num_dimensions; ignore_unused_variable_warning(N);
    01467
    01468         typedef typename Loc::template axis<0>::iterator    first_it_type;
    01469         typedef typename Loc::template axis<N-1>::iterator  last_it_type;
    01470         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type> >();
    01471         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type> >();
    01472
    01473         // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
    01474         gil_function_requires<PointNDConcept<point_t> >();
    01475         BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
    01476         BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
    01477         BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
    01478
    01479         difference_type d;
    01480         loc+=d;
    01481         loc-=d;
    01482         loc=loc+d;
    01483         loc=loc-d;
    01484         reference r1=loc[d];  ignore_unused_variable_warning(r1);
    01485         reference r2=*loc;  ignore_unused_variable_warning(r2);
    01486         cached_location_t cl=loc.cache_location(d);  ignore_unused_variable_warning(cl);
    01487         reference r3=loc[d];  ignore_unused_variable_warning(r3);
    01488
    01489         first_it_type fi=loc.template axis_iterator<0>();
    01490         fi=loc.template axis_iterator<0>(d);
    01491         last_it_type li=loc.template axis_iterator<N-1>();
    01492         li=loc.template axis_iterator<N-1>(d);
    01493
    01494         typedef PixelDereferenceAdaptorArchetype<typename Loc::value_type> deref_t;
    01495         typedef typename Loc::template add_deref<deref_t>::type dtype;
    01496         //gil_function_requires<RandomAccessNDLocatorConcept<dtype> >();    // infinite recursion
    01497     }
    01498     Loc loc;
    01499 };
    01500
    01503
    01541 template <typename Loc>
    01542 struct RandomAccess2DLocatorConcept {
    01543     void constraints() {
    01544         gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
    01545         BOOST_STATIC_ASSERT(Loc::num_dimensions==2);
    01546
    01547         typedef typename dynamic_x_step_type<Loc>::type dynamic_x_step_t;
    01548         typedef typename dynamic_y_step_type<Loc>::type dynamic_y_step_t;
    01549         typedef typename transposed_type<Loc>::type     transposed_t;
    01550
    01551         typedef typename Loc::cached_location_t   cached_location_t;
    01552         gil_function_requires<Point2DConcept<typename Loc::point_t> >();
    01553
    01554         typedef typename Loc::x_iterator x_iterator;
    01555         typedef typename Loc::y_iterator y_iterator;
    01556         typedef typename Loc::x_coord_t  x_coord_t;
    01557         typedef typename Loc::y_coord_t  y_coord_t;
    01558
    01559         x_coord_t xd=0; ignore_unused_variable_warning(xd);
    01560         y_coord_t yd=0; ignore_unused_variable_warning(yd);
    01561
    01562         typename Loc::difference_type d;
    01563         typename Loc::reference r=loc(xd,yd);  ignore_unused_variable_warning(r);
    01564
    01565         dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
    01566         dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
    01567
    01568         typedef typename dynamic_y_step_type<typename dynamic_x_step_type<transposed_t>::type>::type dynamic_xy_step_transposed_t;
    01569         dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
    01570
    01571         bool is_contiguous=loc.is_1d_traversable(xd); ignore_unused_variable_warning(is_contiguous);
    01572         loc.y_distance_to(loc, xd);
    01573
    01574         loc=loc.xy_at(d);
    01575         loc=loc.xy_at(xd,yd);
    01576
    01577         x_iterator xit=loc.x_at(d);
    01578         xit=loc.x_at(xd,yd);
    01579         xit=loc.x();
    01580
    01581         y_iterator yit=loc.y_at(d);
    01582         yit=loc.y_at(xd,yd);
    01583         yit=loc.y();
    01584
    01585         cached_location_t cl=loc.cache_location(xd,yd);  ignore_unused_variable_warning(cl);
    01586     }
    01587     Loc loc;
    01588 };
    01589
    01592
    01604 template <typename Loc>
    01605 struct PixelLocatorConcept {
    01606     void constraints() {
    01607         gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
    01608         gil_function_requires< PixelIteratorConcept<typename Loc::x_iterator> >();
    01609         gil_function_requires< PixelIteratorConcept<typename Loc::y_iterator> >();
    01610         typedef typename Loc::coord_t                      coord_t;
    01611         BOOST_STATIC_ASSERT((is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value));
    01612     }
    01613     Loc loc;
    01614 };
    01615
    01616 namespace detail {
    01617     template <typename Loc> // preconditions: Loc Models RandomAccessNDLocatorConcept
    01618     struct RandomAccessNDLocatorIsMutableConcept {
    01619         void constraints() {
    01620             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename Loc::template axis<0>::iterator> >();
    01621             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename Loc::template axis<Loc::num_dimensions-1>::iterator> >();
    01622
    01623             typename Loc::difference_type d; initialize_it(d);
    01624             typename Loc::value_type v;initialize_it(v);
    01625             typename Loc::cached_location_t cl=loc.cache_location(d);
    01626             *loc=v;
    01627             loc[d]=v;
    01628             loc[cl]=v;
    01629         }
    01630         Loc loc;
    01631     };
    01632
    01633     template <typename Loc> // preconditions: Loc Models RandomAccess2DLocatorConcept
    01634     struct RandomAccess2DLocatorIsMutableConcept {
    01635         void constraints() {
    01636             gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
    01637             typename Loc::x_coord_t xd=0; ignore_unused_variable_warning(xd);
    01638             typename Loc::y_coord_t yd=0; ignore_unused_variable_warning(yd);
    01639             typename Loc::value_type v; initialize_it(v);
    01640             loc(xd,yd)=v;
    01641         }
    01642         Loc loc;
    01643     };
    01644 }
    01645
    01648
    01655 template <typename Loc>
    01656 struct MutableRandomAccessNDLocatorConcept {
    01657     void constraints() {
    01658         gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
    01659         gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
    01660     }
    01661 };
    01662
    01665
    01670 template <typename Loc>
    01671 struct MutableRandomAccess2DLocatorConcept {
    01672     void constraints() {
    01673         gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
    01674         gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
    01675     }
    01676 };
    01677
    01680
    01685 template <typename Loc>
    01686 struct MutablePixelLocatorConcept {
    01687     void constraints() {
    01688         gil_function_requires<PixelLocatorConcept<Loc> >();
    01689         gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
    01690     }
    01691 };
    01692
    01698
    01702
    01706
    01710
    01713
    01762 template <typename View>
    01763 struct RandomAccessNDImageViewConcept {
    01764     void constraints() {
    01765         gil_function_requires< Regular<View> >();
    01766
    01767         typedef typename View::value_type       value_type;
    01768         typedef typename View::reference        reference;       // result of dereferencing
    01769         typedef typename View::difference_type  difference_type; // result of operator-(1d_iterator,1d_iterator)
    01770         typedef typename View::const_t          const_t;         // same as this type, but over const values
    01771         typedef typename View::point_t          point_t;         // N-dimensional point
    01772         typedef typename View::locator          locator;         // N-dimensional locator
    01773         typedef typename View::iterator         iterator;
    01774         typedef typename View::reverse_iterator reverse_iterator;
    01775         typedef typename View::size_type        size_type;
    01776         static const std::size_t N=View::num_dimensions;
    01777
    01778         gil_function_requires<RandomAccessNDLocatorConcept<locator> >();
    01779         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator> >();
    01780         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator> >();
    01781
    01782         typedef typename View::template axis<0>::iterator   first_it_type;
    01783         typedef typename View::template axis<N-1>::iterator last_it_type;
    01784         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type> >();
    01785         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type> >();
    01786
    01787 //        BOOST_STATIC_ASSERT((typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
    01788 //        BOOST_STATIC_ASSERT((typename std::iterator_traits< last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
    01789
    01790         // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
    01791         gil_function_requires<PointNDConcept<point_t> >();
    01792         BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
    01793         BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
    01794         BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
    01795
    01796         point_t p;
    01797         locator lc;
    01798         iterator it;
    01799         reverse_iterator rit;
    01800         difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
    01801
    01802         View(p,lc); // view must be constructible from a locator and a point
    01803
    01804         p=view.dimensions();
    01805         lc=view.pixels();
    01806         size_type sz=view.size();  ignore_unused_variable_warning(sz);
    01807         bool is_contiguous=view.is_1d_traversable(); ignore_unused_variable_warning(is_contiguous);
    01808
    01809         it=view.begin();
    01810         it=view.end();
    01811         rit=view.rbegin();
    01812         rit=view.rend();
    01813
    01814         reference r1=view[d]; ignore_unused_variable_warning(r1);    // 1D access
    01815         reference r2=view(p); ignore_unused_variable_warning(r2);    // 2D access
    01816
    01817         // get 1-D iterator of any dimension at a given pixel location
    01818         first_it_type fi=view.template axis_iterator<0>(p); ignore_unused_variable_warning(fi);
    01819         last_it_type li=view.template axis_iterator<N-1>(p); ignore_unused_variable_warning(li);
    01820
    01821         typedef PixelDereferenceAdaptorArchetype<typename View::value_type> deref_t;
    01822         typedef typename View::template add_deref<deref_t>::type dtype;
    01823     }
    01824     View view;
    01825 };
    01826
    01829
    01866 template <typename View>
    01867 struct RandomAccess2DImageViewConcept {
    01868     void constraints() {
    01869         gil_function_requires<RandomAccessNDImageViewConcept<View> >();
    01870         BOOST_STATIC_ASSERT(View::num_dimensions==2);
    01871
    01872         // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
    01873         gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator> >();
    01874
    01875         typedef typename dynamic_x_step_type<View>::type  dynamic_x_step_t;
    01876         typedef typename dynamic_y_step_type<View>::type  dynamic_y_step_t;
    01877         typedef typename transposed_type<View>::type      transposed_t;
    01878
    01879         typedef typename View::x_iterator x_iterator;
    01880         typedef typename View::y_iterator y_iterator;
    01881         typedef typename View::x_coord_t  x_coord_t;
    01882         typedef typename View::y_coord_t  y_coord_t;
    01883         typedef typename View::xy_locator xy_locator;
    01884
    01885         x_coord_t xd=0; ignore_unused_variable_warning(xd);
    01886         y_coord_t yd=0; ignore_unused_variable_warning(yd);
    01887         x_iterator xit;
    01888         y_iterator yit;
    01889         typename View::point_t d;
    01890
    01891         View(xd,yd,xy_locator());       // constructible with width, height, 2d_locator
    01892
    01893         xy_locator lc=view.xy_at(xd,yd);
    01894         lc=view.xy_at(d);
    01895
    01896         typename View::reference r=view(xd,yd);  ignore_unused_variable_warning(r);
    01897         xd=view.width();
    01898         yd=view.height();
    01899
    01900         xit=view.x_at(d);
    01901         xit=view.x_at(xd,yd);
    01902         xit=view.row_begin(xd);
    01903         xit=view.row_end(xd);
    01904
    01905         yit=view.y_at(d);
    01906         yit=view.y_at(xd,yd);
    01907         yit=view.col_begin(xd);
    01908         yit=view.col_end(xd);
    01909     }
    01910     View view;
    01911 };
    01912
    01913
    01916
    01930 template <typename View>
    01931 struct ImageViewConcept {
    01932     void constraints() {
    01933         gil_function_requires<RandomAccess2DImageViewConcept<View> >();
    01934
    01935         // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
    01936         gil_function_requires<PixelLocatorConcept<typename View::xy_locator> >();
    01937
    01938         BOOST_STATIC_ASSERT((is_same<typename View::x_coord_t, typename View::y_coord_t>::value));
    01939
    01940         typedef typename View::coord_t           coord_t;      // 1D difference type (same for all dimensions)
    01941         std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
    01942     }
    01943     View view;
    01944 };
    01945
    01946
    01947 namespace detail {
    01948     template <typename View>    // Preconditions: View Models RandomAccessNDImageViewConcept
    01949     struct RandomAccessNDImageViewIsMutableConcept {
    01950         void constraints() {
    01951             gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator> >();
    01952
    01953             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator> >();
    01954             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::reverse_iterator> >();
    01955             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::template axis<0>::iterator> >();
    01956             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::template axis<View::num_dimensions-1>::iterator> >();
    01957
    01958             typename View::difference_type diff; initialize_it(diff); ignore_unused_variable_warning(diff);
    01959             typename View::point_t pt;
    01960             typename View::value_type v; initialize_it(v);
    01961
    01962             view[diff]=v;
    01963             view(pt)=v;
    01964         }
    01965         View view;
    01966     };
    01967
    01968     template <typename View>    // preconditions: View Models RandomAccessNDImageViewConcept
    01969     struct RandomAccess2DImageViewIsMutableConcept {
    01970         void constraints() {
    01971             gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
    01972             typename View::x_coord_t xd=0; ignore_unused_variable_warning(xd);
    01973             typename View::y_coord_t yd=0; ignore_unused_variable_warning(yd);
    01974             typename View::value_type v; initialize_it(v);
    01975             view(xd,yd)=v;
    01976         }
    01977         View view;
    01978     };
    01979
    01980     template <typename View>    // preconditions: View Models ImageViewConcept
    01981     struct PixelImageViewIsMutableConcept {
    01982         void constraints() {
    01983             gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
    01984         }
    01985     };
    01986 }
    01987
    01990
    01997 template <typename View>
    01998 struct MutableRandomAccessNDImageViewConcept {
    01999     void constraints() {
    02000         gil_function_requires<RandomAccessNDImageViewConcept<View> >();
    02001         gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
    02002     }
    02003 };
    02004
    02007
    02012 template <typename View>
    02013 struct MutableRandomAccess2DImageViewConcept {
    02014     void constraints() {
    02015         gil_function_requires<RandomAccess2DImageViewConcept<View> >();
    02016         gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
    02017     }
    02018 };
    02019
    02022
    02027 template <typename View>
    02028 struct MutableImageViewConcept {
    02029     void constraints() {
    02030         gil_function_requires<ImageViewConcept<View> >();
    02031         gil_function_requires<detail::PixelImageViewIsMutableConcept<View> >();
    02032     }
    02033 };
    02034
    02038 template <typename V1, typename V2>  // Model ImageViewConcept
    02039 struct views_are_compatible : public pixels_are_compatible<typename V1::value_type, typename V2::value_type> {};
    02040
    02043
    02050 template <typename V1, typename V2>
    02051 struct ViewsCompatibleConcept {
    02052     void constraints() {
    02053         BOOST_STATIC_ASSERT((views_are_compatible<V1,V2>::value));
    02054     }
    02055 };
    02056
    02057
    02063
    02064
    02067
    02088 template <typename Img>
    02089 struct RandomAccessNDImageConcept {
    02090     void constraints() {
    02091         gil_function_requires<Regular<Img> >();
    02092
    02093         typedef typename Img::view_t       view_t;
    02094         gil_function_requires<MutableRandomAccessNDImageViewConcept<view_t> >();
    02095
    02096         typedef typename Img::const_view_t const_view_t;
    02097         typedef typename Img::value_type   pixel_t;
    02098
    02099         typedef typename Img::point_t        point_t;
    02100         gil_function_requires<PointNDConcept<point_t> >();
    02101
    02102         const_view_t cv = const_view(img); ignore_unused_variable_warning(cv);
    02103         view_t       v  = view(img);       ignore_unused_variable_warning(v);
    02104
    02105         pixel_t fill_value;
    02106         point_t pt=img.dimensions();
    02107         Img im1(pt);
    02108         Img im2(pt,1);
    02109         Img im3(pt,fill_value,1);
    02110         img.recreate(pt);
    02111         img.recreate(pt,1);
    02112         img.recreate(pt,fill_value,1);
    02113     }
    02114     Img img;
    02115 };
    02116
    02117
    02120
    02137 template <typename Img>
    02138 struct RandomAccess2DImageConcept {
    02139     void constraints() {
    02140         gil_function_requires<RandomAccessNDImageConcept<Img> >();
    02141         typedef typename Img::x_coord_t  x_coord_t;
    02142         typedef typename Img::y_coord_t  y_coord_t;
    02143         typedef typename Img::value_type value_t;
    02144
    02145         gil_function_requires<MutableRandomAccess2DImageViewConcept<typename Img::view_t> >();
    02146
    02147         x_coord_t w=img.width();
    02148         y_coord_t h=img.height();
    02149         value_t fill_value;
    02150         Img im1(w,h);
    02151         Img im2(w,h,1);
    02152         Img im3(w,h,fill_value,1);
    02153         img.recreate(w,h);
    02154         img.recreate(w,h,1);
    02155         img.recreate(w,h,fill_value,1);
    02156     }
    02157     Img img;
    02158 };
    02159
    02162
    02170 template <typename Img>
    02171 struct ImageConcept {
    02172     void constraints() {
    02173         gil_function_requires<RandomAccess2DImageConcept<Img> >();
    02174         gil_function_requires<MutableImageViewConcept<typename Img::view_t> >();
    02175         typedef typename Img::coord_t        coord_t;
    02176         BOOST_STATIC_ASSERT(num_channels<Img>::value == mpl::size<typename color_space_type<Img>::type>::value);
    02177
    02178         BOOST_STATIC_ASSERT((is_same<coord_t, typename Img::x_coord_t>::value));
    02179         BOOST_STATIC_ASSERT((is_same<coord_t, typename Img::y_coord_t>::value));
    02180     }
    02181     Img img;
    02182 };
    02183
    02184
    02185 } }  // namespace boost::gil
    02186
    02187 #endif