Chris@16: /* Chris@16: Copyright 2005-2007 Adobe Systems Incorporated Chris@16: Chris@16: Use, modification and distribution are subject to the Boost Software License, Chris@16: Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: Chris@16: See http://opensource.adobe.com/gil for most recent version including documentation. Chris@16: */ Chris@16: Chris@16: /*************************************************************************************************/ Chris@16: Chris@16: #ifndef GIL_CONCEPT_H Chris@16: #define GIL_CONCEPT_H Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file Chris@16: /// \brief Concept check classes for GIL concepts Chris@16: /// \author Lubomir Bourdev and Hailin Jin \n Chris@16: /// Adobe Systems Incorporated Chris@16: /// \date 2005-2007 \n Last updated on February 12, 2007 Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #include Chris@16: #include "gil_config.hpp" Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace gil { Chris@16: template struct channel_traits; Chris@16: template struct is_pixel; Chris@16: template Chris@16: typename channel_traits::value_type channel_convert(const srcT& val); Chris@16: template class point2; Chris@16: template const T& axis_value(const point2& p); Chris@16: template T& axis_value( point2& p); Chris@16: template struct kth_element_type; Chris@16: template struct kth_element_reference_type; Chris@16: template struct kth_element_const_reference_type; Chris@16: template struct kth_semantic_element_reference_type; Chris@16: template struct kth_semantic_element_const_reference_type; Chris@16: template struct size; Chris@16: template struct element_type; Chris@16: template struct channel_type; Chris@16: template struct color_space_type; Chris@16: template struct channel_mapping_type; Chris@16: template struct is_planar; Chris@16: template struct num_channels; Chris@16: Chris@16: template struct const_iterator_type; Chris@16: template struct iterator_is_mutable; Chris@16: template struct is_iterator_adaptor; Chris@16: template struct iterator_adaptor_rebind; Chris@16: template struct iterator_adaptor_get_base; Chris@16: Chris@16: Chris@16: // forward-declare at_c Chris@16: namespace detail { template struct homogeneous_color_base; } Chris@16: template Chris@16: typename add_reference::type at_c( detail::homogeneous_color_base& p); Chris@16: Chris@16: template Chris@16: typename add_reference::type>::type at_c(const detail::homogeneous_color_base& p); Chris@16: Chris@16: #if !defined(_MSC_VER) || _MSC_VER > 1310 Chris@16: template struct packed_pixel; Chris@16: template Chris@16: typename kth_element_reference_type, K>::type Chris@16: at_c(packed_pixel& p); Chris@16: Chris@16: template Chris@16: typename kth_element_const_reference_type,K>::type Chris@16: at_c(const packed_pixel& p); Chris@16: Chris@16: template struct bit_aligned_pixel_reference; Chris@16: Chris@16: template inline Chris@16: typename kth_element_reference_type, K>::type Chris@16: at_c(const bit_aligned_pixel_reference& p); Chris@16: #endif Chris@16: Chris@16: // Forward-declare semantic_at_c Chris@16: template Chris@16: typename disable_if,typename kth_semantic_element_reference_type::type>::type semantic_at_c(ColorBase& p); Chris@16: template Chris@16: typename kth_semantic_element_const_reference_type::type semantic_at_c(const ColorBase& p); Chris@16: Chris@16: template struct dynamic_x_step_type; Chris@16: template struct dynamic_y_step_type; Chris@16: template struct transposed_type; Chris@16: Chris@16: namespace detail { Chris@16: template Chris@16: void initialize_it(T& x) {} Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: struct remove_const_and_reference : public remove_const::type> {}; Chris@16: Chris@16: #ifdef BOOST_GIL_USE_CONCEPT_CHECK Chris@16: #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept); Chris@16: template void gil_function_requires() { function_requires(); } Chris@16: #else Chris@16: #define GIL_CLASS_REQUIRE(T,NS,C) Chris@16: template void gil_function_requires() {} Chris@16: #endif Chris@16: Chris@16: /// \ingroup BasicConcepts Chris@16: /** Chris@16: \code Chris@16: auto concept DefaultConstructible { Chris@16: T::T(); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct DefaultConstructible { Chris@16: void constraints() { Chris@16: function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup BasicConcepts Chris@16: /** Chris@16: \codeauto concept CopyConstructible { Chris@16: T::T(T); Chris@16: T::~T(); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct CopyConstructible { Chris@16: void constraints() { Chris@16: function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup BasicConcepts Chris@16: /** Chris@16: \code Chris@16: auto concept Assignable { Chris@16: typename result_type; Chris@16: result_type operator=(T&, U); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct Assignable { Chris@16: void constraints() { Chris@16: function_requires >(); Chris@16: } Chris@16: }; Chris@16: /// \ingroup BasicConcepts Chris@16: /** Chris@16: \code Chris@16: auto concept EqualityComparable { Chris@16: bool operator==(T x, T y); Chris@16: bool operator!=(T x, T y) { return !(x==y); } Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct EqualityComparable { Chris@16: void constraints() { Chris@16: function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup BasicConcepts Chris@16: /** Chris@16: \code Chris@16: concept SameType;// unspecified Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct SameType { Chris@16: void constraints() { Chris@16: BOOST_STATIC_ASSERT((boost::is_same::value_core)); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup BasicConcepts Chris@16: /** Chris@16: \code Chris@16: auto concept Swappable { Chris@16: void swap(T&,T&); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct Swappable { Chris@16: void constraints() { Chris@16: using std::swap; Chris@16: swap(x,y); Chris@16: } Chris@16: T x,y; Chris@16: }; Chris@16: Chris@16: /// \ingroup BasicConcepts Chris@16: /** Chris@16: \code Chris@16: auto concept Regular : DefaultConstructible, CopyConstructible, EqualityComparable, Chris@16: Assignable, Swappable {}; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct Regular { Chris@16: void constraints() { Chris@16: gil_function_requires< boost::DefaultConstructibleConcept >(); Chris@16: gil_function_requires< boost::CopyConstructibleConcept >(); Chris@16: gil_function_requires< boost::EqualityComparableConcept >(); // ==, != Chris@16: gil_function_requires< boost::AssignableConcept >(); Chris@16: gil_function_requires< Swappable >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup BasicConcepts Chris@16: /** Chris@16: \code Chris@16: auto concept Metafunction { Chris@16: typename type; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct Metafunction { Chris@16: void constraints() { Chris@16: typedef typename T::type type; Chris@16: } Chris@16: }; Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // POINT CONCEPTS Chris@16: // Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \brief N-dimensional point concept Chris@16: /// \ingroup PointConcept Chris@16: /** Chris@16: \code Chris@16: concept PointNDConcept : Regular { Chris@16: // the type of a coordinate along each axis Chris@16: template struct axis; where Metafunction; Chris@16: Chris@16: const size_t num_dimensions; Chris@16: Chris@16: // accessor/modifier of the value of each axis. Chris@16: template const typename axis::type& T::axis_value() const; Chris@16: template typename axis::type& T::axis_value(); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct PointNDConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< Regular

>(); Chris@16: Chris@16: typedef typename P::value_type value_type; Chris@16: static const std::size_t N=P::num_dimensions; ignore_unused_variable_warning(N); Chris@16: typedef typename P::template axis<0>::coord_t FT; Chris@16: typedef typename P::template axis::coord_t LT; Chris@16: FT ft=gil::axis_value<0>(point); Chris@16: axis_value<0>(point)=ft; Chris@16: LT lt=axis_value(point); Chris@16: axis_value(point)=lt; Chris@16: Chris@16: value_type v=point[0]; ignore_unused_variable_warning(v); Chris@16: point[0]=point[0]; Chris@16: } Chris@16: P point; Chris@16: }; Chris@16: Chris@16: /// \brief 2-dimensional point concept Chris@16: /// \ingroup PointConcept Chris@16: /** Chris@16: \code Chris@16: concept Point2DConcept : PointNDConcept { Chris@16: where num_dimensions == 2; Chris@16: where SameType::type, axis<1>::type>; Chris@16: Chris@16: typename value_type = axis<0>::type; Chris@16: Chris@16: const value_type& operator[](const T&, size_t i); Chris@16: value_type& operator[]( T&, size_t i); Chris@16: Chris@16: value_type x,y; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct Point2DConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< PointNDConcept

