& p); template typename kth_element_const_reference_type,K>::type at_c(const packed_pixel& p); template struct bit_aligned_pixel_reference; template inline typename kth_element_reference_type, K>::type at_c(const bit_aligned_pixel_reference& p); #endif // Forward-declare semantic_at_c template typename disable_if,typename kth_semantic_element_reference_type::type>::type semantic_at_c(ColorBase& p); template typename kth_semantic_element_const_reference_type::type semantic_at_c(const ColorBase& p); template struct dynamic_x_step_type; template struct dynamic_y_step_type; template struct transposed_type; namespace detail { template void initialize_it(T& x) {} } // namespace detail template struct remove_const_and_reference : public remove_const::type> {}; #ifdef BOOST_GIL_USE_CONCEPT_CHECK #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept); template void gil_function_requires() { function_requires(); } #else #define GIL_CLASS_REQUIRE(T,NS,C) template void gil_function_requires() {} #endif /// \ingroup BasicConcepts /** \code auto concept DefaultConstructible { T::T(); }; \endcode */ template struct DefaultConstructible { void constraints() { function_requires >(); } }; /// \ingroup BasicConcepts /** \codeauto concept CopyConstructible { T::T(T); T::~T(); }; \endcode */ template struct CopyConstructible { void constraints() { function_requires >(); } }; /// \ingroup BasicConcepts /** \code auto concept Assignable { typename result_type; result_type operator=(T&, U); }; \endcode */ template struct Assignable { void constraints() { function_requires >(); } }; /// \ingroup BasicConcepts /** \code auto concept EqualityComparable { bool operator==(T x, T y); bool operator!=(T x, T y) { return !(x==y); } }; \endcode */ template struct EqualityComparable { void constraints() { function_requires >(); } }; /// \ingroup BasicConcepts /** \code concept SameType;// unspecified \endcode */ template struct SameType { void constraints() { BOOST_STATIC_ASSERT((boost::is_same::value_core)); } }; /// \ingroup BasicConcepts /** \code auto concept Swappable { void swap(T&,T&); }; \endcode */ template struct Swappable { void constraints() { using std::swap; swap(x,y); } T x,y; }; /// \ingroup BasicConcepts /** \code auto concept Regular : DefaultConstructible, CopyConstructible, EqualityComparable, Assignable, Swappable {}; \endcode */ template struct Regular { void constraints() { gil_function_requires< boost::DefaultConstructibleConcept >(); gil_function_requires< boost::CopyConstructibleConcept >(); gil_function_requires< boost::EqualityComparableConcept >(); // ==, != gil_function_requires< boost::AssignableConcept >(); gil_function_requires< Swappable >(); } }; /// \ingroup BasicConcepts /** \code auto concept Metafunction { typename type; }; \endcode */ template struct Metafunction { void constraints() { typedef typename T::type type; } }; //////////////////////////////////////////////////////////////////////////////////////// // // POINT CONCEPTS // //////////////////////////////////////////////////////////////////////////////////////// /// \brief N-dimensional point concept /// \ingroup PointConcept /** \code concept PointNDConcept : Regular { // the type of a coordinate along each axis template struct axis; where Metafunction; const size_t num_dimensions; // accessor/modifier of the value of each axis. template const typename axis::type& T::axis_value() const; template typename axis::type& T::axis_value(); }; \endcode */ template struct PointNDConcept { void constraints() { gil_function_requires< Regular >(); 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::coord_t LT; FT ft=gil::axis_value<0>(point); axis_value<0>(point)=ft; LT lt=axis_value(point); axis_value(point)=lt; value_type v=point[0]; ignore_unused_variable_warning(v); point[0]=point[0]; } P point; }; /// \brief 2-dimensional point concept /// \ingroup PointConcept /** \code concept Point2DConcept : PointNDConcept { where num_dimensions == 2; where SameType::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 struct Point2DConcept { void constraints() { gil_function_requires< PointNDConcept >(); 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 // Preconditions: TT Models boost_concepts::ForwardTraversalConcept struct ForwardIteratorIsMutableConcept { void constraints() { *i++ = *i; // require postincrement and assignment } TT i; }; template // Preconditions: TT Models boost::BidirectionalIteratorConcept struct BidirectionalIteratorIsMutableConcept { void constraints() { gil_function_requires< ForwardIteratorIsMutableConcept >(); *i-- = *i; // require postdecrement and assignment } TT i; }; template // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept struct RandomAccessIteratorIsMutableConcept { void constraints() { gil_function_requires< BidirectionalIteratorIsMutableConcept >(); typename std::iterator_traits::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 { // An MPL Random Access Sequence, whose elements are color tags }; \endcode */ template struct ColorSpaceConcept { void constraints() { // An MPL Random Access Sequence, whose elements are color tags } }; template // Models ColorSpaceConcept struct color_spaces_are_compatible : public is_same {}; /// \brief Two color spaces are compatible if they are the same /// \ingroup ColorSpaceAndLayoutConcept /** \code concept ColorSpacesCompatibleConcept { where SameType; }; \endcode */ template struct ColorSpacesCompatibleConcept { void constraints() { BOOST_STATIC_ASSERT((color_spaces_are_compatible::value)); } }; /// \brief Channel mapping concept /// \ingroup ColorSpaceAndLayoutConcept /** \code concept ChannelMappingConcept { // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation }; \endcode */ template 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 : EqualityComparable { typename value_type = T; // use channel_traits::value_type to access it typename reference = T&; // use channel_traits::reference to access it typename pointer = T*; // use channel_traits::pointer to access it typename const_reference = const T&; // use channel_traits::const_reference to access it typename const_pointer = const T*; // use channel_traits::const_pointer to access it static const bool is_mutable; // use channel_traits::is_mutable to access it static T min_value(); // use channel_traits::min_value to access it static T max_value(); // use channel_traits::min_value to access it }; \endcode */ template struct ChannelConcept { void constraints() { gil_function_requires< boost::EqualityComparableConcept >(); typedef typename channel_traits::value_type v; typedef typename channel_traits::reference r; typedef typename channel_traits::pointer p; typedef typename channel_traits::const_reference cr; typedef typename channel_traits::const_pointer cp; channel_traits::min_value(); channel_traits::max_value(); } T c; }; namespace detail { // Preconditions: T models ChannelConcept template struct ChannelIsMutableConcept { void constraints() { c=c; using std::swap; swap(c,c); } T c; }; } /// \brief A channel that allows for modifying its value /// \ingroup ChannelConcept /** \code concept MutableChannelConcept : Assignable, Swappable {}; \endcode */ template struct MutableChannelConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); } }; /// \brief A channel that supports default construction. /// \ingroup ChannelConcept /** \code concept ChannelValueConcept : Regular {}; \endcode */ template struct ChannelValueConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); } }; /// \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::value)); \endcode */ template // Models GIL Pixel struct channels_are_compatible : public is_same::value_type, typename channel_traits::value_type> {}; /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same /// \ingroup ChannelConcept /** \code concept ChannelsCompatibleConcept { where SameType; }; \endcode */ template struct ChannelsCompatibleConcept { void constraints() { BOOST_STATIC_ASSERT((channels_are_compatible::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 { DstChannel channel_convert(const SrcChannel&); }; \endcode */ template struct ChannelConvertibleConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); dst=channel_convert(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(ColorBase) function, which allows for accessing the elements based on their physical order. GIL provides a \p semantic_at_c(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns the corresponding semantic element. \code concept ColorBaseConcept : CopyConstructible, EqualityComparable { // a GIL layout (the color space and element permutation) typename layout_t; // The type of K-th element template struct kth_element_type; where Metafunction; // The result of at_c template struct kth_element_const_reference_type; where Metafunction; template kth_element_const_reference_type::type at_c(T); // Copy-constructible and equality comparable with other compatible color bases template where { ColorBasesCompatibleConcept } T::T(T2); template where { ColorBasesCompatibleConcept } bool operator==(const T&, const T2&); template where { ColorBasesCompatibleConcept } bool operator!=(const T&, const T2&); }; \endcode */ template struct ColorBaseConcept { void constraints() { gil_function_requires< CopyConstructible >(); gil_function_requires< EqualityComparable >(); typedef typename ColorBase::layout_t::color_space_t color_space_t; gil_function_requires >(); 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::value; typedef typename kth_element_type::type TN; typedef typename kth_element_const_reference_type::type CR; #if !defined(_MSC_VER) || _MSC_VER > 1310 CR cr=at_c(cb); ignore_unused_variable_warning(cr); #endif // functions that work for every pixel (no need to require them) semantic_at_c<0>(cb); semantic_at_c(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 : Assignable, Swappable { template struct kth_element_reference_type; where Metafunction; template kth_element_reference_type::type>::type at_c(T); template where { ColorBasesCompatibleConcept } T& operator=(T&, const T2&); }; \endcode */ template struct MutableColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); gil_function_requires< Assignable >(); gil_function_requires< Swappable >(); typedef typename kth_element_reference_type::type CR; #if !defined(_MSC_VER) || _MSC_VER > 1310 CR r=at_c<0>(cb); at_c<0>(cb)=r; #endif } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Color base that also has a default-constructor. Refines Regular /** \code concept ColorBaseValueConcept : MutableColorBaseConcept, Regular { }; \endcode */ template struct ColorBaseValueConcept { void constraints() { gil_function_requires< MutableColorBaseConcept >(); gil_function_requires< Regular >(); } }; /// \ingroup ColorBaseConcept /// \brief Color base whose elements all have the same type /** \code concept HomogeneousColorBaseConcept { // For all K in [0 ... size::value-1): // where SameType::type, kth_element_type::type>; kth_element_const_reference_type::type dynamic_at_c(const CB&, std::size_t n) const; }; \endcode */ template struct HomogeneousColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); static const std::size_t num_elements = size::value; typedef typename kth_element_type::type T0; typedef typename kth_element_type::type TN; BOOST_STATIC_ASSERT((is_same::value)); // better than nothing typedef typename kth_element_const_reference_type::type CR0; CR0 e0=dynamic_at_c(cb,0); } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Homogeneous color base that allows for modifying its elements /** \code concept MutableHomogeneousColorBaseConcept : HomogeneousColorBaseConcept { kth_element_reference_type::type dynamic_at_c(CB&, std::size_t n); }; \endcode */ template struct MutableHomogeneousColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); gil_function_requires< HomogeneousColorBaseConcept >(); typedef typename kth_element_reference_type::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 : MutableHomogeneousColorBaseConcept, Regular { }; \endcode */ template struct HomogeneousColorBaseValueConcept { void constraints() { gil_function_requires< MutableHomogeneousColorBaseConcept >(); gil_function_requires< Regular >(); } }; /// \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
& p); template struct bit_aligned_pixel_reference; template inline typename kth_element_reference_type, K>::type at_c(const bit_aligned_pixel_reference& p); #endif // Forward-declare semantic_at_c template typename disable_if,typename kth_semantic_element_reference_type::type>::type semantic_at_c(ColorBase& p); template typename kth_semantic_element_const_reference_type::type semantic_at_c(const ColorBase& p); template struct dynamic_x_step_type; template struct dynamic_y_step_type; template struct transposed_type; namespace detail { template void initialize_it(T& x) {} } // namespace detail template struct remove_const_and_reference : public remove_const::type> {}; #ifdef BOOST_GIL_USE_CONCEPT_CHECK #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept); template void gil_function_requires() { function_requires(); } #else #define GIL_CLASS_REQUIRE(T,NS,C) template void gil_function_requires() {} #endif /// \ingroup BasicConcepts /** \code auto concept DefaultConstructible { T::T(); }; \endcode */ template struct DefaultConstructible { void constraints() { function_requires >(); } }; /// \ingroup BasicConcepts /** \codeauto concept CopyConstructible { T::T(T); T::~T(); }; \endcode */ template struct CopyConstructible { void constraints() { function_requires >(); } }; /// \ingroup BasicConcepts /** \code auto concept Assignable { typename result_type; result_type operator=(T&, U); }; \endcode */ template struct Assignable { void constraints() { function_requires >(); } }; /// \ingroup BasicConcepts /** \code auto concept EqualityComparable { bool operator==(T x, T y); bool operator!=(T x, T y) { return !(x==y); } }; \endcode */ template struct EqualityComparable { void constraints() { function_requires >(); } }; /// \ingroup BasicConcepts /** \code concept SameType;// unspecified \endcode */ template struct SameType { void constraints() { BOOST_STATIC_ASSERT((boost::is_same::value_core)); } }; /// \ingroup BasicConcepts /** \code auto concept Swappable { void swap(T&,T&); }; \endcode */ template struct Swappable { void constraints() { using std::swap; swap(x,y); } T x,y; }; /// \ingroup BasicConcepts /** \code auto concept Regular : DefaultConstructible, CopyConstructible, EqualityComparable, Assignable, Swappable {}; \endcode */ template struct Regular { void constraints() { gil_function_requires< boost::DefaultConstructibleConcept >(); gil_function_requires< boost::CopyConstructibleConcept >(); gil_function_requires< boost::EqualityComparableConcept >(); // ==, != gil_function_requires< boost::AssignableConcept >(); gil_function_requires< Swappable >(); } }; /// \ingroup BasicConcepts /** \code auto concept Metafunction { typename type; }; \endcode */ template struct Metafunction { void constraints() { typedef typename T::type type; } }; //////////////////////////////////////////////////////////////////////////////////////// // // POINT CONCEPTS // //////////////////////////////////////////////////////////////////////////////////////// /// \brief N-dimensional point concept /// \ingroup PointConcept /** \code concept PointNDConcept : Regular { // the type of a coordinate along each axis template struct axis; where Metafunction; const size_t num_dimensions; // accessor/modifier of the value of each axis. template const typename axis::type& T::axis_value() const; template typename axis::type& T::axis_value(); }; \endcode */ template struct PointNDConcept { void constraints() { gil_function_requires< Regular >(); 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::coord_t LT; FT ft=gil::axis_value<0>(point); axis_value<0>(point)=ft; LT lt=axis_value(point); axis_value(point)=lt; value_type v=point[0]; ignore_unused_variable_warning(v); point[0]=point[0]; } P point; }; /// \brief 2-dimensional point concept /// \ingroup PointConcept /** \code concept Point2DConcept : PointNDConcept { where num_dimensions == 2; where SameType::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 struct Point2DConcept { void constraints() { gil_function_requires< PointNDConcept >(); 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 // Preconditions: TT Models boost_concepts::ForwardTraversalConcept struct ForwardIteratorIsMutableConcept { void constraints() { *i++ = *i; // require postincrement and assignment } TT i; }; template // Preconditions: TT Models boost::BidirectionalIteratorConcept struct BidirectionalIteratorIsMutableConcept { void constraints() { gil_function_requires< ForwardIteratorIsMutableConcept >(); *i-- = *i; // require postdecrement and assignment } TT i; }; template // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept struct RandomAccessIteratorIsMutableConcept { void constraints() { gil_function_requires< BidirectionalIteratorIsMutableConcept >(); typename std::iterator_traits::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 { // An MPL Random Access Sequence, whose elements are color tags }; \endcode */ template struct ColorSpaceConcept { void constraints() { // An MPL Random Access Sequence, whose elements are color tags } }; template // Models ColorSpaceConcept struct color_spaces_are_compatible : public is_same {}; /// \brief Two color spaces are compatible if they are the same /// \ingroup ColorSpaceAndLayoutConcept /** \code concept ColorSpacesCompatibleConcept { where SameType; }; \endcode */ template struct ColorSpacesCompatibleConcept { void constraints() { BOOST_STATIC_ASSERT((color_spaces_are_compatible::value)); } }; /// \brief Channel mapping concept /// \ingroup ColorSpaceAndLayoutConcept /** \code concept ChannelMappingConcept { // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation }; \endcode */ template 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 : EqualityComparable { typename value_type = T; // use channel_traits::value_type to access it typename reference = T&; // use channel_traits::reference to access it typename pointer = T*; // use channel_traits::pointer to access it typename const_reference = const T&; // use channel_traits::const_reference to access it typename const_pointer = const T*; // use channel_traits::const_pointer to access it static const bool is_mutable; // use channel_traits::is_mutable to access it static T min_value(); // use channel_traits::min_value to access it static T max_value(); // use channel_traits::min_value to access it }; \endcode */ template struct ChannelConcept { void constraints() { gil_function_requires< boost::EqualityComparableConcept >(); typedef typename channel_traits::value_type v; typedef typename channel_traits::reference r; typedef typename channel_traits::pointer p; typedef typename channel_traits::const_reference cr; typedef typename channel_traits::const_pointer cp; channel_traits::min_value(); channel_traits::max_value(); } T c; }; namespace detail { // Preconditions: T models ChannelConcept template struct ChannelIsMutableConcept { void constraints() { c=c; using std::swap; swap(c,c); } T c; }; } /// \brief A channel that allows for modifying its value /// \ingroup ChannelConcept /** \code concept MutableChannelConcept : Assignable, Swappable {}; \endcode */ template struct MutableChannelConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); } }; /// \brief A channel that supports default construction. /// \ingroup ChannelConcept /** \code concept ChannelValueConcept : Regular {}; \endcode */ template struct ChannelValueConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); } }; /// \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::value)); \endcode */ template // Models GIL Pixel struct channels_are_compatible : public is_same::value_type, typename channel_traits::value_type> {}; /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same /// \ingroup ChannelConcept /** \code concept ChannelsCompatibleConcept { where SameType; }; \endcode */ template struct ChannelsCompatibleConcept { void constraints() { BOOST_STATIC_ASSERT((channels_are_compatible::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 { DstChannel channel_convert(const SrcChannel&); }; \endcode */ template struct ChannelConvertibleConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); dst=channel_convert(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(ColorBase) function, which allows for accessing the elements based on their physical order. GIL provides a \p semantic_at_c(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns the corresponding semantic element. \code concept ColorBaseConcept : CopyConstructible, EqualityComparable { // a GIL layout (the color space and element permutation) typename layout_t; // The type of K-th element template struct kth_element_type; where Metafunction; // The result of at_c template struct kth_element_const_reference_type; where Metafunction; template kth_element_const_reference_type::type at_c(T); // Copy-constructible and equality comparable with other compatible color bases template where { ColorBasesCompatibleConcept } T::T(T2); template where { ColorBasesCompatibleConcept } bool operator==(const T&, const T2&); template where { ColorBasesCompatibleConcept } bool operator!=(const T&, const T2&); }; \endcode */ template struct ColorBaseConcept { void constraints() { gil_function_requires< CopyConstructible >(); gil_function_requires< EqualityComparable >(); typedef typename ColorBase::layout_t::color_space_t color_space_t; gil_function_requires >(); 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::value; typedef typename kth_element_type::type TN; typedef typename kth_element_const_reference_type::type CR; #if !defined(_MSC_VER) || _MSC_VER > 1310 CR cr=at_c(cb); ignore_unused_variable_warning(cr); #endif // functions that work for every pixel (no need to require them) semantic_at_c<0>(cb); semantic_at_c(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 : Assignable, Swappable { template struct kth_element_reference_type; where Metafunction; template kth_element_reference_type::type>::type at_c(T); template where { ColorBasesCompatibleConcept } T& operator=(T&, const T2&); }; \endcode */ template struct MutableColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); gil_function_requires< Assignable >(); gil_function_requires< Swappable >(); typedef typename kth_element_reference_type::type CR; #if !defined(_MSC_VER) || _MSC_VER > 1310 CR r=at_c<0>(cb); at_c<0>(cb)=r; #endif } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Color base that also has a default-constructor. Refines Regular /** \code concept ColorBaseValueConcept : MutableColorBaseConcept, Regular { }; \endcode */ template struct ColorBaseValueConcept { void constraints() { gil_function_requires< MutableColorBaseConcept >(); gil_function_requires< Regular >(); } }; /// \ingroup ColorBaseConcept /// \brief Color base whose elements all have the same type /** \code concept HomogeneousColorBaseConcept { // For all K in [0 ... size::value-1): // where SameType::type, kth_element_type::type>; kth_element_const_reference_type::type dynamic_at_c(const CB&, std::size_t n) const; }; \endcode */ template struct HomogeneousColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); static const std::size_t num_elements = size::value; typedef typename kth_element_type::type T0; typedef typename kth_element_type::type TN; BOOST_STATIC_ASSERT((is_same::value)); // better than nothing typedef typename kth_element_const_reference_type::type CR0; CR0 e0=dynamic_at_c(cb,0); } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Homogeneous color base that allows for modifying its elements /** \code concept MutableHomogeneousColorBaseConcept : HomogeneousColorBaseConcept { kth_element_reference_type::type dynamic_at_c(CB&, std::size_t n); }; \endcode */ template struct MutableHomogeneousColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); gil_function_requires< HomogeneousColorBaseConcept >(); typedef typename kth_element_reference_type::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 : MutableHomogeneousColorBaseConcept, Regular { }; \endcode */ template struct HomogeneousColorBaseValueConcept { void constraints() { gil_function_requires< MutableHomogeneousColorBaseConcept >(); gil_function_requires< Regular >(); } }; /// \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
>(); 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::coord_t LT; FT ft=gil::axis_value<0>(point); axis_value<0>(point)=ft; LT lt=axis_value(point); axis_value(point)=lt; value_type v=point[0]; ignore_unused_variable_warning(v); point[0]=point[0]; } P point; }; /// \brief 2-dimensional point concept /// \ingroup PointConcept /** \code concept Point2DConcept : PointNDConcept { where num_dimensions == 2; where SameType::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 struct Point2DConcept { void constraints() { gil_function_requires< PointNDConcept >(); 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 // Preconditions: TT Models boost_concepts::ForwardTraversalConcept struct ForwardIteratorIsMutableConcept { void constraints() { *i++ = *i; // require postincrement and assignment } TT i; }; template // Preconditions: TT Models boost::BidirectionalIteratorConcept struct BidirectionalIteratorIsMutableConcept { void constraints() { gil_function_requires< ForwardIteratorIsMutableConcept >(); *i-- = *i; // require postdecrement and assignment } TT i; }; template // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept struct RandomAccessIteratorIsMutableConcept { void constraints() { gil_function_requires< BidirectionalIteratorIsMutableConcept >(); typename std::iterator_traits::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 { // An MPL Random Access Sequence, whose elements are color tags }; \endcode */ template struct ColorSpaceConcept { void constraints() { // An MPL Random Access Sequence, whose elements are color tags } }; template // Models ColorSpaceConcept struct color_spaces_are_compatible : public is_same {}; /// \brief Two color spaces are compatible if they are the same /// \ingroup ColorSpaceAndLayoutConcept /** \code concept ColorSpacesCompatibleConcept { where SameType; }; \endcode */ template struct ColorSpacesCompatibleConcept { void constraints() { BOOST_STATIC_ASSERT((color_spaces_are_compatible::value)); } }; /// \brief Channel mapping concept /// \ingroup ColorSpaceAndLayoutConcept /** \code concept ChannelMappingConcept { // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation }; \endcode */ template 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 : EqualityComparable { typename value_type = T; // use channel_traits::value_type to access it typename reference = T&; // use channel_traits::reference to access it typename pointer = T*; // use channel_traits::pointer to access it typename const_reference = const T&; // use channel_traits::const_reference to access it typename const_pointer = const T*; // use channel_traits::const_pointer to access it static const bool is_mutable; // use channel_traits::is_mutable to access it static T min_value(); // use channel_traits::min_value to access it static T max_value(); // use channel_traits::min_value to access it }; \endcode */ template struct ChannelConcept { void constraints() { gil_function_requires< boost::EqualityComparableConcept >(); typedef typename channel_traits::value_type v; typedef typename channel_traits::reference r; typedef typename channel_traits::pointer p; typedef typename channel_traits::const_reference cr; typedef typename channel_traits::const_pointer cp; channel_traits::min_value(); channel_traits::max_value(); } T c; }; namespace detail { // Preconditions: T models ChannelConcept template struct ChannelIsMutableConcept { void constraints() { c=c; using std::swap; swap(c,c); } T c; }; } /// \brief A channel that allows for modifying its value /// \ingroup ChannelConcept /** \code concept MutableChannelConcept : Assignable, Swappable {}; \endcode */ template struct MutableChannelConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); } }; /// \brief A channel that supports default construction. /// \ingroup ChannelConcept /** \code concept ChannelValueConcept : Regular {}; \endcode */ template struct ChannelValueConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); } }; /// \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::value)); \endcode */ template // Models GIL Pixel struct channels_are_compatible : public is_same::value_type, typename channel_traits::value_type> {}; /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same /// \ingroup ChannelConcept /** \code concept ChannelsCompatibleConcept { where SameType; }; \endcode */ template struct ChannelsCompatibleConcept { void constraints() { BOOST_STATIC_ASSERT((channels_are_compatible::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 { DstChannel channel_convert(const SrcChannel&); }; \endcode */ template struct ChannelConvertibleConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); dst=channel_convert(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(ColorBase) function, which allows for accessing the elements based on their physical order. GIL provides a \p semantic_at_c(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns the corresponding semantic element. \code concept ColorBaseConcept : CopyConstructible, EqualityComparable { // a GIL layout (the color space and element permutation) typename layout_t; // The type of K-th element template struct kth_element_type; where Metafunction; // The result of at_c template struct kth_element_const_reference_type; where Metafunction; template kth_element_const_reference_type::type at_c(T); // Copy-constructible and equality comparable with other compatible color bases template where { ColorBasesCompatibleConcept } T::T(T2); template where { ColorBasesCompatibleConcept } bool operator==(const T&, const T2&); template where { ColorBasesCompatibleConcept } bool operator!=(const T&, const T2&); }; \endcode */ template struct ColorBaseConcept { void constraints() { gil_function_requires< CopyConstructible >(); gil_function_requires< EqualityComparable >(); typedef typename ColorBase::layout_t::color_space_t color_space_t; gil_function_requires >(); 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::value; typedef typename kth_element_type::type TN; typedef typename kth_element_const_reference_type::type CR; #if !defined(_MSC_VER) || _MSC_VER > 1310 CR cr=at_c(cb); ignore_unused_variable_warning(cr); #endif // functions that work for every pixel (no need to require them) semantic_at_c<0>(cb); semantic_at_c(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 : Assignable, Swappable { template struct kth_element_reference_type; where Metafunction; template kth_element_reference_type::type>::type at_c(T); template where { ColorBasesCompatibleConcept } T& operator=(T&, const T2&); }; \endcode */ template struct MutableColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); gil_function_requires< Assignable >(); gil_function_requires< Swappable >(); typedef typename kth_element_reference_type::type CR; #if !defined(_MSC_VER) || _MSC_VER > 1310 CR r=at_c<0>(cb); at_c<0>(cb)=r; #endif } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Color base that also has a default-constructor. Refines Regular /** \code concept ColorBaseValueConcept : MutableColorBaseConcept, Regular { }; \endcode */ template struct ColorBaseValueConcept { void constraints() { gil_function_requires< MutableColorBaseConcept >(); gil_function_requires< Regular >(); } }; /// \ingroup ColorBaseConcept /// \brief Color base whose elements all have the same type /** \code concept HomogeneousColorBaseConcept { // For all K in [0 ... size::value-1): // where SameType::type, kth_element_type::type>; kth_element_const_reference_type::type dynamic_at_c(const CB&, std::size_t n) const; }; \endcode */ template struct HomogeneousColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); static const std::size_t num_elements = size::value; typedef typename kth_element_type::type T0; typedef typename kth_element_type::type TN; BOOST_STATIC_ASSERT((is_same::value)); // better than nothing typedef typename kth_element_const_reference_type::type CR0; CR0 e0=dynamic_at_c(cb,0); } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Homogeneous color base that allows for modifying its elements /** \code concept MutableHomogeneousColorBaseConcept : HomogeneousColorBaseConcept { kth_element_reference_type::type dynamic_at_c(CB&, std::size_t n); }; \endcode */ template struct MutableHomogeneousColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); gil_function_requires< HomogeneousColorBaseConcept >(); typedef typename kth_element_reference_type::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 : MutableHomogeneousColorBaseConcept, Regular { }; \endcode */ template struct HomogeneousColorBaseValueConcept { void constraints() { gil_function_requires< MutableHomogeneousColorBaseConcept >(); gil_function_requires< Regular >(); } }; /// \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
>(); 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 // Preconditions: TT Models boost_concepts::ForwardTraversalConcept struct ForwardIteratorIsMutableConcept { void constraints() { *i++ = *i; // require postincrement and assignment } TT i; }; template // Preconditions: TT Models boost::BidirectionalIteratorConcept struct BidirectionalIteratorIsMutableConcept { void constraints() { gil_function_requires< ForwardIteratorIsMutableConcept >(); *i-- = *i; // require postdecrement and assignment } TT i; }; template // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept struct RandomAccessIteratorIsMutableConcept { void constraints() { gil_function_requires< BidirectionalIteratorIsMutableConcept >(); typename std::iterator_traits::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 { // An MPL Random Access Sequence, whose elements are color tags }; \endcode */ template struct ColorSpaceConcept { void constraints() { // An MPL Random Access Sequence, whose elements are color tags } }; template // Models ColorSpaceConcept struct color_spaces_are_compatible : public is_same {}; /// \brief Two color spaces are compatible if they are the same /// \ingroup ColorSpaceAndLayoutConcept /** \code concept ColorSpacesCompatibleConcept { where SameType; }; \endcode */ template struct ColorSpacesCompatibleConcept { void constraints() { BOOST_STATIC_ASSERT((color_spaces_are_compatible::value)); } }; /// \brief Channel mapping concept /// \ingroup ColorSpaceAndLayoutConcept /** \code concept ChannelMappingConcept { // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation }; \endcode */ template 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 : EqualityComparable { typename value_type = T; // use channel_traits::value_type to access it typename reference = T&; // use channel_traits::reference to access it typename pointer = T*; // use channel_traits::pointer to access it typename const_reference = const T&; // use channel_traits::const_reference to access it typename const_pointer = const T*; // use channel_traits::const_pointer to access it static const bool is_mutable; // use channel_traits::is_mutable to access it static T min_value(); // use channel_traits::min_value to access it static T max_value(); // use channel_traits::min_value to access it }; \endcode */ template struct ChannelConcept { void constraints() { gil_function_requires< boost::EqualityComparableConcept >(); typedef typename channel_traits::value_type v; typedef typename channel_traits::reference r; typedef typename channel_traits::pointer p; typedef typename channel_traits::const_reference cr; typedef typename channel_traits::const_pointer cp; channel_traits::min_value(); channel_traits::max_value(); } T c; }; namespace detail { // Preconditions: T models ChannelConcept template struct ChannelIsMutableConcept { void constraints() { c=c; using std::swap; swap(c,c); } T c; }; } /// \brief A channel that allows for modifying its value /// \ingroup ChannelConcept /** \code concept MutableChannelConcept : Assignable, Swappable {}; \endcode */ template struct MutableChannelConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); } }; /// \brief A channel that supports default construction. /// \ingroup ChannelConcept /** \code concept ChannelValueConcept : Regular {}; \endcode */ template struct ChannelValueConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); } }; /// \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::value)); \endcode */ template // Models GIL Pixel struct channels_are_compatible : public is_same::value_type, typename channel_traits::value_type> {}; /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same /// \ingroup ChannelConcept /** \code concept ChannelsCompatibleConcept { where SameType; }; \endcode */ template struct ChannelsCompatibleConcept { void constraints() { BOOST_STATIC_ASSERT((channels_are_compatible::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 { DstChannel channel_convert(const SrcChannel&); }; \endcode */ template struct ChannelConvertibleConcept { void constraints() { gil_function_requires >(); gil_function_requires >(); dst=channel_convert(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(ColorBase) function, which allows for accessing the elements based on their physical order. GIL provides a \p semantic_at_c(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns the corresponding semantic element. \code concept ColorBaseConcept : CopyConstructible, EqualityComparable { // a GIL layout (the color space and element permutation) typename layout_t; // The type of K-th element template struct kth_element_type; where Metafunction; // The result of at_c template struct kth_element_const_reference_type; where Metafunction; template kth_element_const_reference_type::type at_c(T); // Copy-constructible and equality comparable with other compatible color bases template where { ColorBasesCompatibleConcept } T::T(T2); template where { ColorBasesCompatibleConcept } bool operator==(const T&, const T2&); template where { ColorBasesCompatibleConcept } bool operator!=(const T&, const T2&); }; \endcode */ template struct ColorBaseConcept { void constraints() { gil_function_requires< CopyConstructible >(); gil_function_requires< EqualityComparable >(); typedef typename ColorBase::layout_t::color_space_t color_space_t; gil_function_requires >(); 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::value; typedef typename kth_element_type::type TN; typedef typename kth_element_const_reference_type::type CR; #if !defined(_MSC_VER) || _MSC_VER > 1310 CR cr=at_c(cb); ignore_unused_variable_warning(cr); #endif // functions that work for every pixel (no need to require them) semantic_at_c<0>(cb); semantic_at_c(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 : Assignable, Swappable { template struct kth_element_reference_type; where Metafunction; template kth_element_reference_type::type>::type at_c(T); template where { ColorBasesCompatibleConcept } T& operator=(T&, const T2&); }; \endcode */ template struct MutableColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); gil_function_requires< Assignable >(); gil_function_requires< Swappable >(); typedef typename kth_element_reference_type::type CR; #if !defined(_MSC_VER) || _MSC_VER > 1310 CR r=at_c<0>(cb); at_c<0>(cb)=r; #endif } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Color base that also has a default-constructor. Refines Regular /** \code concept ColorBaseValueConcept : MutableColorBaseConcept, Regular { }; \endcode */ template struct ColorBaseValueConcept { void constraints() { gil_function_requires< MutableColorBaseConcept >(); gil_function_requires< Regular >(); } }; /// \ingroup ColorBaseConcept /// \brief Color base whose elements all have the same type /** \code concept HomogeneousColorBaseConcept { // For all K in [0 ... size::value-1): // where SameType::type, kth_element_type::type>; kth_element_const_reference_type::type dynamic_at_c(const CB&, std::size_t n) const; }; \endcode */ template struct HomogeneousColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); static const std::size_t num_elements = size::value; typedef typename kth_element_type::type T0; typedef typename kth_element_type::type TN; BOOST_STATIC_ASSERT((is_same::value)); // better than nothing typedef typename kth_element_const_reference_type::type CR0; CR0 e0=dynamic_at_c(cb,0); } ColorBase cb; }; /// \ingroup ColorBaseConcept /// \brief Homogeneous color base that allows for modifying its elements /** \code concept MutableHomogeneousColorBaseConcept : HomogeneousColorBaseConcept { kth_element_reference_type::type dynamic_at_c(CB&, std::size_t n); }; \endcode */ template struct MutableHomogeneousColorBaseConcept { void constraints() { gil_function_requires< ColorBaseConcept >(); gil_function_requires< HomogeneousColorBaseConcept >(); typedef typename kth_element_reference_type::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 : MutableHomogeneousColorBaseConcept, Regular { }; \endcode */ template struct HomogeneousColorBaseValueConcept { void constraints() { gil_function_requires< MutableHomogeneousColorBaseConcept >(); gil_function_requires< Regular >(); } }; /// \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