Adobe Systems, Inc.

gil_concept.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2006 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://opensource.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef GIL_CONCEPT_H
00010 #define GIL_CONCEPT_H
00011 
00020 
00021 #include "gil_config.hpp"
00022 #include <boost/type_traits.hpp>
00023 #include <boost/concept_check.hpp>
00024 #include <boost/mpl/and.hpp>
00025 
00026 ADOBE_GIL_NAMESPACE_BEGIN
00027 template <typename T> struct channel_traits;
00028 template <typename PIT> struct pixel_iterator_traits;
00029 template <typename dstT, typename srcT>
00030 typename channel_traits<dstT>::value_type channel_convert(srcT val);
00031 
00032 #ifdef _MSC_VER
00033     #pragma warning(push)
00034     #pragma warning(disable : 4700)     // local variable used without being initialized
00035 #endif
00036 
00037 #ifdef USE_GIL_CONCEPT_CHECK
00038     #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept)
00039     template <typename C> void gil_function_requires() { boost::function_requires<C>(); }
00040 #else
00041     #define GIL_CLASS_REQUIRE(T,NS,C) 
00042     template <typename C> void gil_function_requires() {}
00043 #endif
00044 
00045 
00048 
00055 template <typename T>
00056 struct ValueType {
00057     void constraints() {
00058         gil_function_requires< boost::DefaultConstructibleConcept<T> >();
00059         gil_function_requires< boost::CopyConstructibleConcept<T> >();              
00060         gil_function_requires< boost::EqualityComparableConcept<T> >(); // ==, !=
00061         gil_function_requires< boost::AssignableConcept<T> >();
00062     }
00063 };
00064 
00067 //          POINT CONCEPTS
00070 
00073 
00090 template <typename P>
00091 struct PointNDConcept {
00092     void constraints() {
00093         gil_function_requires< ValueType<P> >();
00094 
00095         typedef typename P::value_type value_type;
00096         static const std::size_t N=P::num_dimensions;
00097         typedef typename P::template axis<0>::coord_t FT;
00098         typedef typename P::template axis<N-1>::coord_t LT;
00099     
00100         value_type v=point[0];  boost::ignore_unused_variable_warning(v);
00101         point[0]=point[0];
00102     }
00103     P point;
00104 };
00105 
00108 
00122 template <typename P>
00123 struct Point2DConcept {
00124     void constraints() {
00125         gil_function_requires< PointNDConcept<P> >();
00126         BOOST_STATIC_ASSERT(P::num_dimensions == 2);
00127         point.x=point.y;
00128     }
00129     P point;
00130 };
00131 
00133 //
00134 //          ITERATOR MUTABILITY CONCEPTS
00135 //
00136 // Taken from boost's concept_check.hpp. Isolating mutability to result in faster compile time 
00137 //
00139 
00140 namespace detail {
00141     template <class TT> // Preconditions: TT Models boost::ForwardIteratorConcept
00142     struct ForwardIteratorIsMutableConcept {
00143         void constraints() {
00144             *i++ = *i;         // require postincrement and assignment
00145         }
00146         TT i;
00147     };
00148 
00149     template <class TT> // Preconditions: TT Models boost::BidirectionalIteratorConcept
00150     struct BidirectionalIteratorIsMutableConcept {
00151         void constraints() {
00152             gil_function_requires< ForwardIteratorIsMutableConcept<TT> >();
00153             *i-- = *i;                  // require postdecrement and assignment
00154         }
00155         TT i;
00156     };
00157 
00158     template <class TT> // Preconditions: TT Models boost::RandomAccessIteratorConcept
00159     struct RandomAccessIteratorIsMutableConcept {
00160         void constraints() {
00161             gil_function_requires< BidirectionalIteratorIsMutableConcept<TT> >();
00162             typename std::iterator_traits<TT>::difference_type n;
00163             i[n] = *i;                  // require element access and assignment
00164         }
00165         TT i;
00166     };
00167 
00168     template <typename C>   // prerequisites: IMG Models boost::RandomAccessContainerConcept
00169     struct RandomAccessContainerIsMutableConcept {
00170         void constraints() {
00171             gil_function_requires<boost::Mutable_RandomAccessContainerConcept<C> >();   // TODO: Fix
00172         }
00173     };
00174 
00175 }   // namespace detail
00176 
00182 
00185 
00194 template <typename CS>
00195 struct ColorSpaceTypeConcept {
00196     void constraints() {
00197         typedef typename CS::base base;
00198         int x=CS::num_channels; boost::ignore_unused_variable_warning(x);
00199     }
00200 };
00201 
00206 
00207 template <typename C1, typename C2>  // Models GIL Pixel
00208 struct color_spaces_are_compatible : public boost::is_same<typename C1::base,typename C2::base> {};
00209 
00212 
00220 template <typename CS1, typename CS2>
00221 struct ColorSpacesCompatibleConcept {
00222     void constraints() {
00223         BOOST_STATIC_ASSERT((color_spaces_are_compatible<CS1,CS2>::value));
00224     }
00225 };
00226 
00232 
00235 
00247 template <typename T>
00248 struct ChannelConcept {
00249     void constraints() {
00250         gil_function_requires< boost::EqualityComparableConcept<T> >(); 
00251         gil_function_requires< boost::LessThanComparableConcept<T> >();
00252         
00253         typedef typename channel_traits<T>::value_type v;
00254         typedef typename channel_traits<T>::reference r;
00255         typedef typename channel_traits<T>::pointer p;
00256         typedef typename channel_traits<T>::const_reference cr;
00257         typedef typename channel_traits<T>::const_pointer cp;
00258     }
00259 
00260      T c;
00261 };
00262 
00263 namespace detail {
00264     // Preconditions: T models ChannelConcept
00265     template <typename T>
00266     struct ChannelIsMutableConcept {
00267         void constraints() {
00268             c=c;
00269         }
00270         T c;
00271     };
00272 }
00273 
00276 
00282 template <typename T>
00283 struct MutableChannelConcept {
00284     void constraints() {
00285         gil_function_requires<ChannelConcept<T> >();
00286         gil_function_requires<detail::ChannelIsMutableConcept<T> >();
00287     }
00288 };
00289 
00292 
00298 template <typename T>
00299 struct ChannelValueConcept {
00300     void constraints() {
00301         gil_function_requires<ChannelConcept<T> >();
00302         gil_function_requires<ValueType<T> >();
00303     }
00304 };
00305 
00308 
00314 template <typename T>
00315 struct MutableChannelValueConcept {
00316     void constraints() {
00317         gil_function_requires<ChannelValueConcept<T> >();
00318         gil_function_requires<detail::ChannelIsMutableConcept<T> >();
00319     }
00320 };
00321 
00326 template <typename T1, typename T2>  // Models GIL Pixel
00327 struct channels_are_compatible 
00328     : public boost::is_same<typename channel_traits<T1>::value_type, typename channel_traits<T2>::value_type> {};
00329 
00332 
00340 template <typename T1, typename T2>
00341 struct ChannelsCompatibleConcept {
00342     void constraints() {
00343         BOOST_STATIC_ASSERT((channels_are_compatible<T1,T2>::value));
00344     }
00345 };
00346 
00351 
00359 template <typename SRC_T, typename DST_T>
00360 struct ChannelConvertibleConcept {
00361     void constraints() {
00362         gil_function_requires<ChannelConcept<SRC_T> >();
00363         gil_function_requires<MutableChannelConcept<DST_T> >();
00364         dst=channel_convert<DST_T,SRC_T>(src);
00365     }
00366     SRC_T src;
00367     DST_T dst;
00368 };
00369 
00375 
00378 
00402 template <typename P>
00403 struct HeterogeneousPixelConcept {
00404     void constraints() {
00405         typedef typename P::color_space_t CS;
00406         gil_function_requires<ColorSpaceTypeConcept<CS> >();
00407 
00408         typedef typename P::template kth_channel_t<0>::type T0;
00409         typedef typename P::template kth_channel_t<CS::num_channels-1>::type TN; 
00410 
00411         gil_function_requires< boost::EqualityComparableConcept<P> >(); // ==, !=
00412 
00413 
00414         pixel.template semantic_channel<0>();      // TODO: Call the other accessors
00415         pixel.template semantic_channel<CS::num_channels-1>();
00416         pixel.template channel<0>();
00417 
00418         // functions that work for every pixel (no need to require them)
00419         // max_channel(p), min_channel(p), fill_channels(p,value), and all variations of for_each_channel() and transform_channels()
00420     }
00421 
00422     P pixel;
00423 };
00424 
00425 namespace detail {
00426     template <typename P>   // Preconditions: P Models HeterogeneousPixelConcept
00427     struct HeterogeneousPixelIsMutableConcept {
00428         void constraints() {
00429             pixel=pixel;
00430             pixel.template semantic_channel<0>()=pixel.template semantic_channel<0>();
00431             pixel.template semantic_channel<P::color_space_t::num_channels-1>()=pixel.template semantic_channel<0>();
00432             pixel.template channel<0>()=pixel.template channel<0>();
00433         }
00434         P pixel;
00435     };
00436 }
00437 
00440 
00453 template <typename P>
00454 struct MutableHeterogeneousPixelConcept {
00455     void constraints() {
00456         gil_function_requires< HeterogeneousPixelConcept<P> >();
00457         gil_function_requires< detail::HeterogeneousPixelIsMutableConcept<P> >();
00458     }
00459 };
00460 
00461 
00462 
00465 
00477 template <typename P>
00478 struct HeterogeneousPixelValueConcept {
00479     void constraints() {
00480         gil_function_requires< HeterogeneousPixelConcept<P> >();
00481         gil_function_requires< ValueType<P> >();
00482     }
00483 };
00484 
00487 
00494 template <typename P>
00495 struct MutableHeterogeneousPixelValueConcept {
00496     void constraints() {
00497         gil_function_requires< HeterogeneousPixelValueConcept<P> >();
00498         gil_function_requires< detail::HeterogeneousPixelIsMutableConcept<P> >();
00499     }
00500 };
00501 
00502 
00503 
00506 
00519 template <typename P>
00520 struct PixelConcept {
00521     void constraints() {
00522         gil_function_requires<HeterogeneousPixelConcept<P> >();
00523 
00524         typedef typename P::channel_t T;
00525         typedef typename P::channel_reference TR;
00526         typedef typename P::channel_const_reference CTR;
00527         gil_function_requires<ChannelValueConcept<T> >();
00528 
00529         pixel[0];
00530 
00531         // functions that work for every pixel (no need to require them)
00532         // max_channel(p), min_channel(p), fill_channels(p,value), and all variations of for_each_channel() and transform_channels()
00533     }
00534 
00535     P pixel;
00536 };
00537 
00538 namespace detail {
00539     template <typename P>   // Preconditions: P Models PixelConcept
00540     struct PixelIsMutableConcept {
00541         void constraints() {
00542             gil_function_requires< detail::HeterogeneousPixelIsMutableConcept<P> >();
00543             pixel[0]=pixel[0];
00544         }
00545         P pixel;
00546     };
00547 }
00548 
00551 
00559 template <typename P>
00560 struct MutablePixelConcept {
00561     void constraints() {
00562         gil_function_requires< PixelConcept<P> >();
00563         gil_function_requires< detail::PixelIsMutableConcept<P> >();
00564     }
00565 };
00566 
00569 
00575 template <typename P>
00576 struct PixelValueConcept {
00577     void constraints() {
00578         gil_function_requires< PixelConcept<P> >();
00579         gil_function_requires< ValueType<P> >();
00580     }
00581 };
00582 
00585 
00591 template <typename P>
00592 struct MutablePixelValueConcept {
00593     void constraints() {
00594         gil_function_requires< PixelValueConcept<P> >();
00595         gil_function_requires< detail::PixelIsMutableConcept<P> >();
00596     }
00597 };
00598 
00603 template <typename P1, typename P2>  // Models GIL Pixel
00604 struct pixels_are_compatible 
00605     : public boost::mpl::and_<color_spaces_are_compatible<typename P1::color_space_t, typename P2::color_space_t>, 
00606                               channels_are_compatible    <typename P1::channel_t,    typename P2::channel_t     > >{};
00607 
00610 
00620 template <typename P1, typename P2>
00621 struct PixelsCompatibleConcept {
00622     void constraints() {
00623         BOOST_STATIC_ASSERT((pixels_are_compatible<P1,P2>::value));
00624     }
00625 };
00626 
00631 
00639 template <typename SRC_P, typename DST_P>
00640 struct PixelConvertibleConcept {
00641     void constraints() {
00642         gil_function_requires<PixelConcept<SRC_P> >();
00643         gil_function_requires<MutablePixelConcept<DST_P> >();
00644         gil_function_requires<ChannelConvertibleConcept<typename SRC_P::channel_t, typename DST_P::channel_t> >();
00645         color_convert(src,dst);
00646     }
00647     SRC_P src;
00648     DST_P dst;
00649 };
00650 
00656 
00661 
00677 template <typename IT>
00678 struct PixelIteratorConcept {   
00679     void constraints() {
00680         gil_function_requires<boost::RandomAccessIteratorConcept<IT> >();
00681         
00682         typedef typename std::iterator_traits<IT>::value_type value_type;
00683         gil_function_requires<PixelValueConcept<value_type> >();
00684 
00685         typedef typename pixel_iterator_traits<IT>::const_reference const_reference;
00686  //       gil_function_requires<PixelConcept<const_reference> >();
00687 
00688         typedef typename pixel_iterator_traits<IT>::channel_t channel_t;
00689         gil_function_requires<ChannelValueConcept<channel_t> >();
00690 
00691         typedef typename pixel_iterator_traits<IT>::color_space_t color_space_t;
00692         gil_function_requires<ColorSpaceTypeConcept<color_space_t> >();
00693 
00694         // We want to make sure DST Models StepIterator and ConstPixelIterator and CNT Models ConstPixelIterator, but wouldn't that cause infinite loop?
00695         typedef typename pixel_iterator_traits<IT>::dynamic_step_t dynamic_step_t;
00696         typedef typename pixel_iterator_traits<IT>::const_t const_t;
00697 
00698         const_t const_it(it);   // immutable iterator must be constructible from (possibly mutable) iterator
00699 
00700         static const bool ib=pixel_iterator_traits<IT>::is_base; boost::ignore_unused_variable_warning(ib);
00701         static const bool ip=pixel_iterator_traits<IT>::is_planar; boost::ignore_unused_variable_warning(ip);
00702         static const bool pdi=pixel_iterator_traits<IT>::pixel_data_is_real; boost::ignore_unused_variable_warning(pdi);
00703 
00704         // when is_base is false, it must also have typename std::iterator_traits<IT>::base_t defined
00705     }
00706 
00707     IT it;
00708 };
00709 
00710 namespace detail {
00711     template <typename IT>  // Preconditions: IT Models PixelIteratorConcept
00712     struct PixelIteratorIsMutableConcept {
00713         void constraints() {
00714             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<IT> >();
00715             gil_function_requires<detail::ChannelIsMutableConcept<typename pixel_iterator_traits<IT>::channel_t> >();
00716         }
00717     };
00718 }
00719 
00722 
00729 template <typename IT>
00730 struct MutablePixelIteratorConcept {
00731     void constraints() {
00732         gil_function_requires<PixelIteratorConcept<IT> >();
00733         gil_function_requires<detail::PixelIteratorIsMutableConcept<IT> >();
00734     }
00735 };
00736 
00737 namespace detail {
00738     // Iterators that can be used as the base of pixel_step_iterator require some additional functions
00739     template <typename IT>  // Preconditions: IT Models boost::RandomAccessIteratorConcept
00740     struct RandomAccessIteratorIsByteAdvancableConcept {
00741         void constraints() {
00742             std::ptrdiff_t bs=byte_step(it);  boost::ignore_unused_variable_warning(bs);
00743             it=byte_advanced(it,3);
00744             std::ptrdiff_t bd=byte_distance(it,it);  boost::ignore_unused_variable_warning(bd);
00745             byte_advance(it,3);
00746             // for performace you may also provide a customized implementation of byte_advanced_ref
00747         }
00748         IT it;
00749     };
00750 }
00751 
00754 
00766 template <typename IT>
00767 struct ByteAdvancableIteratorConcept {
00768     void constraints() {
00769         gil_function_requires<boost::RandomAccessIteratorConcept<IT> >();
00770         gil_function_requires<detail::RandomAccessIteratorIsByteAdvancableConcept<IT> >();
00771     }
00772 };
00773 
00774 
00781 
00792 template <typename IT>
00793 struct IteratorAdaptorConcept {
00794     void constraints() {
00795         gil_function_requires<boost::ForwardIteratorConcept<IT> >();
00796 
00797         typedef typename pixel_iterator_traits<IT>::base_t base_t;
00798         gil_function_requires<boost::ForwardIteratorConcept<base_t> >();
00799 
00800         BOOST_STATIC_ASSERT(!pixel_iterator_traits<IT>::is_base);
00801 
00802         base_t base=it.base();  boost::ignore_unused_variable_warning(base);
00803     }
00804     IT it;
00805 };
00806 
00811 
00819 template <typename IT>
00820 struct StepIteratorConcept {
00821     void constraints() {
00822         gil_function_requires<boost::ForwardIteratorConcept<IT> >();
00823         it.set_step(0);
00824     }
00825     IT it;
00826 };
00827 
00834 
00844 template <typename IT> struct PixelIteratorAdaptorConcept;
00845 template <typename IT>
00846 struct PixelStepIteratorConcept {
00847     void constraints() {
00848         gil_function_requires<StepIteratorConcept<IT> >();
00849 
00850         // In addition must be an iterator adaptor over pixels
00851         gil_function_requires<PixelIteratorAdaptorConcept<IT> >();
00852         
00853         // Must be byte advanceable
00854         gil_function_requires<detail::RandomAccessIteratorIsByteAdvancableConcept<IT> >();
00855         
00856         // Must be constructible from the base iterator and byte step
00857         typedef typename pixel_iterator_traits<IT>::base_t base_t;
00858         IT(base_t(), std::ptrdiff_t());
00859     }
00860 };
00861 
00864 
00870 template <typename IT>
00871 struct PixelIteratorAdaptorConcept {
00872     void constraints() {
00873         gil_function_requires<IteratorAdaptorConcept<IT> >();
00874         gil_function_requires<PixelIteratorConcept<IT> >();
00875     }
00876 };
00877 
00880 
00886 template <typename IT>
00887 struct MutableIteratorAdaptorConcept {
00888     void constraints() {
00889         gil_function_requires<IteratorAdaptorConcept<IT> >();
00890         gil_function_requires<detail::ForwardIteratorIsMutableConcept<IT> >();
00891     }
00892 };
00893 
00896 
00902 template <typename IT>
00903 struct MutablePixelIteratorAdaptorConcept {
00904     void constraints() {
00905         gil_function_requires<PixelIteratorAdaptorConcept<IT> >();
00906         gil_function_requires<detail::PixelIteratorIsMutableConcept<IT> >();
00907     }
00908 };
00909 
00913 
00919 template <typename IT>
00920 struct MutableStepIteratorConcept {
00921     void constraints() {
00922         gil_function_requires<StepIteratorConcept<IT> >();
00923         gil_function_requires<detail::ForwardIteratorIsMutableConcept<IT> >();
00924     }
00925 };
00926 
00930 
00938 template <typename IT>
00939 struct MutablePixelStepIteratorConcept {
00940     void constraints() {
00941         gil_function_requires<PixelStepIteratorConcept<IT> >();
00942         gil_function_requires<detail::PixelIteratorIsMutableConcept<IT> >();
00943     }
00944 };
00945 
00950 
00963 template <typename IT>
00964 struct PixelImageIteratorConcept {
00965     void constraints() {
00966         gil_function_requires<PixelIteratorConcept<IT> >();
00967         it.width();
00968         it.x_pos();
00969         bool is_contig=it.is_contiguous();
00970         typedef typename IT::x_iterator x_iterator;
00971         x_iterator xit = it.x();
00972     }
00973     IT it;
00974 };
00975 
00979 
00985 template <typename IT>
00986 struct MutablePixelImageIteratorConcept {
00987     void constraints() {
00988         gil_function_requires<PixelImageIteratorConcept<IT> >();
00989         gil_function_requires<detail::PixelIteratorIsMutableConcept<IT> >();
00990     }
00991 };
00992 
00998 
01001 
01042 template <typename LOC>
01043 struct RandomAccessNDLocatorConcept {
01044     void constraints() {
01045         gil_function_requires< ValueType<LOC> >();
01046 
01047         typedef typename LOC::value_type        value_type;
01048         typedef typename LOC::reference         reference;          // result of dereferencing
01049         typedef typename LOC::difference_type   difference_type;    // result of operator-(pixel_locator, pixel_locator)
01050         typedef typename LOC::cached_location_t cached_location_t;  // type used to store relative location (to allow for more efficient repeated access)
01051         typedef typename LOC::const_t           const_t;         // same as this type, but over const values
01052         typedef typename LOC::domain_t          domain_t;        // same as value_type
01053         typedef typename LOC::point_t           point_t;         // same as difference_type
01054         static const std::size_t N=LOC::num_dimensions;
01055     
01056         typedef typename LOC::template axis<0>::iterator    first_it_type;
01057         typedef typename LOC::template axis<N-1>::iterator  last_it_type;
01058         gil_function_requires<boost::RandomAccessIteratorConcept<first_it_type> >();
01059         gil_function_requires<boost::RandomAccessIteratorConcept<last_it_type> >();
01060 
01061         // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
01062         gil_function_requires<PointNDConcept<point_t> >();
01063         BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
01064         BOOST_STATIC_ASSERT((boost::is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
01065         BOOST_STATIC_ASSERT((boost::is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
01066 
01067         difference_type d;
01068         loc+=d;
01069         loc-=d;
01070         loc=loc+d;
01071         loc=loc-d;
01072         reference r1=loc[d];  boost::ignore_unused_variable_warning(r1);
01073         reference r2=*loc;  boost::ignore_unused_variable_warning(r2);
01074         cached_location_t cl=loc.cache_location(d);  boost::ignore_unused_variable_warning(cl);
01075         reference r3=loc[d];  boost::ignore_unused_variable_warning(r3);
01076 
01077         first_it_type fi=loc.template axis_iterator<0>();
01078         fi=loc.template axis_iterator<0>(d);
01079         last_it_type li=loc.template axis_iterator<N-1>();
01080         li=loc.template axis_iterator<N-1>(d);
01081     }
01082     LOC loc;
01083 };
01084 
01087 
01117 template <typename LOC>
01118 struct RandomAccess2DLocatorConcept {
01119     void constraints() {
01120         gil_function_requires<RandomAccessNDLocatorConcept<LOC> >();
01121         BOOST_STATIC_ASSERT(LOC::num_dimensions==2);
01122 
01123         typedef typename LOC::cached_location_t   cached_location_t;
01124         gil_function_requires<Point2DConcept<typename LOC::point_t> >();
01125 
01126         typedef typename LOC::x_iterator x_iterator;
01127         typedef typename LOC::y_iterator y_iterator;
01128         typedef typename LOC::x_coord_t  x_coord_t;
01129         typedef typename LOC::y_coord_t  y_coord_t;
01130 
01131         x_coord_t xd;
01132         y_coord_t yd;
01133         typename LOC::difference_type d;
01134         typename LOC::reference r=loc(xd,yd);  boost::ignore_unused_variable_warning(r);
01135 
01136         loc=loc.xy_at(d);
01137         loc=loc.xy_at(xd,yd);
01138 
01139         x_iterator xit=loc.x_at(d);
01140         xit=loc.x_at(xd,yd);
01141         xit=loc.x();
01142 
01143         y_iterator yit=loc.y_at(d);
01144         yit=loc.y_at(xd,yd);
01145         yit=loc.y();
01146 
01147         cached_location_t cl=loc.cache_location(xd,yd);
01148     }
01149     LOC loc;
01150 };
01151 
01154 
01176 template <typename LOC>
01177 struct PixelLocatorConcept {
01178     void constraints() {
01179         gil_function_requires< RandomAccess2DLocatorConcept<LOC> >();
01180         gil_function_requires< PixelIteratorConcept<typename LOC::x_iterator> >();
01181         gil_function_requires< PixelIteratorConcept<typename LOC::y_iterator> >();
01182         typedef typename LOC::dynamic_step_t dynamic_step_t;
01183         typedef typename LOC::channel_t      channel_t;
01184         typedef typename LOC::color_space_t  color_space_t;
01185         typedef typename LOC::coord_t        coord_t;
01186         typedef typename LOC::pixel_t        pixel_t;
01187         BOOST_STATIC_ASSERT((boost::is_same<typename LOC::x_coord_t, typename LOC::y_coord_t>::value));
01188         BOOST_STATIC_ASSERT(LOC::num_channels == color_space_t::num_channels);
01189 
01190         typename LOC::x_iterator xit;
01191         std::ptrdiff_t row_bytes;
01192         LOC lc(xit, row_bytes);
01193 
01194         std::ptrdiff_t r=loc.row_bytes();
01195         r=loc.pix_bytestep();
01196     }
01197     LOC loc;
01198 };
01199 
01200 namespace detail {
01201     template <typename LOC> // preconditions: LOC Models RandomAccessNDLocatorConcept
01202     struct RandomAccessNDLocatorIsMutableConcept {
01203         void constraints() {
01204             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename LOC::template axis<0>::iterator> >();
01205             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename LOC::template axis<LOC::num_dimensions-1>::iterator> >();
01206 
01207             typename LOC::difference_type d;
01208             typename LOC::value_type v;
01209             typename LOC::cached_location_t cl=loc.cache_location(d);
01210             *loc=v;
01211             loc[d]=v;
01212             loc[cl]=v;
01213         }
01214         LOC loc;
01215     };
01216 
01217     template <typename LOC> // preconditions: LOC Models RandomAccess2DLocatorConcept
01218     struct RandomAccess2DLocatorIsMutableConcept {
01219         void constraints() {
01220             gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<LOC> >();
01221             typename LOC::x_coord_t xd;
01222             typename LOC::y_coord_t yd;
01223             typename LOC::value_type v;
01224             loc(xd,yd)=v;
01225         }
01226         LOC loc;
01227     };
01228 }
01229 
01232 
01240 template <typename LOC>
01241 struct MutableRandomAccessNDLocatorConcept {
01242     void constraints() {
01243         gil_function_requires<RandomAccessNDLocatorConcept<LOC> >();
01244         gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<LOC> >();
01245     }
01246 };
01247 
01250 
01256 template <typename LOC>
01257 struct MutableRandomAccess2DLocatorConcept {
01258     void constraints() {
01259         gil_function_requires< RandomAccess2DLocatorConcept<LOC> >();
01260         gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<LOC> >();
01261     }
01262 };
01263 
01266 
01272 template <typename LOC>
01273 struct MutablePixelLocatorConcept {
01274     void constraints() {
01275         gil_function_requires<PixelLocatorConcept<LOC> >();
01276         gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<LOC> >();
01277     }
01278 };
01279 
01285 
01288 
01334 template <typename VIEW>
01335 struct RandomAccessNDImageViewConcept {
01336     void constraints() {
01337         gil_function_requires< ValueType<VIEW> >();
01338 
01339         typedef typename VIEW::value_type       value_type;
01340         typedef typename VIEW::reference        reference;       // result of dereferencing
01341         typedef typename VIEW::difference_type  difference_type; // result of operator-(1d_iterator,1d_iterator)
01342         typedef typename VIEW::const_t          const_t;         // same as this type, but over const values
01343         typedef typename VIEW::domain_t         domain_t;        // same as value_type
01344         typedef typename VIEW::point_t          point_t;         // N-dimensional point
01345         typedef typename VIEW::locator          locator;         // N-dimensional locator
01346         typedef typename VIEW::iterator         iterator;
01347         typedef typename VIEW::reverse_iterator reverse_iterator;
01348         typedef typename VIEW::size_type        size_type;
01349         static const std::size_t N=VIEW::num_dimensions;
01350     
01351         gil_function_requires<RandomAccessNDLocatorConcept<locator> >();
01352         gil_function_requires<boost::RandomAccessIteratorConcept<iterator> >();
01353         gil_function_requires<boost::RandomAccessIteratorConcept<reverse_iterator> >();
01354 
01355         typedef typename VIEW::template axis<0>::iterator   first_it_type;
01356         typedef typename VIEW::template axis<N-1>::iterator last_it_type;
01357         gil_function_requires<boost::RandomAccessIteratorConcept<first_it_type> >();
01358         gil_function_requires<boost::RandomAccessIteratorConcept<last_it_type> >();
01359 
01360 //        BOOST_STATIC_ASSERT((typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
01361 //        BOOST_STATIC_ASSERT((typename std::iterator_traits< last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
01362 
01363         // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
01364         gil_function_requires<PointNDConcept<point_t> >();
01365         BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
01366         BOOST_STATIC_ASSERT((boost::is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
01367         BOOST_STATIC_ASSERT((boost::is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
01368 
01369         point_t p;
01370         locator lc;
01371         iterator it;
01372         reverse_iterator rit;
01373         difference_type d;
01374 
01375         VIEW(p,lc); // view must be constructible from a locator and a point
01376 
01377         p=view.dimensions();
01378         lc=view.pixels();
01379         size_type sz=view.size();  boost::ignore_unused_variable_warning(sz);
01380 
01381         it=view.begin();
01382         it=view.end();
01383         rit=view.rbegin();
01384         rit=view.rend();
01385 
01386         reference r1=view[d]; boost::ignore_unused_variable_warning(r1);    // 1D access 
01387         reference r2=view(p); boost::ignore_unused_variable_warning(r2);    // 2D access
01388 
01389         // get 1-D iterator of any dimension at a given pixel location
01390         first_it_type fi=view.template axis_iterator<0>(p); boost::ignore_unused_variable_warning(fi);
01391         last_it_type li=view.template axis_iterator<N-1>(p);
01392     }
01393     VIEW view;
01394 };
01395 
01398 
01436 template <typename VIEW>
01437 struct RandomAccess2DImageViewConcept {
01438     void constraints() {
01439         gil_function_requires<RandomAccessNDImageViewConcept<VIEW> >();
01440         BOOST_STATIC_ASSERT(VIEW::num_dimensions==2);
01441 
01442         // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
01443         gil_function_requires<RandomAccess2DLocatorConcept<typename VIEW::locator> >();
01444 
01445         typedef typename VIEW::x_iterator x_iterator;
01446         typedef typename VIEW::y_iterator y_iterator;
01447         typedef typename VIEW::x_coord_t  x_coord_t;
01448         typedef typename VIEW::y_coord_t  y_coord_t;
01449         typedef typename VIEW::xy_locator xy_locator;
01450 
01451         x_coord_t xd;
01452         y_coord_t yd;
01453         x_iterator xit;
01454         y_iterator yit;
01455         typename VIEW::point_t d;
01456 
01457         VIEW(xd,yd,xy_locator());       // constructible with width, height, 2d_locator
01458 
01459         xy_locator lc=view.xy_at(xd,yd);
01460         lc=view.xy_at(d);
01461 
01462         typename VIEW::reference r=view(xd,yd);  boost::ignore_unused_variable_warning(r);
01463         xd=view.width();
01464         yd=view.height();
01465 
01466         xit=view.x_at(d);
01467         xit=view.x_at(xd,yd);
01468         xit=view.row_begin(xd);
01469         xit=view.row_end(xd);
01470 
01471         yit=view.y_at(d);
01472         yit=view.y_at(xd,yd);
01473         yit=view.col_begin(xd);
01474         yit=view.col_end(xd);
01475     }
01476     VIEW view;
01477 };
01478 
01479 
01482 
01508 template <typename VIEW>
01509 struct ImageViewConcept {
01510     void constraints() {
01511         gil_function_requires<RandomAccess2DImageViewConcept<VIEW> >();
01512 
01513         // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
01514         gil_function_requires<PixelLocatorConcept<typename VIEW::xy_locator> >();
01515         
01516         BOOST_STATIC_ASSERT((boost::is_same<typename VIEW::x_coord_t, typename VIEW::y_coord_t>::value));
01517 
01518         typedef typename VIEW::coord_t           coord_t;      // 1D difference type (same for all dimensions)
01519         typedef typename VIEW::dynamic_step_t    dynamic_step_t;
01520         typedef typename VIEW::channel_t         channel_t;
01521         typedef typename VIEW::color_space_t     color_space_t;
01522         typedef typename VIEW::pixel_t           pixel_t;
01523 
01524         BOOST_STATIC_ASSERT(VIEW::num_channels == color_space_t::num_channels);
01525 
01526         typename VIEW::x_iterator xit;
01527         typename VIEW::difference_type diff;
01528         typename VIEW::point_t pt;
01529         VIEW(pt,         xit, diff);
01530         VIEW(pt.x, pt.y, xit, diff);
01531 
01532         diff=view.row_bytes();
01533         diff=view.pix_bytestep();
01534 
01535     }
01536     VIEW view;
01537 };
01538 
01539 
01540 namespace detail {
01541     template <typename VIEW>    // Preconditions: VIEW Models RandomAccessNDImageViewConcept
01542     struct RandomAccessNDImageViewIsMutableConcept {
01543         void constraints() {
01544             gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename VIEW::locator> >();
01545 
01546             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename VIEW::iterator> >();
01547             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename VIEW::reverse_iterator> >();
01548             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename VIEW::template axis<0>::iterator> >();
01549             gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename VIEW::template axis<VIEW::num_dimensions-1>::iterator> >();
01550 
01551             typename VIEW::difference_type diff;
01552             typename VIEW::point_t pt;
01553             typename VIEW::value_type v;
01554 
01555             view[diff]=v;
01556             view(pt)=v;
01557         }
01558         VIEW view;
01559     };
01560 
01561     template <typename VIEW>    // preconditions: VIEW Models RandomAccessNDImageViewConcept
01562     struct RandomAccess2DImageViewIsMutableConcept {
01563         void constraints() {        
01564             gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<VIEW> >();
01565             typename VIEW::x_coord_t xd;
01566             typename VIEW::y_coord_t yd;
01567             typename VIEW::value_type v;
01568             view(xd,yd)=v;
01569         }
01570         VIEW view;
01571     };
01572 
01573     template <typename VIEW>    // preconditions: VIEW Models ImageViewConcept
01574     struct PixelImageViewIsMutableConcept {
01575         void constraints() {        
01576             gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<VIEW> >();
01577         }
01578     };
01579 }
01580 
01583 
01591 template <typename VIEW>
01592 struct MutableRandomAccessNDImageViewConcept {
01593     void constraints() {
01594         gil_function_requires<RandomAccessNDImageViewConcept<VIEW> >();
01595         gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<VIEW> >();
01596     }
01597 };
01598 
01601 
01607 template <typename VIEW>
01608 struct MutableRandomAccess2DImageViewConcept {
01609     void constraints() {
01610         gil_function_requires<RandomAccess2DImageViewConcept<VIEW> >();
01611         gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<VIEW> >();
01612     }
01613 };
01614 
01617 
01623 template <typename VIEW>
01624 struct MutableImageViewConcept {
01625     void constraints() {
01626         gil_function_requires<ImageViewConcept<VIEW> >();
01627         gil_function_requires<detail::PixelImageViewIsMutableConcept<VIEW> >();
01628     }
01629 };
01630 
01635 template <typename V1, typename V2>  // Model ImageViewConcept
01636 struct views_are_compatible : public pixels_are_compatible<typename V1::pixel_t, typename V2::pixel_t> {};
01637 
01640 
01649 template <typename V1, typename V2>
01650 struct ViewsCompatibleConcept {
01651     void constraints() {
01652         BOOST_STATIC_ASSERT((views_are_compatible<V1,V2>::value));
01653     }
01654 };
01655 
01656 
01662 
01663 
01666 
01684 template <typename IMG>
01685 struct RandomAccessNDImageConcept {
01686     void constraints() {
01687         gil_function_requires<boost::RandomAccessContainerConcept<IMG> >();
01688         gil_function_requires<boost::DefaultConstructibleConcept<IMG> >();
01689 
01690         typedef typename IMG::view_t       view_t;
01691         typedef typename IMG::const_view_t const_view_t;
01692         gil_function_requires<MutableRandomAccessNDImageViewConcept<view_t> >();
01693         const_view_t cv=const_view(img);
01694 
01695         typedef typename IMG::point_t        point_t;
01696         gil_function_requires<PointNDConcept<point_t> >();
01697         point_t pt=img.dimensions();
01698         IMG(pt,1);      // construct with dimensions and alignment
01699     }
01700     IMG img;
01701 };
01702 
01703 
01706 
01722 template <typename IMG>
01723 struct RandomAccess2DImageConcept {
01724     void constraints() {
01725         gil_function_requires<RandomAccessNDImageConcept<IMG> >();
01726         typedef typename IMG::x_coord_t      x_coord_t;
01727         typedef typename IMG::y_coord_t      y_coord_t;
01728 
01729         x_coord_t w=img.width();
01730         y_coord_t h=img.height();
01731         IMG(w,h,1);     // construct with width, height and alignment
01732     }
01733     IMG img;
01734 };
01735 
01738 
01747 template <typename IMG>
01748 struct ImageConcept {
01749     void constraints() {
01750         gil_function_requires<RandomAccess2DImageConcept<IMG> >();
01751         gil_function_requires<MutableImageViewConcept<typename IMG::view_t> >();
01752         typedef typename IMG::coord_t        coord_t;
01753         BOOST_STATIC_ASSERT(IMG::num_channels == IMG::color_space_t::num_channels);
01754 
01755         BOOST_STATIC_ASSERT((boost::is_same<coord_t, typename IMG::x_coord_t>::value));
01756         BOOST_STATIC_ASSERT((boost::is_same<coord_t, typename IMG::y_coord_t>::value));
01757     }
01758     IMG img;
01759 };
01760 
01761 
01762 
01763 #ifdef _MSC_VER
01764     #pragma warning(pop)
01765 #endif
01766 
01767 ADOBE_GIL_NAMESPACE_END
01768 
01769 #endif

Copyright © 2006 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google