>(); Chris@16: BOOST_STATIC_ASSERT(P::num_dimensions == 2); Chris@16: point.x=point.y; Chris@16: point[0]=point[1]; Chris@16: } Chris@16: P point; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // ITERATOR MUTABILITY CONCEPTS Chris@16: // Chris@16: // Taken from boost's concept_check.hpp. Isolating mutability to result in faster compile time Chris@16: // Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: namespace detail { Chris@16: template // Preconditions: TT Models boost_concepts::ForwardTraversalConcept Chris@16: struct ForwardIteratorIsMutableConcept { Chris@16: void constraints() { Chris@16: *i++ = *i; // require postincrement and assignment Chris@16: } Chris@16: TT i; Chris@16: }; Chris@16: Chris@16: template // Preconditions: TT Models boost::BidirectionalIteratorConcept Chris@16: struct BidirectionalIteratorIsMutableConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< ForwardIteratorIsMutableConcept >(); Chris@16: *i-- = *i; // require postdecrement and assignment Chris@16: } Chris@16: TT i; Chris@16: }; Chris@16: Chris@16: template // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept Chris@16: struct RandomAccessIteratorIsMutableConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< BidirectionalIteratorIsMutableConcept >(); Chris@16: typename std::iterator_traits::difference_type n=0; ignore_unused_variable_warning(n); Chris@16: i[n] = *i; // require element access and assignment Chris@16: } Chris@16: TT i; Chris@16: }; Chris@16: } // namespace detail Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // COLOR SPACE CONCEPTS Chris@16: // Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \brief Color space type concept Chris@16: /// \ingroup ColorSpaceAndLayoutConcept Chris@16: /** Chris@16: \code Chris@16: concept ColorSpaceConcept { Chris@16: // An MPL Random Access Sequence, whose elements are color tags Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ColorSpaceConcept { Chris@16: void constraints() { Chris@16: // An MPL Random Access Sequence, whose elements are color tags Chris@16: } Chris@16: }; Chris@16: Chris@16: template // Models ColorSpaceConcept Chris@16: struct color_spaces_are_compatible : public is_same {}; Chris@16: Chris@16: /// \brief Two color spaces are compatible if they are the same Chris@16: /// \ingroup ColorSpaceAndLayoutConcept Chris@16: /** Chris@16: \code Chris@16: concept ColorSpacesCompatibleConcept { Chris@16: where SameType; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ColorSpacesCompatibleConcept { Chris@16: void constraints() { Chris@16: BOOST_STATIC_ASSERT((color_spaces_are_compatible::value)); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief Channel mapping concept Chris@16: /// \ingroup ColorSpaceAndLayoutConcept Chris@16: /** Chris@16: \code Chris@16: concept ChannelMappingConcept { Chris@16: // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ChannelMappingConcept { Chris@16: void constraints() { Chris@16: // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// Channel CONCEPTS Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \ingroup ChannelConcept Chris@16: /// \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. Chris@16: /** Chris@16: 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. Chris@16: Chris@16: 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. Chris@16: In such cases special classes are needed to represent the value and reference to a channel. Chris@16: Chris@16: Channels have a traits class, \p channel_traits, which defines their associated types as well as their operating ranges. Chris@16: Chris@16: \code Chris@16: concept ChannelConcept : EqualityComparable { Chris@16: typename value_type = T; // use channel_traits::value_type to access it Chris@16: typename reference = T&; // use channel_traits::reference to access it Chris@16: typename pointer = T*; // use channel_traits::pointer to access it Chris@16: typename const_reference = const T&; // use channel_traits::const_reference to access it Chris@16: typename const_pointer = const T*; // use channel_traits::const_pointer to access it Chris@16: static const bool is_mutable; // use channel_traits::is_mutable to access it Chris@16: Chris@16: static T min_value(); // use channel_traits::min_value to access it Chris@16: static T max_value(); // use channel_traits::min_value to access it Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ChannelConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< boost::EqualityComparableConcept >(); Chris@16: Chris@16: typedef typename channel_traits::value_type v; Chris@16: typedef typename channel_traits::reference r; Chris@16: typedef typename channel_traits::pointer p; Chris@16: typedef typename channel_traits::const_reference cr; Chris@16: typedef typename channel_traits::const_pointer cp; Chris@16: Chris@16: channel_traits::min_value(); Chris@16: channel_traits::max_value(); Chris@16: } Chris@16: Chris@16: T c; Chris@16: }; Chris@16: Chris@16: namespace detail { Chris@16: // Preconditions: T models ChannelConcept Chris@16: template Chris@16: struct ChannelIsMutableConcept { Chris@16: void constraints() { Chris@16: c=c; Chris@16: using std::swap; Chris@16: swap(c,c); Chris@16: } Chris@16: T c; Chris@16: }; Chris@16: } Chris@16: Chris@16: /// \brief A channel that allows for modifying its value Chris@16: /// \ingroup ChannelConcept Chris@16: /** Chris@16: \code Chris@16: concept MutableChannelConcept : Assignable, Swappable {}; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableChannelConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief A channel that supports default construction. Chris@16: /// \ingroup ChannelConcept Chris@16: /** Chris@16: \code Chris@16: concept ChannelValueConcept : Regular {}; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ChannelValueConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: /// \brief Predicate metafunction returning whether two channels are compatible Chris@16: /// \ingroup ChannelAlgorithm Chris@16: /// Chris@16: /// Channels are considered compatible if their value types (ignoring constness and references) are the same. Chris@16: /** Chris@16: Example: Chris@16: Chris@16: \code Chris@16: BOOST_STATIC_ASSERT((channels_are_compatible::value)); Chris@16: \endcode Chris@16: */ Chris@16: template // Models GIL Pixel Chris@16: struct channels_are_compatible Chris@16: : public is_same::value_type, typename channel_traits::value_type> {}; Chris@16: Chris@16: /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same Chris@16: /// \ingroup ChannelConcept Chris@16: /** Chris@16: \code Chris@16: concept ChannelsCompatibleConcept { Chris@16: where SameType; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ChannelsCompatibleConcept { Chris@16: void constraints() { Chris@16: BOOST_STATIC_ASSERT((channels_are_compatible::value)); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels Chris@16: /// Chris@16: /// Convertibility is non-symmetric and implies that one channel can be converted to another. Conversion is explicit and often lossy operation. Chris@16: /// \ingroup ChannelConcept Chris@16: /** Chris@16: \code Chris@16: concept ChannelConvertibleConcept { Chris@16: DstChannel channel_convert(const SrcChannel&); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ChannelConvertibleConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: dst=channel_convert(src); ignore_unused_variable_warning(dst); Chris@16: } Chris@16: SrcChannel src; Chris@16: DstChannel dst; Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// COLOR BASE CONCEPTS Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \ingroup ColorBaseConcept Chris@16: /// \brief A color base is a container of color elements (such as channels, channel references or channel pointers) Chris@16: /** Chris@16: The most common use of color base is in the implementation of a pixel, in which case the color Chris@16: 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 Chris@16: 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 Chris@16: whose elements are channel iterators. Chris@16: Chris@16: A color base must have an associated layout (which consists of a color space, as well as an ordering of the channels). Chris@16: 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 Chris@16: a semantic index corresponds to the way the elements are ordered in their color space. Chris@16: 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 Chris@16: in physical ordering is the blue element, whereas the first semantic element is the red one. Chris@16: Models of \p ColorBaseConcept are required to provide the \p at_c(ColorBase) function, which allows for accessing the elements based on their Chris@16: physical order. GIL provides a \p semantic_at_c(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns Chris@16: the corresponding semantic element. Chris@16: Chris@16: \code Chris@16: concept ColorBaseConcept : CopyConstructible, EqualityComparable { Chris@16: // a GIL layout (the color space and element permutation) Chris@16: typename layout_t; Chris@16: Chris@16: // The type of K-th element Chris@16: template struct kth_element_type; where Metafunction; Chris@16: Chris@16: // The result of at_c Chris@16: template struct kth_element_const_reference_type; where Metafunction; Chris@16: Chris@16: template kth_element_const_reference_type::type at_c(T); Chris@16: Chris@16: // Copy-constructible and equality comparable with other compatible color bases Chris@16: template where { ColorBasesCompatibleConcept } Chris@16: T::T(T2); Chris@16: template where { ColorBasesCompatibleConcept } Chris@16: bool operator==(const T&, const T2&); Chris@16: template where { ColorBasesCompatibleConcept } Chris@16: bool operator!=(const T&, const T2&); Chris@16: Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct ColorBaseConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< CopyConstructible >(); Chris@16: gil_function_requires< EqualityComparable >(); Chris@16: Chris@16: typedef typename ColorBase::layout_t::color_space_t color_space_t; Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename ColorBase::layout_t::channel_mapping_t channel_mapping_t; Chris@16: // TODO: channel_mapping_t must be an MPL RandomAccessSequence Chris@16: Chris@16: static const std::size_t num_elements = size::value; Chris@16: Chris@16: typedef typename kth_element_type::type TN; Chris@16: typedef typename kth_element_const_reference_type::type CR; Chris@16: Chris@16: #if !defined(_MSC_VER) || _MSC_VER > 1310 Chris@16: CR cr=at_c(cb); ignore_unused_variable_warning(cr); Chris@16: #endif Chris@16: Chris@16: // functions that work for every pixel (no need to require them) Chris@16: semantic_at_c<0>(cb); Chris@16: semantic_at_c(cb); Chris@16: // also static_max(cb), static_min(cb), static_fill(cb,value), and all variations of static_for_each(), static_generate(), static_transform() Chris@16: } Chris@16: Chris@16: ColorBase cb; Chris@16: }; Chris@16: Chris@16: /// \ingroup ColorBaseConcept Chris@16: /// \brief Color base which allows for modifying its elements Chris@16: /** Chris@16: Chris@16: \code Chris@16: concept MutableColorBaseConcept : Assignable, Swappable { Chris@16: template struct kth_element_reference_type; where Metafunction; Chris@16: Chris@16: template kth_element_reference_type::type>::type at_c(T); Chris@16: Chris@16: template where { ColorBasesCompatibleConcept } Chris@16: T& operator=(T&, const T2&); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableColorBaseConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< ColorBaseConcept >(); Chris@16: gil_function_requires< Assignable >(); Chris@16: gil_function_requires< Swappable >(); Chris@16: Chris@16: typedef typename kth_element_reference_type::type CR; Chris@16: Chris@16: #if !defined(_MSC_VER) || _MSC_VER > 1310 Chris@16: CR r=at_c<0>(cb); Chris@16: at_c<0>(cb)=r; Chris@16: #endif Chris@16: } Chris@16: Chris@16: ColorBase cb; Chris@16: }; Chris@16: Chris@16: /// \ingroup ColorBaseConcept Chris@16: /// \brief Color base that also has a default-constructor. Refines Regular Chris@16: /** Chris@16: \code Chris@16: concept ColorBaseValueConcept : MutableColorBaseConcept, Regular { Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ColorBaseValueConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< MutableColorBaseConcept >(); Chris@16: gil_function_requires< Regular >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup ColorBaseConcept Chris@16: /// \brief Color base whose elements all have the same type Chris@16: /** Chris@16: \code Chris@16: concept HomogeneousColorBaseConcept { Chris@16: // For all K in [0 ... size::value-1): Chris@16: // where SameType::type, kth_element_type::type>; Chris@16: kth_element_const_reference_type::type dynamic_at_c(const CB&, std::size_t n) const; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct HomogeneousColorBaseConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< ColorBaseConcept >(); Chris@16: Chris@16: static const std::size_t num_elements = size::value; Chris@16: Chris@16: typedef typename kth_element_type::type T0; Chris@16: typedef typename kth_element_type::type TN; Chris@16: Chris@16: BOOST_STATIC_ASSERT((is_same::value)); // better than nothing Chris@16: typedef typename kth_element_const_reference_type::type CRef0; Chris@16: CRef0 e0=dynamic_at_c(cb,0); Chris@16: } Chris@16: ColorBase cb; Chris@16: }; Chris@16: Chris@16: /// \ingroup ColorBaseConcept Chris@16: /// \brief Homogeneous color base that allows for modifying its elements Chris@16: /** Chris@16: Chris@16: \code Chris@16: concept MutableHomogeneousColorBaseConcept : HomogeneousColorBaseConcept { Chris@16: kth_element_reference_type::type dynamic_at_c(CB&, std::size_t n); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct MutableHomogeneousColorBaseConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< ColorBaseConcept >(); Chris@16: gil_function_requires< HomogeneousColorBaseConcept >(); Chris@16: typedef typename kth_element_reference_type::type R0; Chris@16: R0 x=dynamic_at_c(cb,0); Chris@16: dynamic_at_c(cb,0) = dynamic_at_c(cb,0); Chris@16: } Chris@16: ColorBase cb; Chris@16: }; Chris@16: Chris@16: /// \ingroup ColorBaseConcept Chris@16: /// \brief Homogeneous color base that also has a default constructor. Refines Regular. Chris@16: /** Chris@16: Chris@16: \code Chris@16: concept HomogeneousColorBaseValueConcept : MutableHomogeneousColorBaseConcept, Regular { Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct HomogeneousColorBaseValueConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< MutableHomogeneousColorBaseConcept >(); Chris@16: gil_function_requires< Regular >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: /// \ingroup ColorBaseConcept Chris@16: /// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise. Chris@16: /** Chris@16: Chris@16: \code Chris@16: concept ColorBasesCompatibleConcept { Chris@16: where SameType; Chris@16: // also, for all K in [0 ... size::value): Chris@16: // where Convertible::type, kth_semantic_element_type::type>; Chris@16: // where Convertible::type, kth_semantic_element_type::type>; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ColorBasesCompatibleConcept { Chris@16: void constraints() { Chris@16: BOOST_STATIC_ASSERT((is_same::value)); Chris@16: // typedef typename kth_semantic_element_type::type e1; Chris@16: // typedef typename kth_semantic_element_type::type e2; Chris@16: // "e1 is convertible to e2" Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// PIXEL CONCEPTS Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \brief Concept for all pixel-based GIL constructs, such as pixels, iterators, locators, views and images whose value type is a pixel Chris@16: /// \ingroup PixelBasedConcept Chris@16: /** Chris@16: \code Chris@16: concept PixelBasedConcept { Chris@16: typename color_space_type; Chris@16: where Metafunction >; Chris@16: where ColorSpaceConcept::type>; Chris@16: typename channel_mapping_type; Chris@16: where Metafunction >; Chris@16: where ChannelMappingConcept::type>; Chris@16: typename is_planar; Chris@16: where Metafunction >; Chris@16: where SameType::type, bool>; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct PixelBasedConcept { Chris@16: void constraints() { Chris@16: typedef typename color_space_type

