| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206 |
- /*
- Copyright 2005-2007 Adobe Systems Incorporated
-
- Use, modification and distribution are subject to the Boost Software License,
- Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- http://www.boost.org/LICENSE_1_0.txt).
- See http://opensource.adobe.com/gil for most recent version including documentation.
- */
- /*************************************************************************************************/
- #ifndef GIL_CONCEPT_H
- #define GIL_CONCEPT_H
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \file
- /// \brief Concept check classes for GIL concepts
- /// \author Lubomir Bourdev and Hailin Jin \n
- /// Adobe Systems Incorporated
- /// \date 2005-2007 \n Last updated on February 12, 2007
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- #include <functional>
- #include "gil_config.hpp"
- #include <boost/type_traits.hpp>
- #include <boost/utility/enable_if.hpp>
- #include <boost/concept_check.hpp>
- #include <boost/iterator/iterator_concepts.hpp>
- #include <boost/mpl/and.hpp>
- #include <boost/mpl/size.hpp>
- namespace boost { namespace gil {
- #if defined(__GNUC__) && (__GNUC__ >= 4)
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
- #endif
- #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
- #pragma warning(push)
- #pragma warning(disable:4510) //default constructor could not be generated
- #pragma warning(disable:4512) //assignment operator could not be generated
- #pragma warning(disable:4610) //can never be instantiated - user defined constructor required
- #endif
- template <typename T> struct channel_traits;
- template <typename P> struct is_pixel;
- template <typename dstT, typename srcT>
- typename channel_traits<dstT>::value_type channel_convert(const srcT& val);
- template <typename T> class point2;
- template <std::size_t K, typename T> const T& axis_value(const point2<T>& p);
- template <std::size_t K, typename T> T& axis_value( point2<T>& p);
- template <typename ColorBase, int K> struct kth_element_type;
- template <typename ColorBase, int K> struct kth_element_reference_type;
- template <typename ColorBase, int K> struct kth_element_const_reference_type;
- template <typename ColorBase, int K> struct kth_semantic_element_reference_type;
- template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type;
- template <typename ColorBase> struct size;
- template <typename ColorBase> struct element_type;
- template <typename T> struct channel_type;
- template <typename T> struct color_space_type;
- template <typename T> struct channel_mapping_type;
- template <typename T> struct is_planar;
- template <typename T> struct num_channels;
- template <typename It> struct const_iterator_type;
- template <typename It> struct iterator_is_mutable;
- template <typename It> struct is_iterator_adaptor;
- template <typename It, typename NewBaseIt> struct iterator_adaptor_rebind;
- template <typename It> struct iterator_adaptor_get_base;
- // forward-declare at_c
- namespace detail { template <typename Element, typename Layout, int K> struct homogeneous_color_base; }
- template <int K, typename E, typename L, int N>
- typename add_reference<E>::type at_c( detail::homogeneous_color_base<E,L,N>& p);
- template <int K, typename E, typename L, int N>
- typename add_reference<typename add_const<E>::type>::type at_c(const detail::homogeneous_color_base<E,L,N>& p);
- template <typename P, typename C, typename L> struct packed_pixel;
- template <int K, typename P, typename C, typename L>
- typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type
- at_c(packed_pixel<P,C,L>& p);
- template <int K, typename P, typename C, typename L>
- typename kth_element_const_reference_type<packed_pixel<P,C,L>,K>::type
- at_c(const packed_pixel<P,C,L>& p);
- template <typename B, typename C, typename L, bool M> struct bit_aligned_pixel_reference;
- template <int K, typename B, typename C, typename L, bool M> inline
- typename kth_element_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>::type
- at_c(const bit_aligned_pixel_reference<B,C,L,M>& p);
- // Forward-declare semantic_at_c
- template <int K, typename ColorBase>
- typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
- template <int K, typename ColorBase>
- typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
- template <typename T> struct dynamic_x_step_type;
- template <typename T> struct dynamic_y_step_type;
- template <typename T> struct transposed_type;
- namespace detail {
- template <typename T>
- void initialize_it(T&) {}
- } // namespace detail
- template <typename T>
- struct remove_const_and_reference : public remove_const<typename remove_reference<T>::type> {};
- #ifdef BOOST_GIL_USE_CONCEPT_CHECK
- #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept);
- template <typename C> void gil_function_requires() { function_requires<C>(); }
- #else
- #define GIL_CLASS_REQUIRE(T,NS,C)
- template <typename C> void gil_function_requires() {}
- #endif
- /// \ingroup BasicConcepts
- /**
- \code
- auto concept DefaultConstructible<typename T> {
- T::T();
- };
- \endcode
- */
- template <typename T>
- struct DefaultConstructible {
- void constraints() {
- function_requires<boost::DefaultConstructibleConcept<T> >();
- }
- };
- /// \ingroup BasicConcepts
- /**
- \codeauto concept CopyConstructible<typename T> {
- T::T(T);
- T::~T();
- };
- \endcode
- */
- template <typename T>
- struct CopyConstructible {
- void constraints() {
- function_requires<boost::CopyConstructibleConcept<T> >();
- }
- };
- /// \ingroup BasicConcepts
- /**
- \code
- auto concept Assignable<typename T, typename U = T> {
- typename result_type;
- result_type operator=(T&, U);
- };
- \endcode
- */
- template <typename T>
- struct Assignable {
- void constraints() {
- function_requires<boost::AssignableConcept<T> >();
- }
- };
- /// \ingroup BasicConcepts
- /**
- \code
- auto concept EqualityComparable<typename T, typename U = T> {
- bool operator==(T x, T y);
- bool operator!=(T x, T y) { return !(x==y); }
- };
- \endcode
- */
- template <typename T>
- struct EqualityComparable {
- void constraints() {
- function_requires<boost::EqualityComparableConcept<T> >();
- }
- };
- /// \ingroup BasicConcepts
- /**
- \code
- concept SameType<typename T, typename U>;// unspecified
- \endcode
- */
- template <typename T, typename U>
- struct SameType {
- void constraints() {
- BOOST_STATIC_ASSERT((boost::is_same<T,U>::value_core));
- }
- };
- /// \ingroup BasicConcepts
- /**
- \code
- auto concept Swappable<typename T> {
- void swap(T&,T&);
- };
- \endcode
- */
- template <typename T>
- struct Swappable {
- void constraints() {
- using std::swap;
- swap(x,y);
- }
- T x,y;
- };
- /// \ingroup BasicConcepts
- /**
- \code
- auto concept Regular<typename T> : DefaultConstructible<T>, CopyConstructible<T>, EqualityComparable<T>,
- Assignable<T>, Swappable<T> {};
- \endcode
- */
- template <typename T>
- struct Regular {
- void constraints() {
- gil_function_requires< boost::DefaultConstructibleConcept<T> >();
- gil_function_requires< boost::CopyConstructibleConcept<T> >();
- gil_function_requires< boost::EqualityComparableConcept<T> >(); // ==, !=
- gil_function_requires< boost::AssignableConcept<T> >();
- gil_function_requires< Swappable<T> >();
- }
- };
- /// \ingroup BasicConcepts
- /**
- \code
- auto concept Metafunction<typename T> {
- typename type;
- };
- \endcode
- */
- template <typename T>
- struct Metafunction {
- void constraints() {
- typedef typename T::type type;
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- //
- // POINT CONCEPTS
- //
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \brief N-dimensional point concept
- /// \ingroup PointConcept
- /**
- \code
- concept PointNDConcept<typename T> : Regular<T> {
- // the type of a coordinate along each axis
- template <size_t K> struct axis; where Metafunction<axis>;
-
- const size_t num_dimensions;
-
- // accessor/modifier of the value of each axis.
- template <size_t K> const typename axis<K>::type& T::axis_value() const;
- template <size_t K> typename axis<K>::type& T::axis_value();
- };
- \endcode
- */
- template <typename P>
- struct PointNDConcept {
- void constraints() {
- gil_function_requires< Regular<P> >();
- typedef typename P::value_type value_type;
- static const std::size_t N=P::num_dimensions; ignore_unused_variable_warning(N);
- typedef typename P::template axis<0>::coord_t FT;
- typedef typename P::template axis<N-1>::coord_t LT;
- FT ft=gil::axis_value<0>(point);
- axis_value<0>(point)=ft;
- LT lt=axis_value<N-1>(point);
- axis_value<N-1>(point)=lt;
-
- // value_type v=point[0]; ignore_unused_variable_warning(v);
- }
- P point;
- };
- /// \brief 2-dimensional point concept
- /// \ingroup PointConcept
- /**
- \code
- concept Point2DConcept<typename T> : PointNDConcept<T> {
- where num_dimensions == 2;
- where SameType<axis<0>::type, axis<1>::type>;
- typename value_type = axis<0>::type;
- const value_type& operator[](const T&, size_t i);
- value_type& operator[]( T&, size_t i);
- value_type x,y;
- };
- \endcode
- */
- template <typename P>
- struct Point2DConcept {
- void constraints() {
- gil_function_requires< PointNDConcept<P> >();
- BOOST_STATIC_ASSERT(P::num_dimensions == 2);
- point.x=point.y;
- point[0]=point[1];
- }
- P point;
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- //
- // ITERATOR MUTABILITY CONCEPTS
- //
- // Taken from boost's concept_check.hpp. Isolating mutability to result in faster compile time
- //
- ////////////////////////////////////////////////////////////////////////////////////////
- namespace detail {
- template <class TT> // Preconditions: TT Models boost_concepts::ForwardTraversalConcept
- struct ForwardIteratorIsMutableConcept {
- void constraints() {
- *i++ = *i; // require postincrement and assignment
- }
- TT i;
- };
- template <class TT> // Preconditions: TT Models boost::BidirectionalIteratorConcept
- struct BidirectionalIteratorIsMutableConcept {
- void constraints() {
- gil_function_requires< ForwardIteratorIsMutableConcept<TT> >();
- *i-- = *i; // require postdecrement and assignment
- }
- TT i;
- };
- template <class TT> // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept
- struct RandomAccessIteratorIsMutableConcept {
- void constraints() {
- gil_function_requires< BidirectionalIteratorIsMutableConcept<TT> >();
- typename std::iterator_traits<TT>::difference_type n=0; ignore_unused_variable_warning(n);
- i[n] = *i; // require element access and assignment
- }
- TT i;
- };
- } // namespace detail
- ////////////////////////////////////////////////////////////////////////////////////////
- //
- // COLOR SPACE CONCEPTS
- //
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \brief Color space type concept
- /// \ingroup ColorSpaceAndLayoutConcept
- /**
- \code
- concept ColorSpaceConcept<MPLRandomAccessSequence Cs> {
- // An MPL Random Access Sequence, whose elements are color tags
- };
- \endcode
- */
- template <typename Cs>
- struct ColorSpaceConcept {
- void constraints() {
- // An MPL Random Access Sequence, whose elements are color tags
- }
- };
- template <typename ColorSpace1, typename ColorSpace2> // Models ColorSpaceConcept
- struct color_spaces_are_compatible : public is_same<ColorSpace1,ColorSpace2> {};
- /// \brief Two color spaces are compatible if they are the same
- /// \ingroup ColorSpaceAndLayoutConcept
- /**
- \code
- concept ColorSpacesCompatibleConcept<ColorSpaceConcept Cs1, ColorSpaceConcept Cs2> {
- where SameType<Cs1,Cs2>;
- };
- \endcode
- */
- template <typename Cs1, typename Cs2>
- struct ColorSpacesCompatibleConcept {
- void constraints() {
- BOOST_STATIC_ASSERT((color_spaces_are_compatible<Cs1,Cs2>::value));
- }
- };
- /// \brief Channel mapping concept
- /// \ingroup ColorSpaceAndLayoutConcept
- /**
- \code
- concept ChannelMappingConcept<MPLRandomAccessSequence CM> {
- // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
- };
- \endcode
- */
- template <typename CM>
- struct ChannelMappingConcept {
- void constraints() {
- // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// Channel CONCEPTS
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \ingroup ChannelConcept
- /// \brief A channel is the building block of a color. Color is defined as a mixture of primary colors and a channel defines the degree to which each primary color is used in the mixture.
- /**
- For example, in the RGB color space, using 8-bit unsigned channels, the color red is defined as [255 0 0], which means maximum of Red, and no Green and Blue.
-
- Built-in scalar types, such as \p int and \p float, are valid GIL channels. In more complex scenarios, channels may be represented as bit ranges or even individual bits.
- In such cases special classes are needed to represent the value and reference to a channel.
-
- Channels have a traits class, \p channel_traits, which defines their associated types as well as their operating ranges.
- \code
- concept ChannelConcept<typename T> : EqualityComparable<T> {
- typename value_type = T; // use channel_traits<T>::value_type to access it
- typename reference = T&; // use channel_traits<T>::reference to access it
- typename pointer = T*; // use channel_traits<T>::pointer to access it
- typename const_reference = const T&; // use channel_traits<T>::const_reference to access it
- typename const_pointer = const T*; // use channel_traits<T>::const_pointer to access it
- static const bool is_mutable; // use channel_traits<T>::is_mutable to access it
- static T min_value(); // use channel_traits<T>::min_value to access it
- static T max_value(); // use channel_traits<T>::min_value to access it
- };
- \endcode
- */
- template <typename T>
- struct ChannelConcept {
- void constraints() {
- gil_function_requires< boost::EqualityComparableConcept<T> >();
-
- typedef typename channel_traits<T>::value_type v;
- typedef typename channel_traits<T>::reference r;
- typedef typename channel_traits<T>::pointer p;
- typedef typename channel_traits<T>::const_reference cr;
- typedef typename channel_traits<T>::const_pointer cp;
- channel_traits<T>::min_value();
- channel_traits<T>::max_value();
- }
- T c;
- };
- namespace detail {
- // Preconditions: T models ChannelConcept
- template <typename T>
- struct ChannelIsMutableConcept {
- void constraints() {
- c1=c2;
- using std::swap;
- swap(c1,c2);
- }
- T c1;
- T c2;
- };
- }
- /// \brief A channel that allows for modifying its value
- /// \ingroup ChannelConcept
- /**
- \code
- concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
- \endcode
- */
- template <typename T>
- struct MutableChannelConcept {
- void constraints() {
- gil_function_requires<ChannelConcept<T> >();
- gil_function_requires<detail::ChannelIsMutableConcept<T> >();
- }
- };
- /// \brief A channel that supports default construction.
- /// \ingroup ChannelConcept
- /**
- \code
- concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
- \endcode
- */
- template <typename T>
- struct ChannelValueConcept {
- void constraints() {
- gil_function_requires<ChannelConcept<T> >();
- gil_function_requires<Regular<T> >();
- }
- };
- /// \brief Predicate metafunction returning whether two channels are compatible
- /// \ingroup ChannelAlgorithm
- ///
- /// Channels are considered compatible if their value types (ignoring constness and references) are the same.
- /**
- Example:
- \code
- BOOST_STATIC_ASSERT((channels_are_compatible<uint8_t, const uint8_t&>::value));
- \endcode
- */
- template <typename T1, typename T2> // Models GIL Pixel
- struct channels_are_compatible
- : public is_same<typename channel_traits<T1>::value_type, typename channel_traits<T2>::value_type> {};
- /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
- /// \ingroup ChannelConcept
- /**
- \code
- concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2> {
- where SameType<T1::value_type, T2::value_type>;
- };
- \endcode
- */
- template <typename T1, typename T2>
- struct ChannelsCompatibleConcept {
- void constraints() {
- BOOST_STATIC_ASSERT((channels_are_compatible<T1,T2>::value));
- }
- };
- /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels
- ///
- /// Convertibility is non-symmetric and implies that one channel can be converted to another. Conversion is explicit and often lossy operation.
- /// \ingroup ChannelConcept
- /**
- \code
- concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel> {
- DstChannel channel_convert(const SrcChannel&);
- };
- \endcode
- */
- template <typename SrcChannel, typename DstChannel>
- struct ChannelConvertibleConcept {
- void constraints() {
- gil_function_requires<ChannelConcept<SrcChannel> >();
- gil_function_requires<MutableChannelConcept<DstChannel> >();
- dst=channel_convert<DstChannel,SrcChannel>(src); ignore_unused_variable_warning(dst);
- }
- SrcChannel src;
- DstChannel dst;
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// COLOR BASE CONCEPTS
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \ingroup ColorBaseConcept
- /// \brief A color base is a container of color elements (such as channels, channel references or channel pointers)
- /**
- The most common use of color base is in the implementation of a pixel, in which case the color
- elements are channel values. The color base concept, however, can be used in other scenarios. For example, a planar pixel has channels that are not
- contiguous in memory. Its reference is a proxy class that uses a color base whose elements are channel references. Its iterator uses a color base
- whose elements are channel iterators.
- A color base must have an associated layout (which consists of a color space, as well as an ordering of the channels).
- There are two ways to index the elements of a color base: A physical index corresponds to the way they are ordered in memory, and
- a semantic index corresponds to the way the elements are ordered in their color space.
- For example, in the RGB color space the elements are ordered as {red_t, green_t, blue_t}. For a color base with a BGR layout, the first element
- in physical ordering is the blue element, whereas the first semantic element is the red one.
- Models of \p ColorBaseConcept are required to provide the \p at_c<K>(ColorBase) function, which allows for accessing the elements based on their
- physical order. GIL provides a \p semantic_at_c<K>(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns
- the corresponding semantic element.
- \code
- concept ColorBaseConcept<typename T> : CopyConstructible<T>, EqualityComparable<T> {
- // a GIL layout (the color space and element permutation)
- typename layout_t;
-
- // The type of K-th element
- template <int K> struct kth_element_type; where Metafunction<kth_element_type>;
-
- // The result of at_c
- template <int K> struct kth_element_const_reference_type; where Metafunction<kth_element_const_reference_type>;
-
- template <int K> kth_element_const_reference_type<T,K>::type at_c(T);
- // Copy-constructible and equality comparable with other compatible color bases
- template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
- T::T(T2);
- template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
- bool operator==(const T&, const T2&);
- template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
- bool operator!=(const T&, const T2&);
- };
- \endcode
- */
- template <typename ColorBase>
- struct ColorBaseConcept {
- void constraints() {
- gil_function_requires< CopyConstructible<ColorBase> >();
- gil_function_requires< EqualityComparable<ColorBase> >();
- typedef typename ColorBase::layout_t::color_space_t color_space_t;
- gil_function_requires<ColorSpaceConcept<color_space_t> >();
- typedef typename ColorBase::layout_t::channel_mapping_t channel_mapping_t;
- // TODO: channel_mapping_t must be an MPL RandomAccessSequence
- static const std::size_t num_elements = size<ColorBase>::value;
- typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
- typedef typename kth_element_const_reference_type<ColorBase,num_elements-1>::type CR;
- CR cr=gil::at_c<num_elements-1>(cb); ignore_unused_variable_warning(cr);
- // functions that work for every pixel (no need to require them)
- semantic_at_c<0>(cb);
- semantic_at_c<num_elements-1>(cb);
- // also static_max(cb), static_min(cb), static_fill(cb,value), and all variations of static_for_each(), static_generate(), static_transform()
- }
- ColorBase cb;
- };
- /// \ingroup ColorBaseConcept
- /// \brief Color base which allows for modifying its elements
- /**
- \code
- concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T> {
- template <int K> struct kth_element_reference_type; where Metafunction<kth_element_reference_type>;
- template <int K> kth_element_reference_type<kth_element_type<T,K>::type>::type at_c(T);
-
- template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
- T& operator=(T&, const T2&);
- };
- \endcode
- */
- template <typename ColorBase>
- struct MutableColorBaseConcept {
- void constraints() {
- gil_function_requires< ColorBaseConcept<ColorBase> >();
- gil_function_requires< Assignable<ColorBase> >();
- gil_function_requires< Swappable<ColorBase> >();
- typedef typename kth_element_reference_type<ColorBase, 0>::type CR;
- CR r=gil::at_c<0>(cb);
- gil::at_c<0>(cb)=r;
- }
- ColorBase cb;
- };
- /// \ingroup ColorBaseConcept
- /// \brief Color base that also has a default-constructor. Refines Regular
- /**
- \code
- concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T> {
- };
- \endcode
- */
- template <typename ColorBase>
- struct ColorBaseValueConcept {
- void constraints() {
- gil_function_requires< MutableColorBaseConcept<ColorBase> >();
- gil_function_requires< Regular<ColorBase> >();
- }
- };
- /// \ingroup ColorBaseConcept
- /// \brief Color base whose elements all have the same type
- /**
- \code
- concept HomogeneousColorBaseConcept<ColorBaseConcept CB> {
- // For all K in [0 ... size<C1>::value-1):
- // where SameType<kth_element_type<CB,K>::type, kth_element_type<CB,K+1>::type>;
- kth_element_const_reference_type<CB,0>::type dynamic_at_c(const CB&, std::size_t n) const;
- };
- \endcode
- */
- template <typename ColorBase>
- struct HomogeneousColorBaseConcept {
- void constraints() {
- gil_function_requires< ColorBaseConcept<ColorBase> >();
- static const std::size_t num_elements = size<ColorBase>::value;
- typedef typename kth_element_type<ColorBase,0>::type T0;
- typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
- BOOST_STATIC_ASSERT((is_same<T0,TN>::value)); // better than nothing
- typedef typename kth_element_const_reference_type<ColorBase,0>::type CRef0;
- CRef0 e0=dynamic_at_c(cb,0);
- }
- ColorBase cb;
- };
- /// \ingroup ColorBaseConcept
- /// \brief Homogeneous color base that allows for modifying its elements
- /**
- \code
- concept MutableHomogeneousColorBaseConcept<ColorBaseConcept CB> : HomogeneousColorBaseConcept<CB> {
- kth_element_reference_type<CB,0>::type dynamic_at_c(CB&, std::size_t n);
- };
- \endcode
- */
- template <typename ColorBase>
- struct MutableHomogeneousColorBaseConcept {
- void constraints() {
- gil_function_requires< ColorBaseConcept<ColorBase> >();
- gil_function_requires< HomogeneousColorBaseConcept<ColorBase> >();
- typedef typename kth_element_reference_type<ColorBase, 0>::type R0;
- R0 x=dynamic_at_c(cb,0);
- dynamic_at_c(cb,0) = dynamic_at_c(cb,0);
- }
- ColorBase cb;
- };
- /// \ingroup ColorBaseConcept
- /// \brief Homogeneous color base that also has a default constructor. Refines Regular.
- /**
- \code
- concept HomogeneousColorBaseValueConcept<typename T> : MutableHomogeneousColorBaseConcept<T>, Regular<T> {
- };
- \endcode
- */
- template <typename ColorBase>
- struct HomogeneousColorBaseValueConcept {
- void constraints() {
- gil_function_requires< MutableHomogeneousColorBaseConcept<ColorBase> >();
- gil_function_requires< Regular<ColorBase> >();
- }
- };
- /// \ingroup ColorBaseConcept
- /// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise.
- /**
- \code
- concept ColorBasesCompatibleConcept<ColorBaseConcept C1, ColorBaseConcept C2> {
- where SameType<C1::layout_t::color_space_t, C2::layout_t::color_space_t>;
- // also, for all K in [0 ... size<C1>::value):
- // where Convertible<kth_semantic_element_type<C1,K>::type, kth_semantic_element_type<C2,K>::type>;
- // where Convertible<kth_semantic_element_type<C2,K>::type, kth_semantic_element_type<C1,K>::type>;
- };
- \endcode
- */
- template <typename ColorBase1, typename ColorBase2>
- struct ColorBasesCompatibleConcept {
- void constraints() {
- BOOST_STATIC_ASSERT((is_same<typename ColorBase1::layout_t::color_space_t,
- typename ColorBase2::layout_t::color_space_t>::value));
- // typedef typename kth_semantic_element_type<ColorBase1,0>::type e1;
- // typedef typename kth_semantic_element_type<ColorBase2,0>::type e2;
- // "e1 is convertible to e2"
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// PIXEL CONCEPTS
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \brief Concept for all pixel-based GIL constructs, such as pixels, iterators, locators, views and images whose value type is a pixel
- /// \ingroup PixelBasedConcept
- /**
- \code
- concept PixelBasedConcept<typename T> {
- typename color_space_type<T>;
- where Metafunction<color_space_type<T> >;
- where ColorSpaceConcept<color_space_type<T>::type>;
- typename channel_mapping_type<T>;
- where Metafunction<channel_mapping_type<T> >;
- where ChannelMappingConcept<channel_mapping_type<T>::type>;
- typename is_planar<T>;
- where Metafunction<is_planar<T> >;
- where SameType<is_planar<T>::type, bool>;
- };
- \endcode
- */
- template <typename P>
- struct PixelBasedConcept {
- void constraints() {
- typedef typename color_space_type<P>::type color_space_t;
- gil_function_requires<ColorSpaceConcept<color_space_t> >();
- typedef typename channel_mapping_type<P>::type channel_mapping_t;
- gil_function_requires<ChannelMappingConcept<channel_mapping_t> >();
- static const bool planar = is_planar<P>::type::value; ignore_unused_variable_warning(planar);
- // This is not part of the concept, but should still work
- static const std::size_t nc = num_channels<P>::value;
- ignore_unused_variable_warning(nc);
- }
- };
- /// \brief Concept for homogeneous pixel-based GIL constructs
- /// \ingroup PixelBasedConcept
- /**
- \code
- concept HomogeneousPixelBasedConcept<PixelBasedConcept T> {
- typename channel_type<T>;
- where Metafunction<channel_type<T> >;
- where ChannelConcept<channel_type<T>::type>;
- };
- \endcode
- */
- template <typename P>
- struct HomogeneousPixelBasedConcept {
- void constraints() {
- gil_function_requires<PixelBasedConcept<P> >();
- typedef typename channel_type<P>::type channel_t;
- gil_function_requires<ChannelConcept<channel_t> >();
- }
- };
- /// \brief Pixel concept - A color base whose elements are channels
- /// \ingroup PixelConcept
- /**
- \code
- concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P> {
- where is_pixel<P>::type::value==true;
- // where for each K [0..size<P>::value-1]:
- // ChannelConcept<kth_element_type<P,K> >;
-
- typename P::value_type; where PixelValueConcept<value_type>;
- typename P::reference; where PixelConcept<reference>;
- typename P::const_reference; where PixelConcept<const_reference>;
- static const bool P::is_mutable;
- template <PixelConcept P2> where { PixelConcept<P,P2> }
- P::P(P2);
- template <PixelConcept P2> where { PixelConcept<P,P2> }
- bool operator==(const P&, const P2&);
- template <PixelConcept P2> where { PixelConcept<P,P2> }
- bool operator!=(const P&, const P2&);
- };
- \endcode
- */
- template <typename P>
- struct PixelConcept {
- void constraints() {
- gil_function_requires<ColorBaseConcept<P> >();
- gil_function_requires<PixelBasedConcept<P> >();
- BOOST_STATIC_ASSERT((is_pixel<P>::value));
- static const bool is_mutable = P::is_mutable; ignore_unused_variable_warning(is_mutable);
- typedef typename P::value_type value_type;
- // gil_function_requires<PixelValueConcept<value_type> >();
- typedef typename P::reference reference;
- gil_function_requires<PixelConcept<typename remove_const_and_reference<reference>::type> >();
- typedef typename P::const_reference const_reference;
- gil_function_requires<PixelConcept<typename remove_const_and_reference<const_reference>::type> >();
- }
- };
- /// \brief Pixel concept that allows for changing its channels
- /// \ingroup PixelConcept
- /**
- \code
- concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P> {
- where is_mutable==true;
- };
- \endcode
- */
- template <typename P>
- struct MutablePixelConcept {
- void constraints() {
- gil_function_requires<PixelConcept<P> >();
- BOOST_STATIC_ASSERT(P::is_mutable);
- }
- };
- /// \brief Homogeneous pixel concept
- /// \ingroup PixelConcept
- /**
- \code
- concept HomogeneousPixelConcept<PixelConcept P> : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P> {
- P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const { return dynamic_at_c(p,i); }
- };
- \endcode
- */
- template <typename P>
- struct HomogeneousPixelConcept {
- void constraints() {
- gil_function_requires<PixelConcept<P> >();
- gil_function_requires<HomogeneousColorBaseConcept<P> >();
- gil_function_requires<HomogeneousPixelBasedConcept<P> >();
- p[0];
- }
- P p;
- };
- /// \brief Homogeneous pixel concept that allows for changing its channels
- /// \ingroup PixelConcept
- /**
- \code
- concept MutableHomogeneousPixelConcept<HomogeneousPixelConcept P> : MutableHomogeneousColorBaseConcept<P> {
- P::template element_reference_type<P>::type operator[](P p, std::size_t i) { return dynamic_at_c(p,i); }
- };
- \endcode
- */
- template <typename P>
- struct MutableHomogeneousPixelConcept {
- void constraints() {
- gil_function_requires<HomogeneousPixelConcept<P> >();
- gil_function_requires<MutableHomogeneousColorBaseConcept<P> >();
- p[0]=v;
- v=p[0];
- }
- typename P::template element_type<P>::type v;
- P p;
- };
- /// \brief Pixel concept that is a Regular type
- /// \ingroup PixelConcept
- /**
- \code
- concept PixelValueConcept<PixelConcept P> : Regular<P> {
- where SameType<value_type,P>;
- };
- \endcode
- */
- template <typename P>
- struct PixelValueConcept {
- void constraints() {
- gil_function_requires<PixelConcept<P> >();
- gil_function_requires<Regular<P> >();
- }
- };
- /// \brief Homogeneous pixel concept that is a Regular type
- /// \ingroup PixelConcept
- /**
- \code
- concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P> {
- where SameType<value_type,P>;
- };
- \endcode
- */
- template <typename P>
- struct HomogeneousPixelValueConcept {
- void constraints() {
- gil_function_requires<HomogeneousPixelConcept<P> >();
- gil_function_requires<Regular<P> >();
- BOOST_STATIC_ASSERT((is_same<P, typename P::value_type>::value));
- }
- };
- namespace detail {
- template <typename P1, typename P2, int K>
- struct channels_are_pairwise_compatible : public
- mpl::and_<channels_are_pairwise_compatible<P1,P2,K-1>,
- channels_are_compatible<typename kth_semantic_element_reference_type<P1,K>::type,
- typename kth_semantic_element_reference_type<P2,K>::type> > {};
-
- template <typename P1, typename P2>
- struct channels_are_pairwise_compatible<P1,P2,-1> : public mpl::true_ {};
- }
- /// \brief Returns whether two pixels are compatible
- ///
- /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another.
- /// \ingroup PixelAlgorithm
- template <typename P1, typename P2> // Models GIL Pixel
- struct pixels_are_compatible
- : public mpl::and_<typename color_spaces_are_compatible<typename color_space_type<P1>::type,
- typename color_space_type<P2>::type>::type,
- detail::channels_are_pairwise_compatible<P1,P2,num_channels<P1>::value-1> > {};
- /// \brief Concept for pixel compatibility
- /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another.
- /// \ingroup PixelConcept
- /**
- \code
- concept PixelsCompatibleConcept<PixelConcept P1, PixelConcept P2> : ColorBasesCompatibleConcept<P1,P2> {
- // where for each K [0..size<P1>::value):
- // ChannelsCompatibleConcept<kth_semantic_element_type<P1,K>::type, kth_semantic_element_type<P2,K>::type>;
- };
- \endcode
- */
- template <typename P1, typename P2> // precondition: P1 and P2 model PixelConcept
- struct PixelsCompatibleConcept {
- void constraints() {
- BOOST_STATIC_ASSERT((pixels_are_compatible<P1,P2>::value));
- }
- };
- /// \brief Pixel convertible concept
- ///
- /// Convertibility is non-symmetric and implies that one pixel can be converted to another, approximating the color. Conversion is explicit and sometimes lossy.
- /// \ingroup PixelConcept
- /**
- \code
- template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
- concept PixelConvertibleConcept {
- void color_convert(const SrcPixel&, DstPixel&);
- };
- \endcode
- */
- template <typename SrcP, typename DstP>
- struct PixelConvertibleConcept {
- void constraints() {
- gil_function_requires<PixelConcept<SrcP> >();
- gil_function_requires<MutablePixelConcept<DstP> >();
- color_convert(src,dst);
- }
- SrcP src;
- DstP dst;
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// DEREFERENCE ADAPTOR CONCEPTS
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \ingroup PixelDereferenceAdaptorConcept
- /// \brief Represents a unary function object that can be invoked upon dereferencing a pixel iterator.
- ///
- /// This can perform an arbitrary computation, such as color conversion or table lookup
- /**
- \code
- concept PixelDereferenceAdaptorConcept<boost::UnaryFunctionConcept D>
- : DefaultConstructibleConcept<D>, CopyConstructibleConcept<D>, AssignableConcept<D> {
- typename const_t; where PixelDereferenceAdaptorConcept<const_t>;
- typename value_type; where PixelValueConcept<value_type>;
- typename reference; // may be mutable
- typename const_reference; // must not be mutable
- static const bool D::is_mutable;
- where Convertible<value_type,result_type>;
- };
- \endcode
- */
- template <typename D>
- struct PixelDereferenceAdaptorConcept {
- void constraints() {
- gil_function_requires< boost::UnaryFunctionConcept<D,
- typename remove_const_and_reference<typename D::result_type>::type,
- typename D::argument_type> >();
- gil_function_requires< boost::DefaultConstructibleConcept<D> >();
- gil_function_requires< boost::CopyConstructibleConcept<D> >();
- gil_function_requires< boost::AssignableConcept<D> >();
- gil_function_requires<PixelConcept<typename remove_const_and_reference<typename D::result_type>::type> >();
- typedef typename D::const_t const_t;
- gil_function_requires<PixelDereferenceAdaptorConcept<const_t> >();
- typedef typename D::value_type value_type;
- gil_function_requires<PixelValueConcept<value_type> >();
- typedef typename D::reference reference; // == PixelConcept (if you remove const and reference)
- typedef typename D::const_reference const_reference; // == PixelConcept (if you remove const and reference)
- const bool is_mutable=D::is_mutable; ignore_unused_variable_warning(is_mutable);
- }
- D d;
- };
- template <typename P>
- struct PixelDereferenceAdaptorArchetype {
- typedef P argument_type;
- typedef P result_type;
- typedef PixelDereferenceAdaptorArchetype const_t;
- typedef typename remove_reference<P>::type value_type;
- typedef typename add_reference<P>::type reference;
- typedef reference const_reference;
- static const bool is_mutable=false;
- P operator()(P) const { throw; }
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// Pixel ITERATOR CONCEPTS
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \brief Concept for iterators, locators and views that can define a type just like the given iterator/locator/view, except it supports runtime specified step along the X navigation
- /// \ingroup PixelIteratorConcept
- /**
- \code
- concept HasDynamicXStepTypeConcept<typename T> {
- typename dynamic_x_step_type<T>;
- where Metafunction<dynamic_x_step_type<T> >;
- };
- \endcode
- */
- template <typename T>
- struct HasDynamicXStepTypeConcept {
- void constraints() {
- typedef typename dynamic_x_step_type<T>::type type;
- }
- };
- /// \brief Concept for locators and views that can define a type just like the given locator or view, except it supports runtime specified step along the Y navigation
- /// \ingroup PixelLocatorConcept
- /**
- \code
- concept HasDynamicYStepTypeConcept<typename T> {
- typename dynamic_y_step_type<T>;
- where Metafunction<dynamic_y_step_type<T> >;
- };
- \endcode
- */
- template <typename T>
- struct HasDynamicYStepTypeConcept {
- void constraints() {
- typedef typename dynamic_y_step_type<T>::type type;
- }
- };
- /// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped
- /// \ingroup PixelLocatorConcept
- /**
- \code
- concept HasTransposedTypeConcept<typename T> {
- typename transposed_type<T>;
- where Metafunction<transposed_type<T> >;
- };
- \endcode
- */
- template <typename T>
- struct HasTransposedTypeConcept {
- void constraints() {
- typedef typename transposed_type<T>::type type;
- }
- };
- /// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept
- /// \ingroup PixelIteratorConcept
- /// \brief STL iterator over pixels
- /// \ingroup PixelIteratorConceptPixelIterator
- /// \brief An STL random access traversal iterator over a model of PixelConcept.
- /**
- GIL's iterators must also provide the following metafunctions:
- - \p const_iterator_type<Iterator>: Returns a read-only equivalent of \p Iterator
- - \p iterator_is_mutable<Iterator>: Returns whether the given iterator is read-only or mutable
- - \p is_iterator_adaptor<Iterator>: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors.
- \code
- concept PixelIteratorConcept<typename Iterator> : boost_concepts::RandomAccessTraversalConcept<Iterator>, PixelBasedConcept<Iterator> {
- where PixelValueConcept<value_type>;
- typename const_iterator_type<It>::type;
- where PixelIteratorConcept<const_iterator_type<It>::type>;
- static const bool iterator_is_mutable<It>::type::value;
- static const bool is_iterator_adaptor<It>::type::value; // is it an iterator adaptor
- };
- \endcode
- */
- template <typename Iterator>
- struct PixelIteratorConcept {
- void constraints() {
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
- gil_function_requires<PixelBasedConcept<Iterator> >();
-
- typedef typename std::iterator_traits<Iterator>::value_type value_type;
- gil_function_requires<PixelValueConcept<value_type> >();
-
- typedef typename const_iterator_type<Iterator>::type const_t;
- static const bool is_mut = iterator_is_mutable<Iterator>::type::value; ignore_unused_variable_warning(is_mut);
- const_t const_it(it); ignore_unused_variable_warning(const_it); // immutable iterator must be constructible from (possibly mutable) iterator
- check_base(typename is_iterator_adaptor<Iterator>::type());
- }
- void check_base(mpl::false_) {}
- void check_base(mpl::true_) {
- typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
- gil_function_requires<PixelIteratorConcept<base_t> >();
- }
- Iterator it;
- };
- namespace detail {
- template <typename Iterator> // Preconditions: Iterator Models PixelIteratorConcept
- struct PixelIteratorIsMutableConcept {
- void constraints() {
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<Iterator> >();
- typedef typename remove_reference<typename std::iterator_traits<Iterator>::reference>::type ref;
- typedef typename element_type<ref>::type channel_t;
- gil_function_requires<detail::ChannelIsMutableConcept<channel_t> >();
- }
- };
- }
- /// \brief Pixel iterator that allows for changing its pixel
- /// \ingroup PixelIteratorConceptPixelIterator
- /**
- \code
- concept MutablePixelIteratorConcept<PixelIteratorConcept Iterator> : MutableRandomAccessIteratorConcept<Iterator> {};
- \endcode
- */
- template <typename Iterator>
- struct MutablePixelIteratorConcept {
- void constraints() {
- gil_function_requires<PixelIteratorConcept<Iterator> >();
- gil_function_requires<detail::PixelIteratorIsMutableConcept<Iterator> >();
- }
- };
- namespace detail {
- // Iterators that can be used as the base of memory_based_step_iterator require some additional functions
- template <typename Iterator> // Preconditions: Iterator Models boost_concepts::RandomAccessTraversalConcept
- struct RandomAccessIteratorIsMemoryBasedConcept {
- void constraints() {
- std::ptrdiff_t bs=memunit_step(it); ignore_unused_variable_warning(bs);
- it=memunit_advanced(it,3);
- std::ptrdiff_t bd=memunit_distance(it,it); ignore_unused_variable_warning(bd);
- memunit_advance(it,3);
- // for performace you may also provide a customized implementation of memunit_advanced_ref
- }
- Iterator it;
- };
- }
- /// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept
- /// \ingroup PixelIteratorConcept
- /// \brief Iterator that advances by a specified step
- /// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits)
- /// \ingroup PixelIteratorConceptStepIterator
- /**
- \code
- concept MemoryBasedIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator> {
- typename byte_to_memunit<Iterator>; where metafunction<byte_to_memunit<Iterator> >;
- std::ptrdiff_t memunit_step(const Iterator&);
- std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&);
- void memunit_advance(Iterator&, std::ptrdiff_t diff);
- Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; }
- Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); }
- };
- \endcode
- */
- template <typename Iterator>
- struct MemoryBasedIteratorConcept {
- void constraints() {
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
- gil_function_requires<detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator> >();
- }
- };
- /// \brief Step iterator concept
- ///
- /// Step iterators are iterators that have a set_step method
- /// \ingroup PixelIteratorConceptStepIterator
- /**
- \code
- concept StepIteratorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
- template <Integral D> void Iterator::set_step(D step);
- };
- \endcode
- */
- template <typename Iterator>
- struct StepIteratorConcept {
- void constraints() {
- gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
- it.set_step(0);
- }
- Iterator it;
- };
- /// \brief Step iterator that allows for modifying its current value
- ///
- /// \ingroup PixelIteratorConceptStepIterator
- /**
- \code
- concept MutableStepIteratorConcept<Mutable_ForwardIteratorConcept Iterator> : StepIteratorConcept<Iterator> {};
- \endcode
- */
- template <typename Iterator>
- struct MutableStepIteratorConcept {
- void constraints() {
- gil_function_requires<StepIteratorConcept<Iterator> >();
- gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
- }
- };
- /// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept
- /// \ingroup PixelIteratorConcept
- /// \brief Adaptor over another iterator
- /// \ingroup PixelIteratorConceptIteratorAdaptor
- /// \brief Iterator adaptor is a forward iterator adapting another forward iterator.
- /**
- In addition to GIL iterator requirements, GIL iterator adaptors must provide the following metafunctions:
- - \p is_iterator_adaptor<Iterator>: Returns \p mpl::true_
- - \p iterator_adaptor_get_base<Iterator>: Returns the base iterator type
- - \p iterator_adaptor_rebind<Iterator,NewBase>: Replaces the base iterator with the new one
- The adaptee can be obtained from the iterator via the "base()" method.
- \code
- concept IteratorAdaptorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
- where SameType<is_iterator_adaptor<Iterator>::type, mpl::true_>;
- typename iterator_adaptor_get_base<Iterator>;
- where Metafunction<iterator_adaptor_get_base<Iterator> >;
- where boost_concepts::ForwardTraversalConcept<iterator_adaptor_get_base<Iterator>::type>;
-
- typename another_iterator;
- typename iterator_adaptor_rebind<Iterator,another_iterator>::type;
- where boost_concepts::ForwardTraversalConcept<another_iterator>;
- where IteratorAdaptorConcept<iterator_adaptor_rebind<Iterator,another_iterator>::type>;
- const iterator_adaptor_get_base<Iterator>::type& Iterator::base() const;
- };
- \endcode
- */
- template <typename Iterator>
- struct IteratorAdaptorConcept {
- void constraints() {
- gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
- typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
- gil_function_requires<boost_concepts::ForwardTraversalConcept<base_t> >();
- BOOST_STATIC_ASSERT(is_iterator_adaptor<Iterator>::value);
- typedef typename iterator_adaptor_rebind<Iterator, void*>::type rebind_t;
- base_t base=it.base(); ignore_unused_variable_warning(base);
- }
- Iterator it;
- };
- /// \brief Iterator adaptor that is mutable
- /// \ingroup PixelIteratorConceptIteratorAdaptor
- /**
- \code
- concept MutableIteratorAdaptorConcept<Mutable_ForwardIteratorConcept Iterator> : IteratorAdaptorConcept<Iterator> {};
- \endcode
- */
- template <typename Iterator>
- struct MutableIteratorAdaptorConcept {
- void constraints() {
- gil_function_requires<IteratorAdaptorConcept<Iterator> >();
- gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// LOCATOR CONCEPTS
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
- /// \ingroup PixelLocatorConcept
- /// \brief N-dimensional locator
- /// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
- /// \ingroup PixelLocatorConcept
- /// \brief 2-dimensional locator
- /// \defgroup PixelLocator2DConcept PixelLocatorConcept
- /// \ingroup PixelLocatorConcept
- /// \brief 2-dimensional locator over pixel data
- /// \ingroup LocatorNDConcept
- /// \brief N-dimensional locator over immutable values
- /**
- \code
- concept RandomAccessNDLocatorConcept<Regular Loc> {
- typename value_type; // value over which the locator navigates
- typename reference; // result of dereferencing
- typename difference_type; where PointNDConcept<difference_type>; // return value of operator-.
- typename const_t; // same as Loc, but operating over immutable values
- typename cached_location_t; // type to store relative location (for efficient repeated access)
- typename point_t = difference_type;
-
- static const size_t num_dimensions; // dimensionality of the locator
- where num_dimensions = point_t::num_dimensions;
-
- // The difference_type and iterator type along each dimension. The iterators may only differ in
- // difference_type. Their value_type must be the same as Loc::value_type
- template <size_t D> struct axis {
- typename coord_t = point_t::axis<D>::coord_t;
- typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
- where iterator::value_type == value_type;
- };
- // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing
- template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
- typename type; where RandomAccessNDLocatorConcept<type>;
- static type make(const Loc& loc, const Deref& deref);
- };
-
- Loc& operator+=(Loc&, const difference_type&);
- Loc& operator-=(Loc&, const difference_type&);
- Loc operator+(const Loc&, const difference_type&);
- Loc operator-(const Loc&, const difference_type&);
-
- reference operator*(const Loc&);
- reference operator[](const Loc&, const difference_type&);
-
- // Storing relative location for faster repeated access and accessing it
- cached_location_t Loc::cache_location(const difference_type&) const;
- reference operator[](const Loc&,const cached_location_t&);
-
- // Accessing iterators along a given dimension at the current location or at a given offset
- template <size_t D> axis<D>::iterator& Loc::axis_iterator();
- template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
- template <size_t D> axis<D>::iterator Loc::axis_iterator(const difference_type&) const;
- };
- \endcode
- */
- template <typename Loc>
- struct RandomAccessNDLocatorConcept {
- void constraints() {
- gil_function_requires< Regular<Loc> >();
- typedef typename Loc::value_type value_type;
- typedef typename Loc::reference reference; // result of dereferencing
- typedef typename Loc::difference_type difference_type; // result of operator-(pixel_locator, pixel_locator)
- typedef typename Loc::cached_location_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access)
- typedef typename Loc::const_t const_t; // same as this type, but over const values
- typedef typename Loc::point_t point_t; // same as difference_type
- static const std::size_t N=Loc::num_dimensions; ignore_unused_variable_warning(N);
-
- typedef typename Loc::template axis<0>::iterator first_it_type;
- typedef typename Loc::template axis<N-1>::iterator last_it_type;
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type> >();
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type> >();
- // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
- gil_function_requires<PointNDConcept<point_t> >();
- BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
- BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
- BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
- difference_type d;
- loc+=d;
- loc-=d;
- loc=loc+d;
- loc=loc-d;
- reference r1=loc[d]; ignore_unused_variable_warning(r1);
- reference r2=*loc; ignore_unused_variable_warning(r2);
- cached_location_t cl=loc.cache_location(d); ignore_unused_variable_warning(cl);
- reference r3=loc[d]; ignore_unused_variable_warning(r3);
- first_it_type fi=loc.template axis_iterator<0>();
- fi=loc.template axis_iterator<0>(d);
- last_it_type li=loc.template axis_iterator<N-1>();
- li=loc.template axis_iterator<N-1>(d);
- typedef PixelDereferenceAdaptorArchetype<typename Loc::value_type> deref_t;
- typedef typename Loc::template add_deref<deref_t>::type dtype;
- //gil_function_requires<RandomAccessNDLocatorConcept<dtype> >(); // infinite recursion
- }
- Loc loc;
- };
- /// \ingroup Locator2DConcept
- /// \brief 2-dimensional locator over immutable values
- /**
- \code
- concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc> {
- where num_dimensions==2;
- where Point2DConcept<point_t>;
-
- typename x_iterator = axis<0>::iterator;
- typename y_iterator = axis<1>::iterator;
- typename x_coord_t = axis<0>::coord_t;
- typename y_coord_t = axis<1>::coord_t;
-
- // Only available to locators that have dynamic step in Y
- //Loc::Loc(const Loc& loc, y_coord_t);
- // Only available to locators that have dynamic step in X and Y
- //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);
- x_iterator& Loc::x();
- x_iterator const& Loc::x() const;
- y_iterator& Loc::y();
- y_iterator const& Loc::y() const;
-
- x_iterator Loc::x_at(const difference_type&) const;
- y_iterator Loc::y_at(const difference_type&) const;
- Loc Loc::xy_at(const difference_type&) const;
-
- // x/y versions of all methods that can take difference type
- x_iterator Loc::x_at(x_coord_t, y_coord_t) const;
- y_iterator Loc::y_at(x_coord_t, y_coord_t) const;
- Loc Loc::xy_at(x_coord_t, y_coord_t) const;
- reference operator()(const Loc&, x_coord_t, y_coord_t);
- cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;
- bool Loc::is_1d_traversable(x_coord_t width) const;
- y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
- };
- \endcode
- */
- template <typename Loc>
- struct RandomAccess2DLocatorConcept {
- void constraints() {
- gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
- BOOST_STATIC_ASSERT(Loc::num_dimensions==2);
- typedef typename dynamic_x_step_type<Loc>::type dynamic_x_step_t;
- typedef typename dynamic_y_step_type<Loc>::type dynamic_y_step_t;
- typedef typename transposed_type<Loc>::type transposed_t;
- typedef typename Loc::cached_location_t cached_location_t;
- gil_function_requires<Point2DConcept<typename Loc::point_t> >();
- typedef typename Loc::x_iterator x_iterator;
- typedef typename Loc::y_iterator y_iterator;
- typedef typename Loc::x_coord_t x_coord_t;
- typedef typename Loc::y_coord_t y_coord_t;
- x_coord_t xd=0; ignore_unused_variable_warning(xd);
- y_coord_t yd=0; ignore_unused_variable_warning(yd);
- typename Loc::difference_type d;
- typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r);
- dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
- dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
- typedef typename dynamic_y_step_type<typename dynamic_x_step_type<transposed_t>::type>::type dynamic_xy_step_transposed_t;
- dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
- bool is_contiguous=loc.is_1d_traversable(xd); ignore_unused_variable_warning(is_contiguous);
- loc.y_distance_to(loc, xd);
- loc=loc.xy_at(d);
- loc=loc.xy_at(xd,yd);
- x_iterator xit=loc.x_at(d);
- xit=loc.x_at(xd,yd);
- xit=loc.x();
- y_iterator yit=loc.y_at(d);
- yit=loc.y_at(xd,yd);
- yit=loc.y();
- cached_location_t cl=loc.cache_location(xd,yd); ignore_unused_variable_warning(cl);
- }
- Loc loc;
- };
- /// \ingroup PixelLocator2DConcept
- /// \brief GIL's 2-dimensional locator over immutable GIL pixels
- /**
- \code
- concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc> {
- where PixelValueConcept<value_type>;
- where PixelIteratorConcept<x_iterator>;
- where PixelIteratorConcept<y_iterator>;
- where x_coord_t == y_coord_t;
- typename coord_t = x_coord_t;
- };
- \endcode
- */
- template <typename Loc>
- struct PixelLocatorConcept {
- void constraints() {
- gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
- gil_function_requires< PixelIteratorConcept<typename Loc::x_iterator> >();
- gil_function_requires< PixelIteratorConcept<typename Loc::y_iterator> >();
- typedef typename Loc::coord_t coord_t;
- BOOST_STATIC_ASSERT((is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value));
- }
- Loc loc;
- };
- namespace detail {
- template <typename Loc> // preconditions: Loc Models RandomAccessNDLocatorConcept
- struct RandomAccessNDLocatorIsMutableConcept {
- void constraints() {
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename Loc::template axis<0>::iterator> >();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename Loc::template axis<Loc::num_dimensions-1>::iterator> >();
- typename Loc::difference_type d; initialize_it(d);
- typename Loc::value_type v;initialize_it(v);
- typename Loc::cached_location_t cl=loc.cache_location(d);
- *loc=v;
- loc[d]=v;
- loc[cl]=v;
- }
- Loc loc;
- };
- template <typename Loc> // preconditions: Loc Models RandomAccess2DLocatorConcept
- struct RandomAccess2DLocatorIsMutableConcept {
- void constraints() {
- gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
- typename Loc::x_coord_t xd=0; ignore_unused_variable_warning(xd);
- typename Loc::y_coord_t yd=0; ignore_unused_variable_warning(yd);
- typename Loc::value_type v; initialize_it(v);
- loc(xd,yd)=v;
- }
- Loc loc;
- };
- }
- /// \ingroup LocatorNDConcept
- /// \brief N-dimensional locator over mutable pixels
- /**
- \code
- concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc> {
- where Mutable<reference>;
- };
- \endcode
- */
- template <typename Loc>
- struct MutableRandomAccessNDLocatorConcept {
- void constraints() {
- gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
- gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
- }
- };
- /// \ingroup Locator2DConcept
- /// \brief 2-dimensional locator over mutable pixels
- /**
- \code
- concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc> : MutableRandomAccessNDLocatorConcept<Loc> {};
- \endcode
- */
- template <typename Loc>
- struct MutableRandomAccess2DLocatorConcept {
- void constraints() {
- gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
- gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
- }
- };
- /// \ingroup PixelLocator2DConcept
- /// \brief GIL's 2-dimensional locator over mutable GIL pixels
- /**
- \code
- concept MutablePixelLocatorConcept<PixelLocatorConcept Loc> : MutableRandomAccess2DLocatorConcept<Loc> {};
- \endcode
- */
- template <typename Loc>
- struct MutablePixelLocatorConcept {
- void constraints() {
- gil_function_requires<PixelLocatorConcept<Loc> >();
- gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// IMAGE VIEW CONCEPTS
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
- /// \ingroup ImageViewConcept
- /// \brief N-dimensional range
- /// \defgroup ImageView2DConcept ImageView2DConcept
- /// \ingroup ImageViewConcept
- /// \brief 2-dimensional range
- /// \defgroup PixelImageViewConcept ImageViewConcept
- /// \ingroup ImageViewConcept
- /// \brief 2-dimensional range over pixel data
- /// \ingroup ImageViewNDConcept
- /// \brief N-dimensional view over immutable values
- /**
- \code
- concept RandomAccessNDImageViewConcept<Regular View> {
- typename value_type;
- typename reference; // result of dereferencing
- typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
- typename const_t; where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
- typename point_t; where PointNDConcept<point_t>; // N-dimensional point
- typename locator; where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
- typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
- typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
- typename size_type; // the return value of size()
- // Equivalent to RandomAccessNDLocatorConcept::axis
- template <size_t D> struct axis {
- typename coord_t = point_t::axis<D>::coord_t;
- typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
- where SameType<coord_t, iterator::difference_type>;
- where SameType<iterator::value_type,value_type>;
- };
- // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
- template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
- typename type; where RandomAccessNDImageViewConcept<type>;
- static type make(const View& v, const Deref& deref);
- };
- static const size_t num_dimensions = point_t::num_dimensions;
-
- // Create from a locator at the top-left corner and dimensions
- View::View(const locator&, const point_type&);
-
- size_type View::size() const; // total number of elements
- reference operator[](View, const difference_type&) const; // 1-dimensional reference
- iterator View::begin() const;
- iterator View::end() const;
- reverse_iterator View::rbegin() const;
- reverse_iterator View::rend() const;
- iterator View::at(const point_t&);
- point_t View::dimensions() const; // number of elements along each dimension
- bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
- // iterator along a given dimension starting at a given point
- template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;
- reference operator()(View,const point_t&) const;
- };
- \endcode
- */
- template <typename View>
- struct RandomAccessNDImageViewConcept {
- void constraints() {
- gil_function_requires< Regular<View> >();
- typedef typename View::value_type value_type;
- typedef typename View::reference reference; // result of dereferencing
- typedef typename View::difference_type difference_type; // result of operator-(1d_iterator,1d_iterator)
- typedef typename View::const_t const_t; // same as this type, but over const values
- typedef typename View::point_t point_t; // N-dimensional point
- typedef typename View::locator locator; // N-dimensional locator
- typedef typename View::iterator iterator;
- typedef typename View::reverse_iterator reverse_iterator;
- typedef typename View::size_type size_type;
- static const std::size_t N=View::num_dimensions;
-
- gil_function_requires<RandomAccessNDLocatorConcept<locator> >();
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator> >();
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator> >();
- typedef typename View::template axis<0>::iterator first_it_type;
- typedef typename View::template axis<N-1>::iterator last_it_type;
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type> >();
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type> >();
- // BOOST_STATIC_ASSERT((typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
- // BOOST_STATIC_ASSERT((typename std::iterator_traits< last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
- // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
- gil_function_requires<PointNDConcept<point_t> >();
- BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
- BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
- BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
- point_t p;
- locator lc;
- iterator it;
- reverse_iterator rit;
- difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
- View(p,lc); // view must be constructible from a locator and a point
- p=view.dimensions();
- lc=view.pixels();
- size_type sz=view.size(); ignore_unused_variable_warning(sz);
- bool is_contiguous=view.is_1d_traversable(); ignore_unused_variable_warning(is_contiguous);
- it=view.begin();
- it=view.end();
- rit=view.rbegin();
- rit=view.rend();
- reference r1=view[d]; ignore_unused_variable_warning(r1); // 1D access
- reference r2=view(p); ignore_unused_variable_warning(r2); // 2D access
- // get 1-D iterator of any dimension at a given pixel location
- first_it_type fi=view.template axis_iterator<0>(p); ignore_unused_variable_warning(fi);
- last_it_type li=view.template axis_iterator<N-1>(p); ignore_unused_variable_warning(li);
- typedef PixelDereferenceAdaptorArchetype<typename View::value_type> deref_t;
- typedef typename View::template add_deref<deref_t>::type dtype;
- }
- View view;
- };
- /// \ingroup ImageView2DConcept
- /// \brief 2-dimensional view over immutable values
- /**
- \code
- concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
- where num_dimensions==2;
- typename x_iterator = axis<0>::iterator;
- typename y_iterator = axis<1>::iterator;
- typename x_coord_t = axis<0>::coord_t;
- typename y_coord_t = axis<1>::coord_t;
- typename xy_locator = locator;
-
- x_coord_t View::width() const;
- y_coord_t View::height() const;
-
- // X-navigation
- x_iterator View::x_at(const point_t&) const;
- x_iterator View::row_begin(y_coord_t) const;
- x_iterator View::row_end (y_coord_t) const;
- // Y-navigation
- y_iterator View::y_at(const point_t&) const;
- y_iterator View::col_begin(x_coord_t) const;
- y_iterator View::col_end (x_coord_t) const;
-
- // navigating in 2D
- xy_locator View::xy_at(const point_t&) const;
- // (x,y) versions of all methods taking point_t
- View::View(x_coord_t,y_coord_t,const locator&);
- iterator View::at(x_coord_t,y_coord_t) const;
- reference operator()(View,x_coord_t,y_coord_t) const;
- xy_locator View::xy_at(x_coord_t,y_coord_t) const;
- x_iterator View::x_at(x_coord_t,y_coord_t) const;
- y_iterator View::y_at(x_coord_t,y_coord_t) const;
- };
- \endcode
- */
- template <typename View>
- struct RandomAccess2DImageViewConcept {
- void constraints() {
- gil_function_requires<RandomAccessNDImageViewConcept<View> >();
- BOOST_STATIC_ASSERT(View::num_dimensions==2);
- // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
- gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator> >();
- typedef typename dynamic_x_step_type<View>::type dynamic_x_step_t;
- typedef typename dynamic_y_step_type<View>::type dynamic_y_step_t;
- typedef typename transposed_type<View>::type transposed_t;
- typedef typename View::x_iterator x_iterator;
- typedef typename View::y_iterator y_iterator;
- typedef typename View::x_coord_t x_coord_t;
- typedef typename View::y_coord_t y_coord_t;
- typedef typename View::xy_locator xy_locator;
- x_coord_t xd=0; ignore_unused_variable_warning(xd);
- y_coord_t yd=0; ignore_unused_variable_warning(yd);
- x_iterator xit;
- y_iterator yit;
- typename View::point_t d;
- View(xd,yd,xy_locator()); // constructible with width, height, 2d_locator
- xy_locator lc=view.xy_at(xd,yd);
- lc=view.xy_at(d);
- typename View::reference r=view(xd,yd); ignore_unused_variable_warning(r);
- xd=view.width();
- yd=view.height();
- xit=view.x_at(d);
- xit=view.x_at(xd,yd);
- xit=view.row_begin(xd);
- xit=view.row_end(xd);
- yit=view.y_at(d);
- yit=view.y_at(xd,yd);
- yit=view.col_begin(xd);
- yit=view.col_end(xd);
- }
- View view;
- };
- /// \ingroup PixelImageViewConcept
- /// \brief GIL's 2-dimensional view over immutable GIL pixels
- /**
- \code
- concept ImageViewConcept<RandomAccess2DImageViewConcept View> {
- where PixelValueConcept<value_type>;
- where PixelIteratorConcept<x_iterator>;
- where PixelIteratorConcept<y_iterator>;
- where x_coord_t == y_coord_t;
-
- typename coord_t = x_coord_t;
- std::size_t View::num_channels() const;
- };
- \endcode
- */
- template <typename View>
- struct ImageViewConcept {
- void constraints() {
- gil_function_requires<RandomAccess2DImageViewConcept<View> >();
- // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
- gil_function_requires<PixelLocatorConcept<typename View::xy_locator> >();
-
- BOOST_STATIC_ASSERT((is_same<typename View::x_coord_t, typename View::y_coord_t>::value));
- typedef typename View::coord_t coord_t; // 1D difference type (same for all dimensions)
- std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
- }
- View view;
- };
- namespace detail {
- template <typename View> // Preconditions: View Models RandomAccessNDImageViewConcept
- struct RandomAccessNDImageViewIsMutableConcept {
- void constraints() {
- gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator> >();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator> >();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::reverse_iterator> >();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::template axis<0>::iterator> >();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::template axis<View::num_dimensions-1>::iterator> >();
- typename View::difference_type diff; initialize_it(diff); ignore_unused_variable_warning(diff);
- typename View::point_t pt;
- typename View::value_type v; initialize_it(v);
- view[diff]=v;
- view(pt)=v;
- }
- View view;
- };
- template <typename View> // preconditions: View Models RandomAccessNDImageViewConcept
- struct RandomAccess2DImageViewIsMutableConcept {
- void constraints() {
- gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
- typename View::x_coord_t xd=0; ignore_unused_variable_warning(xd);
- typename View::y_coord_t yd=0; ignore_unused_variable_warning(yd);
- typename View::value_type v; initialize_it(v);
- view(xd,yd)=v;
- }
- View view;
- };
- template <typename View> // preconditions: View Models ImageViewConcept
- struct PixelImageViewIsMutableConcept {
- void constraints() {
- gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
- }
- };
- }
- /// \ingroup ImageViewNDConcept
- /// \brief N-dimensional view over mutable values
- /**
- \code
- concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View> {
- where Mutable<reference>;
- };
- \endcode
- */
- template <typename View>
- struct MutableRandomAccessNDImageViewConcept {
- void constraints() {
- gil_function_requires<RandomAccessNDImageViewConcept<View> >();
- gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
- }
- };
- /// \ingroup ImageView2DConcept
- /// \brief 2-dimensional view over mutable values
- /**
- \code
- concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View> : MutableRandomAccessNDImageViewConcept<View> {};
- \endcode
- */
- template <typename View>
- struct MutableRandomAccess2DImageViewConcept {
- void constraints() {
- gil_function_requires<RandomAccess2DImageViewConcept<View> >();
- gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
- }
- };
- /// \ingroup PixelImageViewConcept
- /// \brief GIL's 2-dimensional view over mutable GIL pixels
- /**
- \code
- concept MutableImageViewConcept<ImageViewConcept View> : MutableRandomAccess2DImageViewConcept<View> {};
- \endcode
- */
- template <typename View>
- struct MutableImageViewConcept {
- void constraints() {
- gil_function_requires<ImageViewConcept<View> >();
- gil_function_requires<detail::PixelImageViewIsMutableConcept<View> >();
- }
- };
- /// \brief Returns whether two views are compatible
- ///
- /// Views are compatible if their pixels are compatible. Compatible views can be assigned and copy constructed from one another.
- template <typename V1, typename V2> // Model ImageViewConcept
- struct views_are_compatible : public pixels_are_compatible<typename V1::value_type, typename V2::value_type> {};
- /// \brief Views are compatible if they have the same color spaces and compatible channel values. Constness and layout are not important for compatibility
- /// \ingroup ImageViewConcept
- /**
- \code
- concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2> {
- where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
- };
- \endcode
- */
- template <typename V1, typename V2>
- struct ViewsCompatibleConcept {
- void constraints() {
- BOOST_STATIC_ASSERT((views_are_compatible<V1,V2>::value));
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// IMAGE CONCEPTS
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \ingroup ImageConcept
- /// \brief N-dimensional container of values
- /**
- \code
- concept RandomAccessNDImageConcept<typename Img> : Regular<Img> {
- typename view_t; where MutableRandomAccessNDImageViewConcept<view_t>;
- typename const_view_t = view_t::const_t;
- typename point_t = view_t::point_t;
- typename value_type = view_t::value_type;
- typename allocator_type;
- Img::Img(point_t dims, std::size_t alignment=1);
- Img::Img(point_t dims, value_type fill_value, std::size_t alignment);
-
- void Img::recreate(point_t new_dims, std::size_t alignment=1);
- void Img::recreate(point_t new_dims, value_type fill_value, std::size_t alignment);
- const point_t& Img::dimensions() const;
- const const_view_t& const_view(const Img&);
- const view_t& view(Img&);
- };
- \endcode
- */
- template <typename Img>
- struct RandomAccessNDImageConcept {
- void constraints() {
- gil_function_requires<Regular<Img> >();
- typedef typename Img::view_t view_t;
- gil_function_requires<MutableRandomAccessNDImageViewConcept<view_t> >();
- typedef typename Img::const_view_t const_view_t;
- typedef typename Img::value_type pixel_t;
- typedef typename Img::point_t point_t;
- gil_function_requires<PointNDConcept<point_t> >();
- const_view_t cv = const_view(img); ignore_unused_variable_warning(cv);
- view_t v = view(img); ignore_unused_variable_warning(v);
- pixel_t fill_value;
- point_t pt=img.dimensions();
- Img im1(pt);
- Img im2(pt,1);
- Img im3(pt,fill_value,1);
- img.recreate(pt);
- img.recreate(pt,1);
- img.recreate(pt,fill_value,1);
- }
- Img img;
- };
- /// \ingroup ImageConcept
- /// \brief 2-dimensional container of values
- /**
- \code
- concept RandomAccess2DImageConcept<RandomAccessNDImageConcept Img> {
- typename x_coord_t = const_view_t::x_coord_t;
- typename y_coord_t = const_view_t::y_coord_t;
-
- Img::Img(x_coord_t width, y_coord_t height, std::size_t alignment=1);
- Img::Img(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
- x_coord_t Img::width() const;
- y_coord_t Img::height() const;
-
- void Img::recreate(x_coord_t width, y_coord_t height, std::size_t alignment=1);
- void Img::recreate(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
- };
- \endcode
- */
- template <typename Img>
- struct RandomAccess2DImageConcept {
- void constraints() {
- gil_function_requires<RandomAccessNDImageConcept<Img> >();
- typedef typename Img::x_coord_t x_coord_t;
- typedef typename Img::y_coord_t y_coord_t;
- typedef typename Img::value_type value_t;
- gil_function_requires<MutableRandomAccess2DImageViewConcept<typename Img::view_t> >();
- x_coord_t w=img.width();
- y_coord_t h=img.height();
- value_t fill_value;
- Img im1(w,h);
- Img im2(w,h,1);
- Img im3(w,h,fill_value,1);
- img.recreate(w,h);
- img.recreate(w,h,1);
- img.recreate(w,h,fill_value,1);
- }
- Img img;
- };
- /// \ingroup ImageConcept
- /// \brief 2-dimensional image whose value type models PixelValueConcept
- /**
- \code
- concept ImageConcept<RandomAccess2DImageConcept Img> {
- where MutableImageViewConcept<view_t>;
- typename coord_t = view_t::coord_t;
- };
- \endcode
- */
- template <typename Img>
- struct ImageConcept {
- void constraints() {
- gil_function_requires<RandomAccess2DImageConcept<Img> >();
- gil_function_requires<MutableImageViewConcept<typename Img::view_t> >();
- typedef typename Img::coord_t coord_t;
- BOOST_STATIC_ASSERT(num_channels<Img>::value == mpl::size<typename color_space_type<Img>::type>::value);
- BOOST_STATIC_ASSERT((is_same<coord_t, typename Img::x_coord_t>::value));
- BOOST_STATIC_ASSERT((is_same<coord_t, typename Img::y_coord_t>::value));
- }
- Img img;
- };
- #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
- #pragma warning(pop)
- #endif
- #if defined(__GNUC__) && (__GNUC__ >= 4)
- #pragma GCC diagnostic pop
- #endif
- } } // namespace boost::gil
- #endif
|