::type color_space_t; Chris@16: gil_function_requires >(); Chris@16: typedef typename channel_mapping_type

::type channel_mapping_t; Chris@16: gil_function_requires >(); Chris@16: Chris@16: static const bool planar = is_planar

::type::value; ignore_unused_variable_warning(planar); Chris@16: Chris@16: Chris@16: // This is not part of the concept, but should still work Chris@16: static const std::size_t nc = num_channels

::value; Chris@16: ignore_unused_variable_warning(nc); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief Concept for homogeneous pixel-based GIL constructs Chris@16: /// \ingroup PixelBasedConcept Chris@16: /** Chris@16: \code Chris@16: concept HomogeneousPixelBasedConcept { Chris@16: typename channel_type; Chris@16: where Metafunction >; Chris@16: where ChannelConcept::type>; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct HomogeneousPixelBasedConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: typedef typename channel_type

::type channel_t; Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: /// \brief Pixel concept - A color base whose elements are channels Chris@16: /// \ingroup PixelConcept Chris@16: /** Chris@16: \code Chris@16: concept PixelConcept : ColorBaseConcept

, PixelBasedConcept

{ Chris@16: where is_pixel

::type::value==true; Chris@16: // where for each K [0..size

::value-1]: Chris@16: // ChannelConcept >; Chris@16: Chris@16: typename P::value_type; where PixelValueConcept; Chris@16: typename P::reference; where PixelConcept; Chris@16: typename P::const_reference; where PixelConcept; Chris@16: static const bool P::is_mutable; Chris@16: Chris@16: template where { PixelConcept } Chris@16: P::P(P2); Chris@16: template where { PixelConcept } Chris@16: bool operator==(const P&, const P2&); Chris@16: template where { PixelConcept } Chris@16: bool operator!=(const P&, const P2&); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct PixelConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: Chris@16: BOOST_STATIC_ASSERT((is_pixel

::value)); Chris@16: static const bool is_mutable = P::is_mutable; ignore_unused_variable_warning(is_mutable); Chris@16: Chris@16: typedef typename P::value_type value_type; Chris@16: // gil_function_requires >(); Chris@16: Chris@16: typedef typename P::reference reference; Chris@16: gil_function_requires::type> >(); Chris@16: Chris@16: typedef typename P::const_reference const_reference; Chris@16: gil_function_requires::type> >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: /// \brief Pixel concept that allows for changing its channels Chris@16: /// \ingroup PixelConcept Chris@16: /** Chris@16: \code Chris@16: concept MutablePixelConcept : MutableColorBaseConcept

{ Chris@16: where is_mutable==true; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutablePixelConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: BOOST_STATIC_ASSERT(P::is_mutable); Chris@16: } Chris@16: }; Chris@16: /// \brief Homogeneous pixel concept Chris@16: /// \ingroup PixelConcept Chris@16: /** Chris@16: \code Chris@16: concept HomogeneousPixelConcept : HomogeneousColorBaseConcept

, HomogeneousPixelBasedConcept

{ Chris@16: P::template element_const_reference_type

::type operator[](P p, std::size_t i) const { return dynamic_at_c(p,i); } Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct HomogeneousPixelConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: p[0]; Chris@16: } Chris@16: P p; Chris@16: }; Chris@16: Chris@16: /// \brief Homogeneous pixel concept that allows for changing its channels Chris@16: /// \ingroup PixelConcept Chris@16: /** Chris@16: \code Chris@16: concept MutableHomogeneousPixelConcept : MutableHomogeneousColorBaseConcept

{ Chris@16: P::template element_reference_type

::type operator[](P p, std::size_t i) { return dynamic_at_c(p,i); } Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableHomogeneousPixelConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: p[0]=p[0]; Chris@16: } Chris@16: P p; Chris@16: }; Chris@16: Chris@16: /// \brief Pixel concept that is a Regular type Chris@16: /// \ingroup PixelConcept Chris@16: /** Chris@16: \code Chris@16: concept PixelValueConcept : Regular

{ Chris@16: where SameType; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct PixelValueConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief Homogeneous pixel concept that is a Regular type Chris@16: /// \ingroup PixelConcept Chris@16: /** Chris@16: \code Chris@16: concept HomogeneousPixelValueConcept : Regular

{ Chris@16: where SameType; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct HomogeneousPixelValueConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: BOOST_STATIC_ASSERT((is_same::value)); Chris@16: } Chris@16: }; Chris@16: Chris@16: namespace detail { Chris@16: template Chris@16: struct channels_are_pairwise_compatible : public Chris@16: mpl::and_, Chris@16: channels_are_compatible::type, Chris@16: typename kth_semantic_element_reference_type::type> > {}; Chris@16: Chris@16: template Chris@16: struct channels_are_pairwise_compatible : public mpl::true_ {}; Chris@16: } Chris@16: Chris@16: /// \brief Returns whether two pixels are compatible Chris@16: /// Chris@16: /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another. Chris@16: /// \ingroup PixelAlgorithm Chris@16: template // Models GIL Pixel Chris@16: struct pixels_are_compatible Chris@16: : public mpl::and_::type, Chris@16: typename color_space_type::type>::type, Chris@16: detail::channels_are_pairwise_compatible::value-1> > {}; Chris@16: Chris@16: /// \brief Concept for pixel compatibility Chris@16: /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another. Chris@16: /// \ingroup PixelConcept Chris@16: /** Chris@16: \code Chris@16: concept PixelsCompatibleConcept : ColorBasesCompatibleConcept { Chris@16: // where for each K [0..size::value): Chris@16: // ChannelsCompatibleConcept::type, kth_semantic_element_type::type>; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template // precondition: P1 and P2 model PixelConcept Chris@16: struct PixelsCompatibleConcept { Chris@16: void constraints() { Chris@16: BOOST_STATIC_ASSERT((pixels_are_compatible::value)); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief Pixel convertible concept Chris@16: /// Chris@16: /// Convertibility is non-symmetric and implies that one pixel can be converted to another, approximating the color. Conversion is explicit and sometimes lossy. Chris@16: /// \ingroup PixelConcept Chris@16: /** Chris@16: \code Chris@16: template Chris@16: concept PixelConvertibleConcept { Chris@16: void color_convert(const SrcPixel&, DstPixel&); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct PixelConvertibleConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: color_convert(src,dst); Chris@16: } Chris@16: SrcP src; Chris@16: DstP dst; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// DEREFERENCE ADAPTOR CONCEPTS Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \ingroup PixelDereferenceAdaptorConcept Chris@16: Chris@16: /// \brief Represents a unary function object that can be invoked upon dereferencing a pixel iterator. Chris@16: /// Chris@16: /// This can perform an arbitrary computation, such as color conversion or table lookup Chris@16: /** Chris@16: \code Chris@16: concept PixelDereferenceAdaptorConcept Chris@16: : DefaultConstructibleConcept, CopyConstructibleConcept, AssignableConcept { Chris@16: typename const_t; where PixelDereferenceAdaptorConcept; Chris@16: typename value_type; where PixelValueConcept; Chris@16: typename reference; // may be mutable Chris@16: typename const_reference; // must not be mutable Chris@16: static const bool D::is_mutable; Chris@16: Chris@16: where Convertible; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: Chris@16: template Chris@16: struct PixelDereferenceAdaptorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< boost::UnaryFunctionConcept::type, Chris@16: typename D::argument_type> >(); Chris@16: gil_function_requires< boost::DefaultConstructibleConcept >(); Chris@16: gil_function_requires< boost::CopyConstructibleConcept >(); Chris@16: gil_function_requires< boost::AssignableConcept >(); Chris@16: Chris@16: gil_function_requires::type> >(); Chris@16: Chris@16: typedef typename D::const_t const_t; Chris@16: gil_function_requires >(); Chris@16: typedef typename D::value_type value_type; Chris@16: gil_function_requires >(); Chris@16: typedef typename D::reference reference; // == PixelConcept (if you remove const and reference) Chris@16: typedef typename D::const_reference const_reference; // == PixelConcept (if you remove const and reference) Chris@16: Chris@16: const bool is_mutable=D::is_mutable; ignore_unused_variable_warning(is_mutable); Chris@16: } Chris@16: D d; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct PixelDereferenceAdaptorArchetype : public std::unary_function { Chris@16: typedef PixelDereferenceAdaptorArchetype const_t; Chris@16: typedef typename remove_reference

::type value_type; Chris@16: typedef typename add_reference

::type reference; Chris@16: typedef reference const_reference; Chris@16: static const bool is_mutable=false; Chris@16: P operator()(P x) const { throw; } Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// Pixel ITERATOR CONCEPTS Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \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 Chris@16: /// \ingroup PixelIteratorConcept Chris@16: /** Chris@16: \code Chris@16: concept HasDynamicXStepTypeConcept { Chris@16: typename dynamic_x_step_type; Chris@16: where Metafunction >; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct HasDynamicXStepTypeConcept { Chris@16: void constraints() { Chris@16: typedef typename dynamic_x_step_type::type type; Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \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 Chris@16: /// \ingroup PixelLocatorConcept Chris@16: /** Chris@16: \code Chris@16: concept HasDynamicYStepTypeConcept { Chris@16: typename dynamic_y_step_type; Chris@16: where Metafunction >; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct HasDynamicYStepTypeConcept { Chris@16: void constraints() { Chris@16: typedef typename dynamic_y_step_type::type type; Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: /// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped Chris@16: /// \ingroup PixelLocatorConcept Chris@16: /** Chris@16: \code Chris@16: concept HasTransposedTypeConcept { Chris@16: typename transposed_type; Chris@16: where Metafunction >; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct HasTransposedTypeConcept { Chris@16: void constraints() { Chris@16: typedef typename transposed_type::type type; Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept Chris@16: /// \ingroup PixelIteratorConcept Chris@16: /// \brief STL iterator over pixels Chris@16: Chris@16: /// \ingroup PixelIteratorConceptPixelIterator Chris@16: /// \brief An STL random access traversal iterator over a model of PixelConcept. Chris@16: /** Chris@16: GIL's iterators must also provide the following metafunctions: Chris@16: - \p const_iterator_type: Returns a read-only equivalent of \p Iterator Chris@16: - \p iterator_is_mutable: Returns whether the given iterator is read-only or mutable Chris@16: - \p is_iterator_adaptor: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors. Chris@16: Chris@16: \code Chris@16: concept PixelIteratorConcept : boost_concepts::RandomAccessTraversalConcept, PixelBasedConcept { Chris@16: where PixelValueConcept; Chris@16: typename const_iterator_type::type; Chris@16: where PixelIteratorConcept::type>; Chris@16: static const bool iterator_is_mutable::type::value; Chris@16: static const bool is_iterator_adaptor::type::value; // is it an iterator adaptor Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct PixelIteratorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename std::iterator_traits::value_type value_type; Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename const_iterator_type::type const_t; Chris@16: static const bool is_mut = iterator_is_mutable::type::value; ignore_unused_variable_warning(is_mut); Chris@16: Chris@16: const_t const_it(it); ignore_unused_variable_warning(const_it); // immutable iterator must be constructible from (possibly mutable) iterator Chris@16: Chris@16: check_base(typename is_iterator_adaptor::type()); Chris@16: } Chris@16: void check_base(mpl::false_) {} Chris@16: void check_base(mpl::true_) { Chris@16: typedef typename iterator_adaptor_get_base::type base_t; Chris@16: gil_function_requires >(); Chris@16: } Chris@16: Chris@16: Iterator it; Chris@16: }; Chris@16: Chris@16: namespace detail { Chris@16: template // Preconditions: Iterator Models PixelIteratorConcept Chris@16: struct PixelIteratorIsMutableConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: typedef typename remove_reference::reference>::type ref; Chris@16: typedef typename element_type::type channel_t; Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: /// \brief Pixel iterator that allows for changing its pixel Chris@16: /// \ingroup PixelIteratorConceptPixelIterator Chris@16: /** Chris@16: \code Chris@16: concept MutablePixelIteratorConcept : MutableRandomAccessIteratorConcept {}; Chris@16: Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutablePixelIteratorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: namespace detail { Chris@16: // Iterators that can be used as the base of memory_based_step_iterator require some additional functions Chris@16: template // Preconditions: Iterator Models boost_concepts::RandomAccessTraversalConcept Chris@16: struct RandomAccessIteratorIsMemoryBasedConcept { Chris@16: void constraints() { Chris@16: std::ptrdiff_t bs=memunit_step(it); ignore_unused_variable_warning(bs); Chris@16: it=memunit_advanced(it,3); Chris@16: std::ptrdiff_t bd=memunit_distance(it,it); ignore_unused_variable_warning(bd); Chris@16: memunit_advance(it,3); Chris@16: // for performace you may also provide a customized implementation of memunit_advanced_ref Chris@16: } Chris@16: Iterator it; Chris@16: }; Chris@16: } Chris@16: Chris@16: /// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept Chris@16: /// \ingroup PixelIteratorConcept Chris@16: /// \brief Iterator that advances by a specified step Chris@16: Chris@16: /// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits) Chris@16: /// \ingroup PixelIteratorConceptStepIterator Chris@16: /** Chris@16: \code Chris@16: concept MemoryBasedIteratorConcept { Chris@16: typename byte_to_memunit; where metafunction >; Chris@16: std::ptrdiff_t memunit_step(const Iterator&); Chris@16: std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&); Chris@16: void memunit_advance(Iterator&, std::ptrdiff_t diff); Chris@16: Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; } Chris@16: Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); } Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MemoryBasedIteratorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief Step iterator concept Chris@16: /// Chris@16: /// Step iterators are iterators that have a set_step method Chris@16: /// \ingroup PixelIteratorConceptStepIterator Chris@16: /** Chris@16: \code Chris@16: concept StepIteratorConcept { Chris@16: template void Iterator::set_step(D step); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct StepIteratorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: it.set_step(0); Chris@16: } Chris@16: Iterator it; Chris@16: }; Chris@16: Chris@16: Chris@16: /// \brief Step iterator that allows for modifying its current value Chris@16: /// Chris@16: /// \ingroup PixelIteratorConceptStepIterator Chris@16: /** Chris@16: \code Chris@16: concept MutableStepIteratorConcept : StepIteratorConcept {}; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableStepIteratorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept Chris@16: /// \ingroup PixelIteratorConcept Chris@16: /// \brief Adaptor over another iterator Chris@16: Chris@16: /// \ingroup PixelIteratorConceptIteratorAdaptor Chris@16: /// \brief Iterator adaptor is a forward iterator adapting another forward iterator. Chris@16: /** Chris@16: In addition to GIL iterator requirements, GIL iterator adaptors must provide the following metafunctions: Chris@16: - \p is_iterator_adaptor: Returns \p mpl::true_ Chris@16: - \p iterator_adaptor_get_base: Returns the base iterator type Chris@16: - \p iterator_adaptor_rebind: Replaces the base iterator with the new one Chris@16: Chris@16: The adaptee can be obtained from the iterator via the "base()" method. Chris@16: Chris@16: \code Chris@16: concept IteratorAdaptorConcept { Chris@16: where SameType::type, mpl::true_>; Chris@16: Chris@16: typename iterator_adaptor_get_base; Chris@16: where Metafunction >; Chris@16: where boost_concepts::ForwardTraversalConcept::type>; Chris@16: Chris@16: typename another_iterator; Chris@16: typename iterator_adaptor_rebind::type; Chris@16: where boost_concepts::ForwardTraversalConcept; Chris@16: where IteratorAdaptorConcept::type>; Chris@16: Chris@16: const iterator_adaptor_get_base::type& Iterator::base() const; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct IteratorAdaptorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename iterator_adaptor_get_base::type base_t; Chris@16: gil_function_requires >(); Chris@16: Chris@16: BOOST_STATIC_ASSERT(is_iterator_adaptor::value); Chris@16: typedef typename iterator_adaptor_rebind::type rebind_t; Chris@16: Chris@16: base_t base=it.base(); ignore_unused_variable_warning(base); Chris@16: } Chris@16: Iterator it; Chris@16: }; Chris@16: Chris@16: /// \brief Iterator adaptor that is mutable Chris@16: /// \ingroup PixelIteratorConceptIteratorAdaptor Chris@16: /** Chris@16: \code Chris@16: concept MutableIteratorAdaptorConcept : IteratorAdaptorConcept {}; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableIteratorAdaptorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// LOCATOR CONCEPTS Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept Chris@16: /// \ingroup PixelLocatorConcept Chris@16: /// \brief N-dimensional locator Chris@16: Chris@16: /// \defgroup Locator2DConcept RandomAccess2DLocatorConcept Chris@16: /// \ingroup PixelLocatorConcept Chris@16: /// \brief 2-dimensional locator Chris@16: Chris@16: /// \defgroup PixelLocator2DConcept PixelLocatorConcept Chris@16: /// \ingroup PixelLocatorConcept Chris@16: /// \brief 2-dimensional locator over pixel data Chris@16: Chris@16: /// \ingroup LocatorNDConcept Chris@16: /// \brief N-dimensional locator over immutable values Chris@16: /** Chris@16: \code Chris@16: concept RandomAccessNDLocatorConcept { Chris@16: typename value_type; // value over which the locator navigates Chris@16: typename reference; // result of dereferencing Chris@16: typename difference_type; where PointNDConcept; // return value of operator-. Chris@16: typename const_t; // same as Loc, but operating over immutable values Chris@16: typename cached_location_t; // type to store relative location (for efficient repeated access) Chris@16: typename point_t = difference_type; Chris@16: Chris@16: static const size_t num_dimensions; // dimensionality of the locator Chris@16: where num_dimensions = point_t::num_dimensions; Chris@16: Chris@16: // The difference_type and iterator type along each dimension. The iterators may only differ in Chris@16: // difference_type. Their value_type must be the same as Loc::value_type Chris@16: template struct axis { Chris@16: typename coord_t = point_t::axis::coord_t; Chris@16: typename iterator; where RandomAccessTraversalConcept; // iterator along D-th axis. Chris@16: where iterator::value_type == value_type; Chris@16: }; Chris@16: Chris@16: // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing Chris@16: template struct add_deref { Chris@16: typename type; where RandomAccessNDLocatorConcept; Chris@16: static type make(const Loc& loc, const Deref& deref); Chris@16: }; Chris@16: Chris@16: Loc& operator+=(Loc&, const difference_type&); Chris@16: Loc& operator-=(Loc&, const difference_type&); Chris@16: Loc operator+(const Loc&, const difference_type&); Chris@16: Loc operator-(const Loc&, const difference_type&); Chris@16: Chris@16: reference operator*(const Loc&); Chris@16: reference operator[](const Loc&, const difference_type&); Chris@16: Chris@16: // Storing relative location for faster repeated access and accessing it Chris@16: cached_location_t Loc::cache_location(const difference_type&) const; Chris@16: reference operator[](const Loc&,const cached_location_t&); Chris@16: Chris@16: // Accessing iterators along a given dimension at the current location or at a given offset Chris@16: template axis::iterator& Loc::axis_iterator(); Chris@16: template axis::iterator const& Loc::axis_iterator() const; Chris@16: template axis::iterator Loc::axis_iterator(const difference_type&) const; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct RandomAccessNDLocatorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< Regular >(); Chris@16: Chris@16: typedef typename Loc::value_type value_type; Chris@16: typedef typename Loc::reference reference; // result of dereferencing Chris@16: typedef typename Loc::difference_type difference_type; // result of operator-(pixel_locator, pixel_locator) Chris@16: typedef typename Loc::cached_location_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access) Chris@16: typedef typename Loc::const_t const_t; // same as this type, but over const values Chris@16: typedef typename Loc::point_t point_t; // same as difference_type Chris@16: static const std::size_t N=Loc::num_dimensions; ignore_unused_variable_warning(N); Chris@16: Chris@16: typedef typename Loc::template axis<0>::iterator first_it_type; Chris@16: typedef typename Loc::template axis::iterator last_it_type; Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: Chris@16: // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator Chris@16: gil_function_requires >(); Chris@16: BOOST_STATIC_ASSERT(point_t::num_dimensions==N); Chris@16: BOOST_STATIC_ASSERT((is_same::difference_type, typename point_t::template axis<0>::coord_t>::value)); Chris@16: BOOST_STATIC_ASSERT((is_same::difference_type, typename point_t::template axis::coord_t>::value)); Chris@16: Chris@16: difference_type d; Chris@16: loc+=d; Chris@16: loc-=d; Chris@16: loc=loc+d; Chris@16: loc=loc-d; Chris@16: reference r1=loc[d]; ignore_unused_variable_warning(r1); Chris@16: reference r2=*loc; ignore_unused_variable_warning(r2); Chris@16: cached_location_t cl=loc.cache_location(d); ignore_unused_variable_warning(cl); Chris@16: reference r3=loc[d]; ignore_unused_variable_warning(r3); Chris@16: Chris@16: first_it_type fi=loc.template axis_iterator<0>(); Chris@16: fi=loc.template axis_iterator<0>(d); Chris@16: last_it_type li=loc.template axis_iterator(); Chris@16: li=loc.template axis_iterator(d); Chris@16: Chris@16: typedef PixelDereferenceAdaptorArchetype deref_t; Chris@16: typedef typename Loc::template add_deref::type dtype; Chris@16: //gil_function_requires >(); // infinite recursion Chris@16: } Chris@16: Loc loc; Chris@16: }; Chris@16: Chris@16: /// \ingroup Locator2DConcept Chris@16: /// \brief 2-dimensional locator over immutable values Chris@16: /** Chris@16: \code Chris@16: concept RandomAccess2DLocatorConcept { Chris@16: where num_dimensions==2; Chris@16: where Point2DConcept; Chris@16: Chris@16: typename x_iterator = axis<0>::iterator; Chris@16: typename y_iterator = axis<1>::iterator; Chris@16: typename x_coord_t = axis<0>::coord_t; Chris@16: typename y_coord_t = axis<1>::coord_t; Chris@16: Chris@16: // Only available to locators that have dynamic step in Y Chris@16: //Loc::Loc(const Loc& loc, y_coord_t); Chris@16: Chris@16: // Only available to locators that have dynamic step in X and Y Chris@16: //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false); Chris@16: Chris@16: x_iterator& Loc::x(); Chris@16: x_iterator const& Loc::x() const; Chris@16: y_iterator& Loc::y(); Chris@16: y_iterator const& Loc::y() const; Chris@16: Chris@16: x_iterator Loc::x_at(const difference_type&) const; Chris@16: y_iterator Loc::y_at(const difference_type&) const; Chris@16: Loc Loc::xy_at(const difference_type&) const; Chris@16: Chris@16: // x/y versions of all methods that can take difference type Chris@16: x_iterator Loc::x_at(x_coord_t, y_coord_t) const; Chris@16: y_iterator Loc::y_at(x_coord_t, y_coord_t) const; Chris@16: Loc Loc::xy_at(x_coord_t, y_coord_t) const; Chris@16: reference operator()(const Loc&, x_coord_t, y_coord_t); Chris@16: cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const; Chris@16: Chris@16: bool Loc::is_1d_traversable(x_coord_t width) const; Chris@16: y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct RandomAccess2DLocatorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: BOOST_STATIC_ASSERT(Loc::num_dimensions==2); Chris@16: Chris@16: typedef typename dynamic_x_step_type::type dynamic_x_step_t; Chris@16: typedef typename dynamic_y_step_type::type dynamic_y_step_t; Chris@16: typedef typename transposed_type::type transposed_t; Chris@16: Chris@16: typedef typename Loc::cached_location_t cached_location_t; Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename Loc::x_iterator x_iterator; Chris@16: typedef typename Loc::y_iterator y_iterator; Chris@16: typedef typename Loc::x_coord_t x_coord_t; Chris@16: typedef typename Loc::y_coord_t y_coord_t; Chris@16: Chris@16: x_coord_t xd=0; ignore_unused_variable_warning(xd); Chris@16: y_coord_t yd=0; ignore_unused_variable_warning(yd); Chris@16: Chris@16: typename Loc::difference_type d; Chris@16: typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r); Chris@16: Chris@16: dynamic_x_step_t loc2(dynamic_x_step_t(), yd); Chris@16: dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd); Chris@16: Chris@16: typedef typename dynamic_y_step_type::type>::type dynamic_xy_step_transposed_t; Chris@16: dynamic_xy_step_transposed_t loc4(loc, xd,yd,true); Chris@16: Chris@16: bool is_contiguous=loc.is_1d_traversable(xd); ignore_unused_variable_warning(is_contiguous); Chris@16: loc.y_distance_to(loc, xd); Chris@16: Chris@16: loc=loc.xy_at(d); Chris@16: loc=loc.xy_at(xd,yd); Chris@16: Chris@16: x_iterator xit=loc.x_at(d); Chris@16: xit=loc.x_at(xd,yd); Chris@16: xit=loc.x(); Chris@16: Chris@16: y_iterator yit=loc.y_at(d); Chris@16: yit=loc.y_at(xd,yd); Chris@16: yit=loc.y(); Chris@16: Chris@16: cached_location_t cl=loc.cache_location(xd,yd); ignore_unused_variable_warning(cl); Chris@16: } Chris@16: Loc loc; Chris@16: }; Chris@16: Chris@16: /// \ingroup PixelLocator2DConcept Chris@16: /// \brief GIL's 2-dimensional locator over immutable GIL pixels Chris@16: /** Chris@16: \code Chris@16: concept PixelLocatorConcept { Chris@16: where PixelValueConcept; Chris@16: where PixelIteratorConcept; Chris@16: where PixelIteratorConcept; Chris@16: where x_coord_t == y_coord_t; Chris@16: Chris@16: typename coord_t = x_coord_t; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct PixelLocatorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< RandomAccess2DLocatorConcept >(); Chris@16: gil_function_requires< PixelIteratorConcept >(); Chris@16: gil_function_requires< PixelIteratorConcept >(); Chris@16: typedef typename Loc::coord_t coord_t; Chris@16: BOOST_STATIC_ASSERT((is_same::value)); Chris@16: } Chris@16: Loc loc; Chris@16: }; Chris@16: Chris@16: namespace detail { Chris@16: template // preconditions: Loc Models RandomAccessNDLocatorConcept Chris@16: struct RandomAccessNDLocatorIsMutableConcept { Chris@16: void constraints() { Chris@16: gil_function_requires::iterator> >(); Chris@16: gil_function_requires::iterator> >(); Chris@16: Chris@16: typename Loc::difference_type d; initialize_it(d); Chris@16: typename Loc::value_type v;initialize_it(v); Chris@16: typename Loc::cached_location_t cl=loc.cache_location(d); Chris@16: *loc=v; Chris@16: loc[d]=v; Chris@16: loc[cl]=v; Chris@16: } Chris@16: Loc loc; Chris@16: }; Chris@16: Chris@16: template // preconditions: Loc Models RandomAccess2DLocatorConcept Chris@16: struct RandomAccess2DLocatorIsMutableConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: typename Loc::x_coord_t xd=0; ignore_unused_variable_warning(xd); Chris@16: typename Loc::y_coord_t yd=0; ignore_unused_variable_warning(yd); Chris@16: typename Loc::value_type v; initialize_it(v); Chris@16: loc(xd,yd)=v; Chris@16: } Chris@16: Loc loc; Chris@16: }; Chris@16: } Chris@16: Chris@16: /// \ingroup LocatorNDConcept Chris@16: /// \brief N-dimensional locator over mutable pixels Chris@16: /** Chris@16: \code Chris@16: concept MutableRandomAccessNDLocatorConcept { Chris@16: where Mutable; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableRandomAccessNDLocatorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup Locator2DConcept Chris@16: /// \brief 2-dimensional locator over mutable pixels Chris@16: /** Chris@16: \code Chris@16: concept MutableRandomAccess2DLocatorConcept : MutableRandomAccessNDLocatorConcept {}; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableRandomAccess2DLocatorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< RandomAccess2DLocatorConcept >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup PixelLocator2DConcept Chris@16: /// \brief GIL's 2-dimensional locator over mutable GIL pixels Chris@16: /** Chris@16: \code Chris@16: concept MutablePixelLocatorConcept : MutableRandomAccess2DLocatorConcept {}; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutablePixelLocatorConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// IMAGE VIEW CONCEPTS Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept Chris@16: /// \ingroup ImageViewConcept Chris@16: /// \brief N-dimensional range Chris@16: Chris@16: /// \defgroup ImageView2DConcept ImageView2DConcept Chris@16: /// \ingroup ImageViewConcept Chris@16: /// \brief 2-dimensional range Chris@16: Chris@16: /// \defgroup PixelImageViewConcept ImageViewConcept Chris@16: /// \ingroup ImageViewConcept Chris@16: /// \brief 2-dimensional range over pixel data Chris@16: Chris@16: /// \ingroup ImageViewNDConcept Chris@16: /// \brief N-dimensional view over immutable values Chris@16: /** Chris@16: \code Chris@16: concept RandomAccessNDImageViewConcept { Chris@16: typename value_type; Chris@16: typename reference; // result of dereferencing Chris@16: typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!) Chris@16: typename const_t; where RandomAccessNDImageViewConcept; // same as View, but over immutable values Chris@16: typename point_t; where PointNDConcept; // N-dimensional point Chris@16: typename locator; where RandomAccessNDLocatorConcept; // N-dimensional locator. Chris@16: typename iterator; where RandomAccessTraversalConcept; // 1-dimensional iterator over all values Chris@16: typename reverse_iterator; where RandomAccessTraversalConcept; Chris@16: typename size_type; // the return value of size() Chris@16: Chris@16: // Equivalent to RandomAccessNDLocatorConcept::axis Chris@16: template struct axis { Chris@16: typename coord_t = point_t::axis::coord_t; Chris@16: typename iterator; where RandomAccessTraversalConcept; // iterator along D-th axis. Chris@16: where SameType; Chris@16: where SameType; Chris@16: }; Chris@16: Chris@16: // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing Chris@16: template struct add_deref { Chris@16: typename type; where RandomAccessNDImageViewConcept; Chris@16: static type make(const View& v, const Deref& deref); Chris@16: }; Chris@16: Chris@16: static const size_t num_dimensions = point_t::num_dimensions; Chris@16: Chris@16: // Create from a locator at the top-left corner and dimensions Chris@16: View::View(const locator&, const point_type&); Chris@16: Chris@16: size_type View::size() const; // total number of elements Chris@16: reference operator[](View, const difference_type&) const; // 1-dimensional reference Chris@16: iterator View::begin() const; Chris@16: iterator View::end() const; Chris@16: reverse_iterator View::rbegin() const; Chris@16: reverse_iterator View::rend() const; Chris@16: iterator View::at(const point_t&); Chris@16: point_t View::dimensions() const; // number of elements along each dimension Chris@16: bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values? Chris@16: Chris@16: // iterator along a given dimension starting at a given point Chris@16: template View::axis::iterator View::axis_iterator(const point_t&) const; Chris@16: Chris@16: reference operator()(View,const point_t&) const; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct RandomAccessNDImageViewConcept { Chris@16: void constraints() { Chris@16: gil_function_requires< Regular >(); Chris@16: Chris@16: typedef typename View::value_type value_type; Chris@16: typedef typename View::reference reference; // result of dereferencing Chris@16: typedef typename View::difference_type difference_type; // result of operator-(1d_iterator,1d_iterator) Chris@16: typedef typename View::const_t const_t; // same as this type, but over const values Chris@16: typedef typename View::point_t point_t; // N-dimensional point Chris@16: typedef typename View::locator locator; // N-dimensional locator Chris@16: typedef typename View::iterator iterator; Chris@16: typedef typename View::reverse_iterator reverse_iterator; Chris@16: typedef typename View::size_type size_type; Chris@16: static const std::size_t N=View::num_dimensions; Chris@16: Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename View::template axis<0>::iterator first_it_type; Chris@16: typedef typename View::template axis::iterator last_it_type; Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: Chris@16: // BOOST_STATIC_ASSERT((typename std::iterator_traits::difference_type, typename point_t::template axis<0>::coord_t>::value)); Chris@16: // BOOST_STATIC_ASSERT((typename std::iterator_traits< last_it_type>::difference_type, typename point_t::template axis::coord_t>::value)); Chris@16: Chris@16: // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator Chris@16: gil_function_requires >(); Chris@16: BOOST_STATIC_ASSERT(point_t::num_dimensions==N); Chris@16: BOOST_STATIC_ASSERT((is_same::difference_type, typename point_t::template axis<0>::coord_t>::value)); Chris@16: BOOST_STATIC_ASSERT((is_same::difference_type, typename point_t::template axis::coord_t>::value)); Chris@16: Chris@16: point_t p; Chris@16: locator lc; Chris@16: iterator it; Chris@16: reverse_iterator rit; Chris@16: difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d); Chris@16: Chris@16: View(p,lc); // view must be constructible from a locator and a point Chris@16: Chris@16: p=view.dimensions(); Chris@16: lc=view.pixels(); Chris@16: size_type sz=view.size(); ignore_unused_variable_warning(sz); Chris@16: bool is_contiguous=view.is_1d_traversable(); ignore_unused_variable_warning(is_contiguous); Chris@16: Chris@16: it=view.begin(); Chris@16: it=view.end(); Chris@16: rit=view.rbegin(); Chris@16: rit=view.rend(); Chris@16: Chris@16: reference r1=view[d]; ignore_unused_variable_warning(r1); // 1D access Chris@16: reference r2=view(p); ignore_unused_variable_warning(r2); // 2D access Chris@16: Chris@16: // get 1-D iterator of any dimension at a given pixel location Chris@16: first_it_type fi=view.template axis_iterator<0>(p); ignore_unused_variable_warning(fi); Chris@16: last_it_type li=view.template axis_iterator(p); ignore_unused_variable_warning(li); Chris@16: Chris@16: typedef PixelDereferenceAdaptorArchetype deref_t; Chris@16: typedef typename View::template add_deref::type dtype; Chris@16: } Chris@16: View view; Chris@16: }; Chris@16: Chris@16: /// \ingroup ImageView2DConcept Chris@16: /// \brief 2-dimensional view over immutable values Chris@16: /** Chris@16: \code Chris@16: concept RandomAccess2DImageViewConcept { Chris@16: where num_dimensions==2; Chris@16: Chris@16: typename x_iterator = axis<0>::iterator; Chris@16: typename y_iterator = axis<1>::iterator; Chris@16: typename x_coord_t = axis<0>::coord_t; Chris@16: typename y_coord_t = axis<1>::coord_t; Chris@16: typename xy_locator = locator; Chris@16: Chris@16: x_coord_t View::width() const; Chris@16: y_coord_t View::height() const; Chris@16: Chris@16: // X-navigation Chris@16: x_iterator View::x_at(const point_t&) const; Chris@16: x_iterator View::row_begin(y_coord_t) const; Chris@16: x_iterator View::row_end (y_coord_t) const; Chris@16: Chris@16: // Y-navigation Chris@16: y_iterator View::y_at(const point_t&) const; Chris@16: y_iterator View::col_begin(x_coord_t) const; Chris@16: y_iterator View::col_end (x_coord_t) const; Chris@16: Chris@16: // navigating in 2D Chris@16: xy_locator View::xy_at(const point_t&) const; Chris@16: Chris@16: // (x,y) versions of all methods taking point_t Chris@16: View::View(x_coord_t,y_coord_t,const locator&); Chris@16: iterator View::at(x_coord_t,y_coord_t) const; Chris@16: reference operator()(View,x_coord_t,y_coord_t) const; Chris@16: xy_locator View::xy_at(x_coord_t,y_coord_t) const; Chris@16: x_iterator View::x_at(x_coord_t,y_coord_t) const; Chris@16: y_iterator View::y_at(x_coord_t,y_coord_t) const; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct RandomAccess2DImageViewConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: BOOST_STATIC_ASSERT(View::num_dimensions==2); Chris@16: Chris@16: // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename dynamic_x_step_type::type dynamic_x_step_t; Chris@16: typedef typename dynamic_y_step_type::type dynamic_y_step_t; Chris@16: typedef typename transposed_type::type transposed_t; Chris@16: Chris@16: typedef typename View::x_iterator x_iterator; Chris@16: typedef typename View::y_iterator y_iterator; Chris@16: typedef typename View::x_coord_t x_coord_t; Chris@16: typedef typename View::y_coord_t y_coord_t; Chris@16: typedef typename View::xy_locator xy_locator; Chris@16: Chris@16: x_coord_t xd=0; ignore_unused_variable_warning(xd); Chris@16: y_coord_t yd=0; ignore_unused_variable_warning(yd); Chris@16: x_iterator xit; Chris@16: y_iterator yit; Chris@16: typename View::point_t d; Chris@16: Chris@16: View(xd,yd,xy_locator()); // constructible with width, height, 2d_locator Chris@16: Chris@16: xy_locator lc=view.xy_at(xd,yd); Chris@16: lc=view.xy_at(d); Chris@16: Chris@16: typename View::reference r=view(xd,yd); ignore_unused_variable_warning(r); Chris@16: xd=view.width(); Chris@16: yd=view.height(); Chris@16: Chris@16: xit=view.x_at(d); Chris@16: xit=view.x_at(xd,yd); Chris@16: xit=view.row_begin(xd); Chris@16: xit=view.row_end(xd); Chris@16: Chris@16: yit=view.y_at(d); Chris@16: yit=view.y_at(xd,yd); Chris@16: yit=view.col_begin(xd); Chris@16: yit=view.col_end(xd); Chris@16: } Chris@16: View view; Chris@16: }; Chris@16: Chris@16: Chris@16: /// \ingroup PixelImageViewConcept Chris@16: /// \brief GIL's 2-dimensional view over immutable GIL pixels Chris@16: /** Chris@16: \code Chris@16: concept ImageViewConcept { Chris@16: where PixelValueConcept; Chris@16: where PixelIteratorConcept; Chris@16: where PixelIteratorConcept; Chris@16: where x_coord_t == y_coord_t; Chris@16: Chris@16: typename coord_t = x_coord_t; Chris@16: Chris@16: std::size_t View::num_channels() const; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ImageViewConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: Chris@16: // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time Chris@16: gil_function_requires >(); Chris@16: Chris@16: BOOST_STATIC_ASSERT((is_same::value)); Chris@16: Chris@16: typedef typename View::coord_t coord_t; // 1D difference type (same for all dimensions) Chris@16: std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan); Chris@16: } Chris@16: View view; Chris@16: }; Chris@16: Chris@16: Chris@16: namespace detail { Chris@16: template // Preconditions: View Models RandomAccessNDImageViewConcept Chris@16: struct RandomAccessNDImageViewIsMutableConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: gil_function_requires::iterator> >(); Chris@16: gil_function_requires::iterator> >(); Chris@16: Chris@16: typename View::difference_type diff; initialize_it(diff); ignore_unused_variable_warning(diff); Chris@16: typename View::point_t pt; Chris@16: typename View::value_type v; initialize_it(v); Chris@16: Chris@16: view[diff]=v; Chris@16: view(pt)=v; Chris@16: } Chris@16: View view; Chris@16: }; Chris@16: Chris@16: template // preconditions: View Models RandomAccessNDImageViewConcept Chris@16: struct RandomAccess2DImageViewIsMutableConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: typename View::x_coord_t xd=0; ignore_unused_variable_warning(xd); Chris@16: typename View::y_coord_t yd=0; ignore_unused_variable_warning(yd); Chris@16: typename View::value_type v; initialize_it(v); Chris@16: view(xd,yd)=v; Chris@16: } Chris@16: View view; Chris@16: }; Chris@16: Chris@16: template // preconditions: View Models ImageViewConcept Chris@16: struct PixelImageViewIsMutableConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: /// \ingroup ImageViewNDConcept Chris@16: /// \brief N-dimensional view over mutable values Chris@16: /** Chris@16: \code Chris@16: concept MutableRandomAccessNDImageViewConcept { Chris@16: where Mutable; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableRandomAccessNDImageViewConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup ImageView2DConcept Chris@16: /// \brief 2-dimensional view over mutable values Chris@16: /** Chris@16: \code Chris@16: concept MutableRandomAccess2DImageViewConcept : MutableRandomAccessNDImageViewConcept {}; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableRandomAccess2DImageViewConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \ingroup PixelImageViewConcept Chris@16: /// \brief GIL's 2-dimensional view over mutable GIL pixels Chris@16: /** Chris@16: \code Chris@16: concept MutableImageViewConcept : MutableRandomAccess2DImageViewConcept {}; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct MutableImageViewConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief Returns whether two views are compatible Chris@16: /// Chris@16: /// Views are compatible if their pixels are compatible. Compatible views can be assigned and copy constructed from one another. Chris@16: template // Model ImageViewConcept Chris@16: struct views_are_compatible : public pixels_are_compatible {}; Chris@16: Chris@16: /// \brief Views are compatible if they have the same color spaces and compatible channel values. Constness and layout are not important for compatibility Chris@16: /// \ingroup ImageViewConcept Chris@16: /** Chris@16: \code Chris@16: concept ViewsCompatibleConcept { Chris@16: where PixelsCompatibleConcept; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ViewsCompatibleConcept { Chris@16: void constraints() { Chris@16: BOOST_STATIC_ASSERT((views_are_compatible::value)); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// Chris@16: /// IMAGE CONCEPTS Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: Chris@16: /// \ingroup ImageConcept Chris@16: /// \brief N-dimensional container of values Chris@16: /** Chris@16: \code Chris@16: concept RandomAccessNDImageConcept : Regular { Chris@16: typename view_t; where MutableRandomAccessNDImageViewConcept; Chris@16: typename const_view_t = view_t::const_t; Chris@16: typename point_t = view_t::point_t; Chris@16: typename value_type = view_t::value_type; Chris@16: typename allocator_type; Chris@16: Chris@16: Img::Img(point_t dims, std::size_t alignment=1); Chris@16: Img::Img(point_t dims, value_type fill_value, std::size_t alignment); Chris@16: Chris@16: void Img::recreate(point_t new_dims, std::size_t alignment=1); Chris@16: void Img::recreate(point_t new_dims, value_type fill_value, std::size_t alignment); Chris@16: Chris@16: const point_t& Img::dimensions() const; Chris@16: const const_view_t& const_view(const Img&); Chris@16: const view_t& view(Img&); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct RandomAccessNDImageConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename Img::view_t view_t; Chris@16: gil_function_requires >(); Chris@16: Chris@16: typedef typename Img::const_view_t const_view_t; Chris@16: typedef typename Img::value_type pixel_t; Chris@16: Chris@16: typedef typename Img::point_t point_t; Chris@16: gil_function_requires >(); Chris@16: Chris@16: const_view_t cv = const_view(img); ignore_unused_variable_warning(cv); Chris@16: view_t v = view(img); ignore_unused_variable_warning(v); Chris@16: Chris@16: pixel_t fill_value; Chris@16: point_t pt=img.dimensions(); Chris@16: Img im1(pt); Chris@16: Img im2(pt,1); Chris@16: Img im3(pt,fill_value,1); Chris@16: img.recreate(pt); Chris@16: img.recreate(pt,1); Chris@16: img.recreate(pt,fill_value,1); Chris@16: } Chris@16: Img img; Chris@16: }; Chris@16: Chris@16: Chris@16: /// \ingroup ImageConcept Chris@16: /// \brief 2-dimensional container of values Chris@16: /** Chris@16: \code Chris@16: concept RandomAccess2DImageConcept { Chris@16: typename x_coord_t = const_view_t::x_coord_t; Chris@16: typename y_coord_t = const_view_t::y_coord_t; Chris@16: Chris@16: Img::Img(x_coord_t width, y_coord_t height, std::size_t alignment=1); Chris@16: Img::Img(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment); Chris@16: Chris@16: x_coord_t Img::width() const; Chris@16: y_coord_t Img::height() const; Chris@16: Chris@16: void Img::recreate(x_coord_t width, y_coord_t height, std::size_t alignment=1); Chris@16: void Img::recreate(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment); Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct RandomAccess2DImageConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: typedef typename Img::x_coord_t x_coord_t; Chris@16: typedef typename Img::y_coord_t y_coord_t; Chris@16: typedef typename Img::value_type value_t; Chris@16: Chris@16: gil_function_requires >(); Chris@16: Chris@16: x_coord_t w=img.width(); Chris@16: y_coord_t h=img.height(); Chris@16: value_t fill_value; Chris@16: Img im1(w,h); Chris@16: Img im2(w,h,1); Chris@16: Img im3(w,h,fill_value,1); Chris@16: img.recreate(w,h); Chris@16: img.recreate(w,h,1); Chris@16: img.recreate(w,h,fill_value,1); Chris@16: } Chris@16: Img img; Chris@16: }; Chris@16: Chris@16: /// \ingroup ImageConcept Chris@16: /// \brief 2-dimensional image whose value type models PixelValueConcept Chris@16: /** Chris@16: \code Chris@16: concept ImageConcept { Chris@16: where MutableImageViewConcept; Chris@16: typename coord_t = view_t::coord_t; Chris@16: }; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct ImageConcept { Chris@16: void constraints() { Chris@16: gil_function_requires >(); Chris@16: gil_function_requires >(); Chris@16: typedef typename Img::coord_t coord_t; Chris@16: BOOST_STATIC_ASSERT(num_channels::value == mpl::size::type>::value); Chris@16: Chris@16: BOOST_STATIC_ASSERT((is_same::value)); Chris@16: BOOST_STATIC_ASSERT((is_same::value)); Chris@16: } Chris@16: Img img; Chris@16: }; Chris@16: Chris@16: Chris@16: } } // namespace boost::gil Chris@16: Chris@16: #endif