feat():initial version

This commit is contained in:
2026-06-09 20:16:47 +08:00
commit 85fbb3188c
14809 changed files with 3044607 additions and 0 deletions

View File

@@ -0,0 +1,196 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_BASIC_HPP
#define BOOST_GIL_CONCEPTS_BASIC_HPP
#include <boost/config.hpp>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#pragma clang diagnostic ignored "-Wuninitialized"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
#include <boost/gil/concepts/concept_check.hpp>
#include <type_traits>
#include <utility> // std::swap
namespace boost { namespace gil {
/// \brief Concept of default construction requirement.
/// \code
/// auto concept DefaultConstructible<typename T>
/// {
/// T::T();
/// };
/// \endcode
/// \ingroup BasicConcepts
///
template <typename T>
struct DefaultConstructible
{
void constraints()
{
function_requires<boost::DefaultConstructibleConcept<T>>();
}
};
/// \brief Concept of copy construction requirement.
/// \code
/// auto concept CopyConstructible<typename T>
/// {
/// T::T(T);
/// T::~T();
/// };
/// \endcode
/// \ingroup BasicConcepts
///
template <typename T>
struct CopyConstructible
{
void constraints()
{
function_requires<boost::CopyConstructibleConcept<T>>();
}
};
/// \brief Concept of copy assignment requirement.
/// \code
/// auto concept Assignable<typename T, typename U = T>
/// {
/// typename result_type;
/// result_type operator=(T&, U);
/// };
/// \endcode
/// \ingroup BasicConcepts
///
template <typename T>
struct Assignable
{
void constraints()
{
function_requires<boost::AssignableConcept<T>>();
}
};
/// \brief Concept of == and != comparability requirement.
/// \code
/// auto concept EqualityComparable<typename T, typename U = T>
/// {
/// bool operator==(T x, T y);
/// bool operator!=(T x, T y) { return !(x==y); }
/// };
/// \endcode
/// \ingroup BasicConcepts
///
template <typename T>
struct EqualityComparable
{
void constraints()
{
function_requires<boost::EqualityComparableConcept<T>>();
}
};
/// \brief Concept of swap operation requirement.
/// \code
/// auto concept Swappable<typename T>
/// {
/// void swap(T&,T&);
/// };
/// \endcode
/// \ingroup BasicConcepts
///
template <typename T>
struct Swappable
{
void constraints()
{
using std::swap;
swap(x,y);
}
T x,y;
};
/// \brief Concept for type regularity requirement.
/// \code
/// auto concept Regular<typename T>
/// : DefaultConstructible<T>
/// , CopyConstructible<T>
/// , EqualityComparable<T>
/// , Assignable<T>
/// , Swappable<T>
/// {};
/// \endcode
/// \ingroup BasicConcepts
///
template <typename T>
struct Regular
{
void constraints()
{
gil_function_requires< boost::DefaultConstructibleConcept<T>>();
gil_function_requires< boost::CopyConstructibleConcept<T>>();
gil_function_requires< boost::EqualityComparableConcept<T>>(); // ==, !=
gil_function_requires< boost::AssignableConcept<T>>();
gil_function_requires< Swappable<T>>();
}
};
/// \brief Concept for type as metafunction requirement.
/// \code
/// auto concept Metafunction<typename T>
/// {
/// typename type;
/// };
/// \endcode
/// \ingroup BasicConcepts
///
template <typename T>
struct Metafunction
{
void constraints()
{
using type = typename T::type;
}
};
/// \brief Concept of types equivalence requirement.
/// \code
/// auto concept SameType<typename T, typename U>; // unspecified
/// \endcode
/// \ingroup BasicConcepts
///
template <typename T, typename U>
struct SameType
{
void constraints()
{
static_assert(std::is_same<T, U>::value, "");
}
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,216 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_CHANNEL_HPP
#define BOOST_GIL_CONCEPTS_CHANNEL_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <boost/concept_check.hpp>
#include <utility> // std::swap
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
// Forward declarations
template <typename T>
struct channel_traits;
template <typename DstT, typename SrcT>
auto channel_convert(SrcT const& val)
-> typename channel_traits<DstT>::value_type;
/// \ingroup ChannelConcept
/// \brief A channel is the building block of a color.
/// Color is defined as a mixture of primary colors and a channel defines
/// the degree to which each primary color is used in the mixture.
///
/// For example, in the RGB color space, using 8-bit unsigned channels,
/// the color red is defined as [255 0 0], which means maximum of Red,
/// and no Green and Blue.
///
/// Built-in scalar types, such as \p int and \p float, are valid GIL channels.
/// In more complex scenarios, channels may be represented as bit ranges or
/// even individual bits.
/// In such cases special classes are needed to represent the value and
/// reference to a channel.
///
/// Channels have a traits class, \p channel_traits, which defines their
/// associated types as well as their operating ranges.
///
/// \code
/// concept ChannelConcept<typename T> : EqualityComparable<T>
/// {
/// typename value_type = T; // use channel_traits<T>::value_type to access it
/// typename reference = T&; // use channel_traits<T>::reference to access it
/// typename pointer = T*; // use channel_traits<T>::pointer to access it
/// typename const_reference = const T&; // use channel_traits<T>::const_reference to access it
/// typename const_pointer = const T*; // use channel_traits<T>::const_pointer to access it
/// static const bool is_mutable; // use channel_traits<T>::is_mutable to access it
///
/// static T min_value(); // use channel_traits<T>::min_value to access it
/// static T max_value(); // use channel_traits<T>::max_value to access it
/// };
/// \endcode
template <typename T>
struct ChannelConcept
{
void constraints()
{
gil_function_requires<boost::EqualityComparableConcept<T>>();
using v = typename channel_traits<T>::value_type;
using r = typename channel_traits<T>::reference;
using p = typename channel_traits<T>::pointer;
using cr = typename channel_traits<T>::const_reference;
using cp = typename channel_traits<T>::const_pointer;
channel_traits<T>::min_value();
channel_traits<T>::max_value();
}
T c;
};
namespace detail
{
/// \tparam T models ChannelConcept
template <typename T>
struct ChannelIsMutableConcept
{
void constraints()
{
c1 = c2;
using std::swap;
swap(c1, c2);
}
T c1;
T c2;
};
} // namespace detail
/// \brief A channel that allows for modifying its value
/// \code
/// concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
/// \endcode
/// \ingroup ChannelConcept
template <typename T>
struct MutableChannelConcept
{
void constraints()
{
gil_function_requires<ChannelConcept<T>>();
gil_function_requires<detail::ChannelIsMutableConcept<T>>();
}
};
/// \brief A channel that supports default construction.
/// \code
/// concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
/// \endcode
/// \ingroup ChannelConcept
template <typename T>
struct ChannelValueConcept
{
void constraints()
{
gil_function_requires<ChannelConcept<T>>();
gil_function_requires<Regular<T>>();
}
};
/// \brief Predicate metafunction returning whether two channels are compatible
///
/// Channels are considered compatible if their value types
/// (ignoring constness and references) are the same.
///
/// Example:
///
/// \code
/// static_assert(channels_are_compatible<uint8_t, const uint8_t&>::value, "");
/// \endcode
/// \ingroup ChannelAlgorithm
template <typename T1, typename T2> // Models GIL Pixel
struct channels_are_compatible
: std::is_same
<
typename channel_traits<T1>::value_type,
typename channel_traits<T2>::value_type
>
{
};
/// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
///
/// \code
/// concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2>
/// {
/// where SameType<T1::value_type, T2::value_type>;
/// };
/// \endcode
/// \ingroup ChannelConcept
template <typename Channel1, typename Channel2>
struct ChannelsCompatibleConcept
{
void constraints()
{
static_assert(channels_are_compatible<Channel1, Channel2>::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.
///
/// concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel>
/// {
/// DstChannel channel_convert(const SrcChannel&);
/// };
/// \endcode
/// \ingroup ChannelConcept
template <typename SrcChannel, typename DstChannel>
struct ChannelConvertibleConcept
{
void constraints()
{
gil_function_requires<ChannelConcept<SrcChannel>>();
gil_function_requires<MutableChannelConcept<DstChannel>>();
dst = channel_convert<DstChannel, SrcChannel>(src);
ignore_unused_variable_warning(dst);
}
SrcChannel src;
DstChannel dst;
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,99 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_COLOR_HPP
#define BOOST_GIL_CONCEPTS_COLOR_HPP
#include <boost/gil/concepts/concept_check.hpp>
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
/// \ingroup ColorSpaceAndLayoutConcept
/// \brief Color space type concept
/// \code
/// concept ColorSpaceConcept<MPLRandomAccessSequence CS>
/// {
/// // Boost.MP11-compatible list, whose elements are color tags.
/// };
/// \endcode
template <typename CS>
struct ColorSpaceConcept
{
void constraints()
{
// Boost.MP11-compatible list, whose elements are color tags
// TODO: Is this incomplete?
}
};
// Models ColorSpaceConcept
template <typename CS1, typename CS2>
struct color_spaces_are_compatible : std::is_same<CS1, CS2> {};
/// \ingroup ColorSpaceAndLayoutConcept
/// \brief Two color spaces are compatible if they are the same
/// \code
/// concept ColorSpacesCompatibleConcept<ColorSpaceConcept CS1, ColorSpaceConcept CS2>
/// {
/// where SameType<CS1, CS2>;
/// };
/// \endcode
template <typename CS1, typename CS2>
struct ColorSpacesCompatibleConcept
{
void constraints()
{
static_assert(color_spaces_are_compatible<CS1, CS2>::value, "");
}
};
/// \ingroup ColorSpaceAndLayoutConcept
/// \brief Channel mapping concept
/// \code
/// concept ChannelMappingConcept<MPLRandomAccessSequence CM>
/// {
/// // Boost.MP11-compatible list, whose elements
/// // model MPLIntegralConstant representing a permutation
/// };
/// \endcode
template <typename CM>
struct ChannelMappingConcept
{
void constraints()
{
// Boost.MP11-compatible list, whose elements model
// MPLIntegralConstant representing a permutation.
// TODO: Is this incomplete?
}
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,329 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_COLOR_BASE_HPP
#define BOOST_GIL_CONCEPTS_COLOR_BASE_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/color.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <boost/core/ignore_unused.hpp>
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
// Forward declarations of at_c
namespace detail {
template <typename Element, typename Layout, int K>
struct homogeneous_color_base;
} // namespace detail
template <int K, typename E, typename L, int N>
auto at_c(detail::homogeneous_color_base<E, L, N>& p)
-> typename std::add_lvalue_reference<E>::type;
template <int K, typename E, typename L, int N>
auto at_c(detail::homogeneous_color_base<E, L, N> const& p)
-> typename std::add_lvalue_reference<typename std::add_const<E>::type>::type;
template <typename P, typename C, typename L>
struct packed_pixel;
template <int K, typename P, typename C, typename L>
auto at_c(packed_pixel<P, C, L>& p)
-> typename kth_element_reference_type<packed_pixel<P, C, L>, K>::type;
template <int K, typename P, typename C, typename L>
auto at_c(packed_pixel<P, C, L> const& p)
-> typename kth_element_const_reference_type<packed_pixel<P, C, L>, K>::type;
template <typename B, typename C, typename L, bool M>
struct bit_aligned_pixel_reference;
template <int K, typename B, typename C, typename L, bool M>
inline auto at_c(bit_aligned_pixel_reference<B, C, L, M> const& p)
-> typename kth_element_reference_type
<
bit_aligned_pixel_reference<B, C, L, M>,
K
>::type;
// Forward declarations of semantic_at_c
template <int K, typename ColorBase>
auto semantic_at_c(ColorBase& p)
-> typename std::enable_if
<
!std::is_const<ColorBase>::value,
typename kth_semantic_element_reference_type<ColorBase, K>::type
>::type;
template <int K, typename ColorBase>
auto semantic_at_c(ColorBase const& p)
-> typename kth_semantic_element_const_reference_type<ColorBase, K>::type;
/// \ingroup ColorBaseConcept
/// \brief A color base is a container of color elements (such as channels, channel references or channel pointers).
///
/// The most common use of color base is in the implementation of a pixel,
/// in which case the color elements are channel values. The color base concept,
/// however, can be used in other scenarios. For example, a planar pixel has
/// channels that are not contiguous in memory. Its reference is a proxy class
/// that uses a color base whose elements are channel references. Its iterator
/// uses a color base whose elements are channel iterators.
///
/// A color base must have an associated layout (which consists of a color space,
/// as well as an ordering of the channels).
/// There are two ways to index the elements of a color base: A physical index
/// corresponds to the way they are ordered in memory, and a semantic index
/// corresponds to the way the elements are ordered in their color space.
/// For example, in the RGB color space the elements are ordered as
/// {red_t, green_t, blue_t}. For a color base with a BGR layout, the first element
/// in physical ordering is the blue element, whereas the first semantic element
/// is the red one.
/// Models of \p ColorBaseConcept are required to provide the \p at_c<K>(ColorBase)
/// function, which allows for accessing the elements based on their physical order.
/// GIL provides a \p semantic_at_c<K>(ColorBase) function (described later)
/// which can operate on any model of ColorBaseConcept and returns the corresponding
/// semantic element.
///
/// \code
/// concept ColorBaseConcept<typename T> : CopyConstructible<T>, EqualityComparable<T>
/// {
/// // a GIL layout (the color space and element permutation)
/// typename layout_t;
///
/// // The type of K-th element
/// template <int K>
/// struct kth_element_type;
/// where Metafunction<kth_element_type>;
///
/// // The result of at_c
/// template <int K>
/// struct kth_element_const_reference_type;
/// where Metafunction<kth_element_const_reference_type>;
///
/// template <int K>
/// kth_element_const_reference_type<T,K>::type at_c(T);
///
/// // Copy-constructible and equality comparable with other compatible color bases
/// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
/// T::T(T2);
/// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
/// bool operator==(const T&, const T2&);
/// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
/// bool operator!=(const T&, const T2&);
/// };
/// \endcode
template <typename ColorBase>
struct ColorBaseConcept
{
void constraints()
{
gil_function_requires<CopyConstructible<ColorBase>>();
gil_function_requires<EqualityComparable<ColorBase>>();
using color_space_t = typename ColorBase::layout_t::color_space_t;
gil_function_requires<ColorSpaceConcept<color_space_t>>();
using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
// TODO: channel_mapping_t must be an Boost.MP11-compatible random access sequence
static const int num_elements = size<ColorBase>::value;
using TN = typename kth_element_type<ColorBase, num_elements - 1>::type;
using RN = typename kth_element_const_reference_type<ColorBase, num_elements - 1>::type;
RN r = gil::at_c<num_elements - 1>(cb);
boost::ignore_unused(r);
// functions that work for every pixel (no need to require them)
semantic_at_c<0>(cb);
semantic_at_c<num_elements-1>(cb);
// also static_max(cb), static_min(cb), static_fill(cb,value),
// and all variations of static_for_each(), static_generate(), static_transform()
}
ColorBase cb;
};
/// \ingroup ColorBaseConcept
/// \brief Color base which allows for modifying its elements
/// \code
/// concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T>
/// {
/// template <int K>
/// struct kth_element_reference_type; where Metafunction<kth_element_reference_type>;
///
/// template <int K>
/// kth_element_reference_type<kth_element_type<T,K>::type>::type at_c(T);
///
/// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
/// T& operator=(T&, const T2&);
/// };
/// \endcode
template <typename ColorBase>
struct MutableColorBaseConcept
{
void constraints()
{
gil_function_requires<ColorBaseConcept<ColorBase>>();
gil_function_requires<Assignable<ColorBase>>();
gil_function_requires<Swappable<ColorBase>>();
using R0 = typename kth_element_reference_type<ColorBase, 0>::type;
R0 r = gil::at_c<0>(cb);
gil::at_c<0>(cb) = r;
}
ColorBase cb;
};
/// \ingroup ColorBaseConcept
/// \brief Color base that also has a default-constructor. Refines Regular
/// \code
/// concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T>
/// {
/// };
/// \endcode
template <typename ColorBase>
struct ColorBaseValueConcept
{
void constraints()
{
gil_function_requires<MutableColorBaseConcept<ColorBase>>();
gil_function_requires<Regular<ColorBase>>();
}
};
/// \ingroup ColorBaseConcept
/// \brief Color base whose elements all have the same type
/// \code
/// concept HomogeneousColorBaseConcept<ColorBaseConcept CB>
/// {
/// // For all K in [0 ... size<C1>::value-1):
/// // where SameType<kth_element_type<CB,K>::type, kth_element_type<CB,K+1>::type>;
/// kth_element_const_reference_type<CB,0>::type dynamic_at_c(CB const&, std::size_t n) const;
/// };
/// \endcode
template <typename ColorBase>
struct HomogeneousColorBaseConcept
{
void constraints()
{
gil_function_requires<ColorBaseConcept<ColorBase>>();
static const int num_elements = size<ColorBase>::value;
using T0 = typename kth_element_type<ColorBase, 0>::type;
using TN = typename kth_element_type<ColorBase, num_elements - 1>::type;
static_assert(std::is_same<T0, TN>::value, ""); // better than nothing
using R0 = typename kth_element_const_reference_type<ColorBase, 0>::type;
R0 r = dynamic_at_c(cb, 0);
boost::ignore_unused(r);
}
ColorBase cb;
};
/// \ingroup ColorBaseConcept
/// \brief Homogeneous color base that allows for modifying its elements
/// \code
/// concept MutableHomogeneousColorBaseConcept<ColorBaseConcept CB>
/// : HomogeneousColorBaseConcept<CB>
/// {
/// kth_element_reference_type<CB, 0>::type dynamic_at_c(CB&, std::size_t n);
/// };
/// \endcode
template <typename ColorBase>
struct MutableHomogeneousColorBaseConcept
{
void constraints()
{
gil_function_requires<ColorBaseConcept<ColorBase>>();
gil_function_requires<HomogeneousColorBaseConcept<ColorBase>>();
using R0 = typename kth_element_reference_type<ColorBase, 0>::type;
R0 r = dynamic_at_c(cb, 0);
boost::ignore_unused(r);
dynamic_at_c(cb, 0) = dynamic_at_c(cb, 0);
}
ColorBase cb;
};
/// \ingroup ColorBaseConcept
/// \brief Homogeneous color base that also has a default constructor.
/// Refines Regular.
///
/// \code
/// concept HomogeneousColorBaseValueConcept<typename T>
/// : MutableHomogeneousColorBaseConcept<T>, Regular<T>
/// {
/// };
/// \endcode
template <typename ColorBase>
struct HomogeneousColorBaseValueConcept
{
void constraints()
{
gil_function_requires<MutableHomogeneousColorBaseConcept<ColorBase>>();
gil_function_requires<Regular<ColorBase>>();
}
};
/// \ingroup ColorBaseConcept
/// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise.
/// \code
/// concept ColorBasesCompatibleConcept<ColorBaseConcept C1, ColorBaseConcept C2>
/// {
/// where SameType<C1::layout_t::color_space_t, C2::layout_t::color_space_t>;
/// // also, for all K in [0 ... size<C1>::value):
/// // where Convertible<kth_semantic_element_type<C1,K>::type, kth_semantic_element_type<C2,K>::type>;
/// // where Convertible<kth_semantic_element_type<C2,K>::type, kth_semantic_element_type<C1,K>::type>;
/// };
/// \endcode
template <typename ColorBase1, typename ColorBase2>
struct ColorBasesCompatibleConcept
{
void constraints()
{
static_assert(std::is_same
<
typename ColorBase1::layout_t::color_space_t,
typename ColorBase2::layout_t::color_space_t
>::value, "");
// using e1 = typename kth_semantic_element_type<ColorBase1,0>::type;
// using e2 = typename kth_semantic_element_type<ColorBase2,0>::type;
// "e1 is convertible to e2"
}
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,60 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_CONCEPTS_CHECK_HPP
#define BOOST_GIL_CONCEPTS_CONCEPTS_CHECK_HPP
#include <boost/config.hpp>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wfloat-equal"
#pragma clang diagnostic ignored "-Wuninitialized"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
#include <boost/concept_check.hpp>
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
// TODO: Document BOOST_GIL_USE_CONCEPT_CHECK here
namespace boost { namespace gil {
// TODO: What is BOOST_GIL_CLASS_REQUIRE for; Why not use BOOST_CLASS_REQUIRE?
// TODO: What is gil_function_requires for; Why not function_requires?
#ifdef BOOST_GIL_USE_CONCEPT_CHECK
#define BOOST_GIL_CLASS_REQUIRE(type_var, ns, concept) \
BOOST_CLASS_REQUIRE(type_var, ns, concept);
template <typename Concept>
void gil_function_requires() { function_requires<Concept>(); }
#else
#define BOOST_GIL_CLASS_REQUIRE(type_var, ns, concept)
template <typename C>
void gil_function_requires() {}
#endif
}} // namespace boost::gil:
#endif

View File

@@ -0,0 +1,24 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_DETAIL_TYPE_TRAITS_HPP
#define BOOST_GIL_CONCEPTS_DETAIL_TYPE_TRAITS_HPP
#include <type_traits>
namespace boost { namespace gil { namespace detail {
// TODO: C++20: deprecate and replace with std::std_remove_cvref
template <typename T>
struct remove_const_and_reference
: std::remove_const<typename std::remove_reference<T>::type>
{
};
}}} // namespace boost::gil::detail
#endif

View File

@@ -0,0 +1,19 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_DETAIL_UTILITY_HPP
#define BOOST_GIL_CONCEPTS_DETAIL_UTILITY_HPP
namespace boost { namespace gil { namespace detail {
// TODO: Remove, replace with ignore_unised?
template <typename T>
void initialize_it(T&) {}
}}} // namespace boost::gil::detail
#endif

View File

@@ -0,0 +1,78 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_DYNAMIC_STEP_HPP
#define BOOST_GIL_CONCEPTS_DYNAMIC_STEP_HPP
#include <boost/gil/concepts/fwd.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
/// \ingroup PixelIteratorConcept
/// \brief Concept for iterators, locators and views that can define a type just like the given
/// iterator, locator or view, except it supports runtime specified step along the X navigation.
///
/// \code
/// concept HasDynamicXStepTypeConcept<typename T>
/// {
/// typename dynamic_x_step_type<T>;
/// where Metafunction<dynamic_x_step_type<T> >;
/// };
/// \endcode
template <typename T>
struct HasDynamicXStepTypeConcept
{
void constraints()
{
using type = typename dynamic_x_step_type<T>::type;
ignore_unused_variable_warning(type{});
}
};
/// \ingroup PixelLocatorConcept
/// \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
/// \code
/// concept HasDynamicYStepTypeConcept<typename T>
/// {
/// typename dynamic_y_step_type<T>;
/// where Metafunction<dynamic_y_step_type<T> >;
/// };
/// \endcode
template <typename T>
struct HasDynamicYStepTypeConcept
{
void constraints()
{
using type = typename dynamic_y_step_type<T>::type;
ignore_unused_variable_warning(type{});
}
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,36 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_FWD_HPP
#define BOOST_GIL_CONCEPTS_FWD_HPP
namespace boost { namespace gil {
// Forward declarations used by concepts
template <typename ColorBase, int K> struct kth_element_type;
template <typename ColorBase, int K> struct kth_element_reference_type;
template <typename ColorBase, int K> struct kth_element_const_reference_type;
template <typename ColorBase, int K> struct kth_semantic_element_reference_type;
template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type;
template <typename ColorBase> struct size;
template <typename ColorBase> struct element_type;
template <typename T> struct is_pixel;
template <typename T> struct is_planar;
template <typename T> struct channel_type;
template <typename T> struct color_space_type;
template <typename T> struct channel_mapping_type;
template <typename T> struct num_channels;
template <typename T> struct dynamic_x_step_type;
template <typename T> struct dynamic_y_step_type;
template <typename T> struct transposed_type;
}} // namespace boost::gil
#endif

View File

@@ -0,0 +1,169 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_IMAGE_HPP
#define BOOST_GIL_CONCEPTS_IMAGE_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <boost/gil/concepts/image_view.hpp>
#include <boost/gil/concepts/point.hpp>
#include <boost/gil/detail/mp11.hpp>
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
/// \ingroup ImageConcept
/// \brief N-dimensional container of values
///
/// \code
/// concept RandomAccessNDImageConcept<typename Image> : Regular<Image>
/// {
/// typename view_t; where MutableRandomAccessNDImageViewConcept<view_t>;
/// typename const_view_t = view_t::const_t;
/// typename point_t = view_t::point_t;
/// typename value_type = view_t::value_type;
/// typename allocator_type;
///
/// Image::Image(point_t dims, std::size_t alignment=1);
/// Image::Image(point_t dims, value_type fill_value, std::size_t alignment);
///
/// void Image::recreate(point_t new_dims, std::size_t alignment=1);
/// void Image::recreate(point_t new_dims, value_type fill_value, std::size_t alignment);
///
/// const point_t& Image::dimensions() const;
/// const const_view_t& const_view(const Image&);
/// const view_t& view(Image&);
/// };
/// \endcode
template <typename Image>
struct RandomAccessNDImageConcept
{
void constraints()
{
gil_function_requires<Regular<Image>>();
using view_t = typename Image::view_t;
gil_function_requires<MutableRandomAccessNDImageViewConcept<view_t>>();
using const_view_t = typename Image::const_view_t;
using pixel_t = typename Image::value_type;
using point_t = typename Image::point_t;
gil_function_requires<PointNDConcept<point_t>>();
const_view_t cv = const_view(image);
ignore_unused_variable_warning(cv);
view_t v = view(image);
ignore_unused_variable_warning(v);
pixel_t fill_value;
point_t pt = image.dimensions();
Image image1(pt);
Image image2(pt, 1);
Image image3(pt, fill_value, 1);
image.recreate(pt);
image.recreate(pt, 1);
image.recreate(pt, fill_value, 1);
}
Image image;
};
/// \ingroup ImageConcept
/// \brief 2-dimensional container of values
///
/// \code
/// concept RandomAccess2DImageConcept<RandomAccessNDImageConcept Image>
/// {
/// typename x_coord_t = const_view_t::x_coord_t;
/// typename y_coord_t = const_view_t::y_coord_t;
///
/// Image::Image(x_coord_t width, y_coord_t height, std::size_t alignment=1);
/// Image::Image(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
///
/// x_coord_t Image::width() const;
/// y_coord_t Image::height() const;
///
/// void Image::recreate(x_coord_t width, y_coord_t height, std::size_t alignment=1);
/// void Image::recreate(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
/// };
/// \endcode
template <typename Image>
struct RandomAccess2DImageConcept
{
void constraints()
{
gil_function_requires<RandomAccessNDImageConcept<Image>>();
using x_coord_t = typename Image::x_coord_t;
using y_coord_t = typename Image::y_coord_t;
using value_t = typename Image::value_type;
gil_function_requires<MutableRandomAccess2DImageViewConcept<typename Image::view_t>>();
x_coord_t w=image.width();
y_coord_t h=image.height();
value_t fill_value;
Image im1(w,h);
Image im2(w,h,1);
Image im3(w,h,fill_value,1);
image.recreate(w,h);
image.recreate(w,h,1);
image.recreate(w,h,fill_value,1);
}
Image image;
};
/// \ingroup ImageConcept
/// \brief 2-dimensional image whose value type models PixelValueConcept
///
/// \code
/// concept ImageConcept<RandomAccess2DImageConcept Image>
/// {
/// where MutableImageViewConcept<view_t>;
/// typename coord_t = view_t::coord_t;
/// };
/// \endcode
template <typename Image>
struct ImageConcept
{
void constraints()
{
gil_function_requires<RandomAccess2DImageConcept<Image>>();
gil_function_requires<MutableImageViewConcept<typename Image::view_t>>();
using coord_t = typename Image::coord_t;
static_assert(num_channels<Image>::value == mp11::mp_size<typename color_space_type<Image>::type>::value, "");
static_assert(std::is_same<coord_t, typename Image::x_coord_t>::value, "");
static_assert(std::is_same<coord_t, typename Image::y_coord_t>::value, "");
}
Image image;
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,557 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
#define BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <boost/gil/concepts/pixel.hpp>
#include <boost/gil/concepts/pixel_dereference.hpp>
#include <boost/gil/concepts/pixel_iterator.hpp>
#include <boost/gil/concepts/pixel_locator.hpp>
#include <boost/gil/concepts/point.hpp>
#include <boost/gil/concepts/detail/utility.hpp>
#include <cstddef>
#include <iterator>
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif
namespace boost { namespace gil {
/// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
/// \ingroup ImageViewConcept
/// \brief N-dimensional range
/// \defgroup ImageView2DConcept ImageView2DLocatorConcept
/// \ingroup ImageViewConcept
/// \brief 2-dimensional range
/// \defgroup PixelImageViewConcept ImageViewConcept
/// \ingroup ImageViewConcept
/// \brief 2-dimensional range over pixel data
/// \ingroup ImageViewNDConcept
/// \brief N-dimensional view over immutable values
///
/// \code
/// concept RandomAccessNDImageViewConcept<Regular View>
/// {
/// typename value_type;
/// typename reference; // result of dereferencing
/// typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
/// typename const_t; where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
/// typename point_t; where PointNDConcept<point_t>; // N-dimensional point
/// typename locator; where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
/// typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
/// typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
/// typename size_type; // the return value of size()
///
/// // Equivalent to RandomAccessNDLocatorConcept::axis
/// template <size_t D> struct axis {
/// typename coord_t = point_t::axis<D>::coord_t;
/// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
/// where SameType<coord_t, iterator::difference_type>;
/// where SameType<iterator::value_type,value_type>;
/// };
///
/// // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
/// template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
/// typename type; where RandomAccessNDImageViewConcept<type>;
/// static type make(const View& v, const Deref& deref);
/// };
///
/// static const size_t num_dimensions = point_t::num_dimensions;
///
/// // Create from a locator at the top-left corner and dimensions
/// View::View(const locator&, const point_type&);
///
/// size_type View::size() const; // total number of elements
/// reference operator[](View, const difference_type&) const; // 1-dimensional reference
/// iterator View::begin() const;
/// iterator View::end() const;
/// reverse_iterator View::rbegin() const;
/// reverse_iterator View::rend() const;
/// iterator View::at(const point_t&);
/// point_t View::dimensions() const; // number of elements along each dimension
/// bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
///
/// // iterator along a given dimension starting at a given point
/// template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;
///
/// reference operator()(View,const point_t&) const;
/// };
/// \endcode
template <typename View>
struct RandomAccessNDImageViewConcept
{
void constraints()
{
gil_function_requires<Regular<View>>();
using value_type = typename View::value_type;
using reference = typename View::reference; // result of dereferencing
using pointer = typename View::pointer;
using difference_type = typename View::difference_type; // result of operator-(1d_iterator,1d_iterator)
using const_t = typename View::const_t; // same as this type, but over const values
using point_t = typename View::point_t; // N-dimensional point
using locator = typename View::locator; // N-dimensional locator
using iterator = typename View::iterator;
using const_iterator = typename View::const_iterator;
using reverse_iterator = typename View::reverse_iterator;
using size_type = typename View::size_type;
static const std::size_t N=View::num_dimensions;
gil_function_requires<RandomAccessNDLocatorConcept<locator>>();
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator>>();
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator>>();
using first_it_type = typename View::template axis<0>::iterator;
using last_it_type = typename View::template axis<N-1>::iterator;
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
// static_assert(typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value, "");
// static_assert(typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value, "");
// point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
gil_function_requires<PointNDConcept<point_t>>();
static_assert(point_t::num_dimensions == N, "");
static_assert(std::is_same
<
typename std::iterator_traits<first_it_type>::difference_type,
typename point_t::template axis<0>::coord_t
>::value, "");
static_assert(std::is_same
<
typename std::iterator_traits<last_it_type>::difference_type,
typename point_t::template axis<N-1>::coord_t
>::value, "");
point_t p;
locator lc;
iterator it;
reverse_iterator rit;
difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
View(p,lc); // view must be constructible from a locator and a point
p = view.dimensions();
lc = view.pixels();
size_type sz = view.size(); ignore_unused_variable_warning(sz);
bool is_contiguous = view.is_1d_traversable();
ignore_unused_variable_warning(is_contiguous);
it = view.begin();
it = view.end();
rit = view.rbegin();
rit = view.rend();
reference r1 = view[d]; ignore_unused_variable_warning(r1); // 1D access
reference r2 = view(p); ignore_unused_variable_warning(r2); // 2D access
// get 1-D iterator of any dimension at a given pixel location
first_it_type fi = view.template axis_iterator<0>(p);
ignore_unused_variable_warning(fi);
last_it_type li = view.template axis_iterator<N-1>(p);
ignore_unused_variable_warning(li);
using deref_t = PixelDereferenceAdaptorArchetype<typename View::value_type>;
using dtype = typename View::template add_deref<deref_t>::type;
}
View view;
};
/// \ingroup ImageView2DConcept
/// \brief 2-dimensional view over immutable values
///
/// \code
/// concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
/// where num_dimensions==2;
///
/// typename x_iterator = axis<0>::iterator;
/// typename y_iterator = axis<1>::iterator;
/// typename x_coord_t = axis<0>::coord_t;
/// typename y_coord_t = axis<1>::coord_t;
/// typename xy_locator = locator;
///
/// x_coord_t View::width() const;
/// y_coord_t View::height() const;
///
/// // X-navigation
/// x_iterator View::x_at(const point_t&) const;
/// x_iterator View::row_begin(y_coord_t) const;
/// x_iterator View::row_end (y_coord_t) const;
///
/// // Y-navigation
/// y_iterator View::y_at(const point_t&) const;
/// y_iterator View::col_begin(x_coord_t) const;
/// y_iterator View::col_end (x_coord_t) const;
///
/// // navigating in 2D
/// xy_locator View::xy_at(const point_t&) const;
///
/// // (x,y) versions of all methods taking point_t
/// View::View(x_coord_t,y_coord_t,const locator&);
/// iterator View::at(x_coord_t,y_coord_t) const;
/// reference operator()(View,x_coord_t,y_coord_t) const;
/// xy_locator View::xy_at(x_coord_t,y_coord_t) const;
/// x_iterator View::x_at(x_coord_t,y_coord_t) const;
/// y_iterator View::y_at(x_coord_t,y_coord_t) const;
/// };
/// \endcode
template <typename View>
struct RandomAccess2DImageViewConcept
{
void constraints()
{
gil_function_requires<RandomAccessNDImageViewConcept<View>>();
static_assert(View::num_dimensions == 2, "");
// TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator>>();
using dynamic_x_step_t = typename dynamic_x_step_type<View>::type;
using dynamic_y_step_t = typename dynamic_y_step_type<View>::type;
using transposed_t = typename transposed_type<View>::type;
using x_iterator = typename View::x_iterator;
using y_iterator = typename View::y_iterator;
using x_coord_t = typename View::x_coord_t;
using y_coord_t = typename View::y_coord_t;
using xy_locator = typename View::xy_locator;
x_coord_t xd = 0; ignore_unused_variable_warning(xd);
y_coord_t yd = 0; ignore_unused_variable_warning(yd);
x_iterator xit;
y_iterator yit;
typename View::point_t d;
View(xd, yd, xy_locator()); // constructible with width, height, 2d_locator
xy_locator lc = view.xy_at(xd, yd);
lc = view.xy_at(d);
typename View::reference r = view(xd, yd);
ignore_unused_variable_warning(r);
xd = view.width();
yd = view.height();
xit = view.x_at(d);
xit = view.x_at(xd,yd);
xit = view.row_begin(xd);
xit = view.row_end(xd);
yit = view.y_at(d);
yit = view.y_at(xd,yd);
yit = view.col_begin(xd);
yit = view.col_end(xd);
}
View view;
};
/// \brief GIL view as Collection.
///
/// \see https://www.boost.org/libs/utility/Collection.html
///
template <typename View>
struct CollectionImageViewConcept
{
void constraints()
{
using value_type = typename View::value_type;
using iterator = typename View::iterator;
using const_iterator = typename View::const_iterator;
using reference = typename View::reference;
using const_reference = typename View::const_reference;
using pointer = typename View::pointer;
using difference_type = typename View::difference_type;
using size_type= typename View::size_type;
iterator i;
i = view1.begin();
i = view2.end();
const_iterator ci;
ci = view1.begin();
ci = view2.end();
size_type s;
s = view1.size();
s = view2.size();
ignore_unused_variable_warning(s);
view1.empty();
view1.swap(view2);
}
View view1;
View view2;
};
/// \brief GIL view as ForwardCollection.
///
/// \see https://www.boost.org/libs/utility/Collection.html
///
template <typename View>
struct ForwardCollectionImageViewConcept
{
void constraints()
{
gil_function_requires<CollectionImageViewConcept<View>>();
using reference = typename View::reference;
using const_reference = typename View::const_reference;
reference r = view.front();
ignore_unused_variable_warning(r);
const_reference cr = view.front();
ignore_unused_variable_warning(cr);
}
View view;
};
/// \brief GIL view as ReversibleCollection.
///
/// \see https://www.boost.org/libs/utility/Collection.html
///
template <typename View>
struct ReversibleCollectionImageViewConcept
{
void constraints()
{
gil_function_requires<CollectionImageViewConcept<View>>();
using reverse_iterator = typename View::reverse_iterator;
using reference = typename View::reference;
using const_reference = typename View::const_reference;
reverse_iterator i;
i = view.rbegin();
i = view.rend();
reference r = view.back();
ignore_unused_variable_warning(r);
const_reference cr = view.back();
ignore_unused_variable_warning(cr);
}
View view;
};
/// \ingroup PixelImageViewConcept
/// \brief GIL's 2-dimensional view over immutable GIL pixels
/// \code
/// concept ImageViewConcept<RandomAccess2DImageViewConcept View>
/// {
/// where PixelValueConcept<value_type>;
/// where PixelIteratorConcept<x_iterator>;
/// where PixelIteratorConcept<y_iterator>;
/// where x_coord_t == y_coord_t;
///
/// typename coord_t = x_coord_t;
///
/// std::size_t View::num_channels() const;
/// };
/// \endcode
template <typename View>
struct ImageViewConcept
{
void constraints()
{
gil_function_requires<RandomAccess2DImageViewConcept<View>>();
// TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
gil_function_requires<PixelLocatorConcept<typename View::xy_locator>>();
static_assert(std::is_same<typename View::x_coord_t, typename View::y_coord_t>::value, "");
using coord_t = typename View::coord_t; // 1D difference type (same for all dimensions)
std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
}
View view;
};
namespace detail {
/// \tparam View Models RandomAccessNDImageViewConcept
template <typename View>
struct RandomAccessNDImageViewIsMutableConcept
{
void constraints()
{
gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator>>();
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator>>();
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
<
typename View::reverse_iterator
>>();
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
<
typename View::template axis<0>::iterator
>>();
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
<
typename View::template axis<View::num_dimensions - 1>::iterator
>>();
typename View::difference_type diff;
initialize_it(diff);
ignore_unused_variable_warning(diff);
typename View::point_t pt;
typename View::value_type v;
initialize_it(v);
view[diff] = v;
view(pt) = v;
}
View view;
};
/// \tparam View Models RandomAccessNDImageViewConcept
template <typename View>
struct RandomAccess2DImageViewIsMutableConcept
{
void constraints()
{
gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
typename View::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
typename View::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
typename View::value_type v; initialize_it(v);
view(xd, yd) = v;
}
View view;
};
/// \tparam View Models ImageViewConcept
template <typename View>
struct PixelImageViewIsMutableConcept
{
void constraints()
{
gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
}
};
} // namespace detail
/// \ingroup ImageViewNDConcept
/// \brief N-dimensional view over mutable values
///
/// \code
/// concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View>
/// {
/// where Mutable<reference>;
/// };
/// \endcode
template <typename View>
struct MutableRandomAccessNDImageViewConcept
{
void constraints()
{
gil_function_requires<RandomAccessNDImageViewConcept<View>>();
gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
}
};
/// \ingroup ImageView2DConcept
/// \brief 2-dimensional view over mutable values
///
/// \code
/// concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View>
/// : MutableRandomAccessNDImageViewConcept<View> {};
/// \endcode
template <typename View>
struct MutableRandomAccess2DImageViewConcept
{
void constraints()
{
gil_function_requires<RandomAccess2DImageViewConcept<View>>();
gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
}
};
/// \ingroup PixelImageViewConcept
/// \brief GIL's 2-dimensional view over mutable GIL pixels
///
/// \code
/// concept MutableImageViewConcept<ImageViewConcept View>
/// : MutableRandomAccess2DImageViewConcept<View> {};
/// \endcode
template <typename View>
struct MutableImageViewConcept
{
void constraints()
{
gil_function_requires<ImageViewConcept<View>>();
gil_function_requires<detail::PixelImageViewIsMutableConcept<View>>();
}
};
/// \brief Returns whether two views are compatible
///
/// Views are compatible if their pixels are compatible.
/// Compatible views can be assigned and copy constructed from one another.
///
/// \tparam V1 Models ImageViewConcept
/// \tparam V2 Models ImageViewConcept
///
template <typename V1, typename V2>
struct views_are_compatible
: pixels_are_compatible<typename V1::value_type, typename V2::value_type>
{
};
/// \ingroup ImageViewConcept
/// \brief Views are compatible if they have the same color spaces and compatible channel values.
///
/// Constness and layout are not important for compatibility.
///
/// \code
/// concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2>
/// {
/// where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
/// };
/// \endcode
template <typename V1, typename V2>
struct ViewsCompatibleConcept
{
void constraints()
{
static_assert(views_are_compatible<V1, V2>::value, "");
}
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,299 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_PIXEL_HPP
#define BOOST_GIL_CONCEPTS_PIXEL_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/channel.hpp>
#include <boost/gil/concepts/color.hpp>
#include <boost/gil/concepts/color_base.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <boost/gil/concepts/pixel_based.hpp>
#include <boost/gil/concepts/detail/type_traits.hpp>
#include <boost/gil/detail/mp11.hpp>
#include <cstddef>
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
/// \brief Pixel concept - A color base whose elements are channels
/// \ingroup PixelConcept
/// \code
/// concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P>
/// {
/// where is_pixel<P>::value == true;
/// // where for each K [0..size<P>::value - 1]:
/// // ChannelConcept<kth_element_type<P, K>>;
///
/// typename P::value_type;
/// where PixelValueConcept<value_type>;
/// typename P::reference;
/// where PixelConcept<reference>;
/// typename P::const_reference;
/// where PixelConcept<const_reference>;
/// static const bool P::is_mutable;
///
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
/// P::P(P2);
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
/// bool operator==(const P&, const P2&);
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
/// bool operator!=(const P&, const P2&);
/// };
/// \endcode
template <typename P>
struct PixelConcept
{
void constraints()
{
gil_function_requires<ColorBaseConcept<P>>();
gil_function_requires<PixelBasedConcept<P>>();
static_assert(is_pixel<P>::value, "");
static const bool is_mutable = P::is_mutable;
ignore_unused_variable_warning(is_mutable);
using value_type = typename P::value_type;
// TODO: Is the cyclic dependency intentional? --mloskot
// gil_function_requires<PixelValueConcept<value_type>>();
using reference = typename P::reference;
gil_function_requires<PixelConcept
<
typename detail::remove_const_and_reference<reference>::type
>>();
using const_reference = typename P::const_reference;
gil_function_requires<PixelConcept
<
typename detail::remove_const_and_reference<const_reference>::type
>>();
}
};
/// \brief Pixel concept that allows for changing its channels
/// \ingroup PixelConcept
/// \code
/// concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P>
/// {
/// where is_mutable==true;
/// };
/// \endcode
template <typename P>
struct MutablePixelConcept
{
void constraints()
{
gil_function_requires<PixelConcept<P>>();
static_assert(P::is_mutable, "");
}
};
/// \brief Homogeneous pixel concept
/// \ingroup PixelConcept
/// \code
/// concept HomogeneousPixelConcept<PixelConcept P>
/// : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P>
/// {
/// P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const
/// {
/// return dynamic_at_c(p,i);
/// }
/// };
/// \endcode
template <typename P>
struct HomogeneousPixelConcept
{
void constraints()
{
gil_function_requires<PixelConcept<P>>();
gil_function_requires<HomogeneousColorBaseConcept<P>>();
gil_function_requires<HomogeneousPixelBasedConcept<P>>();
p[0];
}
P p;
};
/// \brief Homogeneous pixel concept that allows for changing its channels
/// \ingroup PixelConcept
/// \code
/// concept MutableHomogeneousPixelConcept<HomogeneousPixelConcept P>
/// : MutableHomogeneousColorBaseConcept<P>
/// {
/// P::template element_reference_type<P>::type operator[](P p, std::size_t i)
/// {
/// return dynamic_at_c(p, i);
/// }
/// };
/// \endcode
template <typename P>
struct MutableHomogeneousPixelConcept
{
void constraints()
{
gil_function_requires<HomogeneousPixelConcept<P>>();
gil_function_requires<MutableHomogeneousColorBaseConcept<P>>();
p[0] = v;
v = p[0];
}
typename P::template element_type<P>::type v;
P p;
};
/// \brief Pixel concept that is a Regular type
/// \ingroup PixelConcept
/// \code
/// concept PixelValueConcept<PixelConcept P> : Regular<P>
/// {
/// where SameType<value_type,P>;
/// };
/// \endcode
template <typename P>
struct PixelValueConcept
{
void constraints()
{
gil_function_requires<PixelConcept<P>>();
gil_function_requires<Regular<P>>();
}
};
/// \brief Homogeneous pixel concept that is a Regular type
/// \ingroup PixelConcept
/// \code
/// concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P>
/// {
/// where SameType<value_type,P>;
/// };
/// \endcode
template <typename P>
struct HomogeneousPixelValueConcept
{
void constraints()
{
gil_function_requires<HomogeneousPixelConcept<P>>();
gil_function_requires<Regular<P>>();
static_assert(std::is_same<P, typename P::value_type>::value, "");
}
};
namespace detail {
template <typename P1, typename P2, int K>
struct channels_are_pairwise_compatible
: mp11::mp_and
<
channels_are_pairwise_compatible<P1, P2, K - 1>,
channels_are_compatible
<
typename kth_semantic_element_reference_type<P1, K>::type,
typename kth_semantic_element_reference_type<P2, K>::type
>
>
{
};
template <typename P1, typename P2>
struct channels_are_pairwise_compatible<P1, P2, -1> : std::true_type {};
} // namespace detail
/// \ingroup PixelAlgorithm
/// \brief Returns whether two pixels are compatible
/// Pixels are compatible if their channels and color space types are compatible.
/// Compatible pixels can be assigned and copy constructed from one another.
/// \tparam P1 Models PixelConcept
/// \tparam P2 Models PixelConcept
template <typename P1, typename P2>
struct pixels_are_compatible
: mp11::mp_and
<
typename color_spaces_are_compatible
<
typename color_space_type<P1>::type,
typename color_space_type<P2>::type
>::type,
detail::channels_are_pairwise_compatible
<
P1, P2, num_channels<P1>::value - 1
>
>
{
};
/// \ingroup PixelConcept
/// \brief Concept for pixel compatibility
/// Pixels are compatible if their channels and color space types are compatible.
/// Compatible pixels can be assigned and copy constructed from one another.
/// \tparam P1 Models PixelConcept
/// \tparam P2 Models PixelConcept
/// \code
/// concept PixelsCompatibleConcept<PixelConcept P1, PixelConcept P2>
/// : ColorBasesCompatibleConcept<P1,P2> {
/// // where for each K [0..size<P1>::value):
/// // ChannelsCompatibleConcept<kth_semantic_element_type<P1,K>::type, kth_semantic_element_type<P2,K>::type>;
/// };
/// \endcode
template <typename P1, typename P2>
struct PixelsCompatibleConcept
{
void constraints()
{
static_assert(pixels_are_compatible<P1, P2>::value, "");
}
};
/// \ingroup PixelConcept
/// \brief Pixel convertible concept
/// Convertibility is non-symmetric and implies that one pixel
/// can be converted to another, approximating the color.
/// Conversion is explicit and sometimes lossy.
/// \code
/// template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
/// concept PixelConvertibleConcept
/// {
/// void color_convert(const SrcPixel&, DstPixel&);
/// };
/// \endcode
template <typename SrcP, typename DstP>
struct PixelConvertibleConcept
{
void constraints()
{
gil_function_requires<PixelConcept<SrcP>>();
gil_function_requires<MutablePixelConcept<DstP>>();
color_convert(src, dst);
}
SrcP src;
DstP dst;
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,104 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_PIXEL_BASED_HPP
#define BOOST_GIL_CONCEPTS_PIXEL_BASED_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/channel.hpp>
#include <boost/gil/concepts/color.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <cstddef>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
/// \ingroup PixelBasedConcept
/// \brief Concept for all pixel-based GIL constructs.
///
/// Pixel-based constructs include pixels, iterators, locators, views and
/// images whose value type is a pixel.
///
/// \code
/// concept PixelBasedConcept<typename T>
/// {
/// typename color_space_type<T>;
/// where Metafunction<color_space_type<T> >;
/// where ColorSpaceConcept<color_space_type<T>::type>;
/// typename channel_mapping_type<T>;
/// where Metafunction<channel_mapping_type<T> >;
/// where ChannelMappingConcept<channel_mapping_type<T>::type>;
/// typename is_planar<T>;
/// where Metafunction<is_planar<T> >;
/// where SameType<is_planar<T>::type, bool>;
/// };
/// \endcode
template <typename P>
struct PixelBasedConcept
{
void constraints()
{
using color_space_t = typename color_space_type<P>::type;
gil_function_requires<ColorSpaceConcept<color_space_t>>();
using channel_mapping_t = typename channel_mapping_type<P>::type ;
gil_function_requires<ChannelMappingConcept<channel_mapping_t>>();
static const bool planar = is_planar<P>::value;
ignore_unused_variable_warning(planar);
// This is not part of the concept, but should still work
static const std::size_t nc = num_channels<P>::value;
ignore_unused_variable_warning(nc);
}
};
/// \brief Concept for homogeneous pixel-based GIL constructs
/// \ingroup PixelBasedConcept
/// \code
/// concept HomogeneousPixelBasedConcept<PixelBasedConcept T>
/// {
/// typename channel_type<T>;
/// where Metafunction<channel_type<T>>;
/// where ChannelConcept<channel_type<T>::type>;
/// };
/// \endcode
template <typename P>
struct HomogeneousPixelBasedConcept
{
void constraints()
{
gil_function_requires<PixelBasedConcept<P>>();
using channel_t = typename channel_type<P>::type;
gil_function_requires<ChannelConcept<channel_t>>();
}
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,115 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_PIXEL_DEREFERENCE_HPP
#define BOOST_GIL_CONCEPTS_PIXEL_DEREFERENCE_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <boost/gil/concepts/pixel.hpp>
#include <boost/gil/concepts/detail/type_traits.hpp>
#include <boost/concept_check.hpp>
#include <cstddef>
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
/// \ingroup PixelDereferenceAdaptorConcept
/// \brief Represents a unary function object that can be invoked upon dereferencing a pixel iterator.
///
/// This can perform an arbitrary computation, such as color conversion or table lookup.
/// \code
/// concept PixelDereferenceAdaptorConcept<boost::UnaryFunctionConcept D>
/// : DefaultConstructibleConcept<D>, CopyConstructibleConcept<D>, AssignableConcept<D>
/// {
/// typename const_t; where PixelDereferenceAdaptorConcept<const_t>;
/// typename value_type; where PixelValueConcept<value_type>;
/// typename reference; // may be mutable
/// typename const_reference; // must not be mutable
/// static const bool D::is_mutable;
///
/// where Convertible<value_type,result_type>;
/// };
/// \endcode
template <typename D>
struct PixelDereferenceAdaptorConcept
{
void constraints()
{
gil_function_requires
<
boost::UnaryFunctionConcept
<
D,
typename detail::remove_const_and_reference<typename D::result_type>::type,
typename D::argument_type
>
>();
gil_function_requires<boost::DefaultConstructibleConcept<D>>();
gil_function_requires<boost::CopyConstructibleConcept<D>>();
gil_function_requires<boost::AssignableConcept<D>>();
gil_function_requires<PixelConcept
<
typename detail::remove_const_and_reference<typename D::result_type>::type
>>();
using const_t = typename D::const_t;
gil_function_requires<PixelDereferenceAdaptorConcept<const_t>>();
using value_type = typename D::value_type;
gil_function_requires<PixelValueConcept<value_type>>();
// TODO: Should this be concept-checked after "if you remove const and reference"? --mloskot
using reference = typename D::reference; // == PixelConcept (if you remove const and reference)
using const_reference = typename D::const_reference; // == PixelConcept (if you remove const and reference)
bool const is_mutable = D::is_mutable;
ignore_unused_variable_warning(is_mutable);
}
D d;
};
template <typename P>
struct PixelDereferenceAdaptorArchetype
{
using argument_type = P;
using result_type = P;
using const_t = PixelDereferenceAdaptorArchetype;
using value_type = typename std::remove_reference<P>::type;
using reference = typename std::add_lvalue_reference<P>::type;
using const_reference = reference;
static const bool is_mutable = false;
P operator()(P) const { throw; }
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,361 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_PIXEL_ITERATOR_HPP
#define BOOST_GIL_CONCEPTS_PIXEL_ITERATOR_HPP
#include <boost/gil/concepts/channel.hpp>
#include <boost/gil/concepts/color.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <boost/gil/concepts/pixel.hpp>
#include <boost/gil/concepts/pixel_based.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <cstddef>
#include <iterator>
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
// Forward declarations
template <typename It> struct const_iterator_type;
template <typename It> struct iterator_is_mutable;
template <typename It> struct is_iterator_adaptor;
template <typename It, typename NewBaseIt> struct iterator_adaptor_rebind;
template <typename It> struct iterator_adaptor_get_base;
// These iterator mutability concepts are taken from Boost concept_check.hpp.
// Isolating mutability to result in faster compile time
namespace detail {
// Preconditions: TT Models boost_concepts::ForwardTraversalConcept
template <class TT>
struct ForwardIteratorIsMutableConcept
{
void constraints()
{
auto const tmp = *i;
*i++ = tmp; // require postincrement and assignment
}
TT i;
};
// Preconditions: TT Models boost::BidirectionalIteratorConcept
template <class TT>
struct BidirectionalIteratorIsMutableConcept
{
void constraints()
{
gil_function_requires< ForwardIteratorIsMutableConcept<TT>>();
auto const tmp = *i;
*i-- = tmp; // require postdecrement and assignment
}
TT i;
};
// Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept
template <class TT>
struct RandomAccessIteratorIsMutableConcept
{
void constraints()
{
gil_function_requires<BidirectionalIteratorIsMutableConcept<TT>>();
typename std::iterator_traits<TT>::difference_type n = 0;
ignore_unused_variable_warning(n);
i[n] = *i; // require element access and assignment
}
TT i;
};
// Iterators that can be used as the base of memory_based_step_iterator require some additional functions
// \tparam Iterator Models boost_concepts::RandomAccessTraversalConcept
template <typename Iterator>
struct RandomAccessIteratorIsMemoryBasedConcept
{
void constraints()
{
std::ptrdiff_t bs = memunit_step(it);
ignore_unused_variable_warning(bs);
it = memunit_advanced(it, 3);
std::ptrdiff_t bd = memunit_distance(it, it);
ignore_unused_variable_warning(bd);
memunit_advance(it,3);
// for performace you may also provide a customized implementation of memunit_advanced_ref
}
Iterator it;
};
/// \tparam Iterator Models PixelIteratorConcept
template <typename Iterator>
struct PixelIteratorIsMutableConcept
{
void constraints()
{
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<Iterator>>();
using ref_t = typename std::remove_reference
<
typename std::iterator_traits<Iterator>::reference
>::type;
using channel_t = typename element_type<ref_t>::type;
gil_function_requires<detail::ChannelIsMutableConcept<channel_t>>();
}
};
} // namespace detail
/// \ingroup PixelLocatorConcept
/// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped
/// \code
/// concept HasTransposedTypeConcept<typename T>
/// {
/// typename transposed_type<T>;
/// where Metafunction<transposed_type<T> >;
/// };
/// \endcode
template <typename T>
struct HasTransposedTypeConcept
{
void constraints()
{
using type = typename transposed_type<T>::type;
ignore_unused_variable_warning(type{});
}
};
/// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept
/// \ingroup PixelIteratorConcept
/// \brief STL iterator over pixels
/// \ingroup PixelIteratorConceptPixelIterator
/// \brief An STL random access traversal iterator over a model of PixelConcept.
///
/// GIL's iterators must also provide the following metafunctions:
/// - \p const_iterator_type<Iterator>: Returns a read-only equivalent of \p Iterator
/// - \p iterator_is_mutable<Iterator>: Returns whether the given iterator is read-only or mutable
/// - \p is_iterator_adaptor<Iterator>: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors.
///
/// \code
/// concept PixelIteratorConcept<typename Iterator>
/// : boost_concepts::RandomAccessTraversalConcept<Iterator>, PixelBasedConcept<Iterator>
/// {
/// where PixelValueConcept<value_type>;
/// typename const_iterator_type<It>::type;
/// where PixelIteratorConcept<const_iterator_type<It>::type>;
/// static const bool iterator_is_mutable<It>::value;
/// static const bool is_iterator_adaptor<It>::value; // is it an iterator adaptor
/// };
/// \endcode
template <typename Iterator>
struct PixelIteratorConcept
{
void constraints()
{
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator>>();
gil_function_requires<PixelBasedConcept<Iterator>>();
using value_type = typename std::iterator_traits<Iterator>::value_type;
gil_function_requires<PixelValueConcept<value_type>>();
using const_t = typename const_iterator_type<Iterator>::type;
static bool const is_mutable = iterator_is_mutable<Iterator>::value;
ignore_unused_variable_warning(is_mutable);
// immutable iterator must be constructible from (possibly mutable) iterator
const_t const_it(it);
ignore_unused_variable_warning(const_it);
check_base(typename is_iterator_adaptor<Iterator>::type());
}
void check_base(std::false_type) {}
void check_base(std::true_type)
{
using base_t = typename iterator_adaptor_get_base<Iterator>::type;
gil_function_requires<PixelIteratorConcept<base_t>>();
}
Iterator it;
};
/// \brief Pixel iterator that allows for changing its pixel
/// \ingroup PixelIteratorConceptPixelIterator
/// \code
/// concept MutablePixelIteratorConcept<PixelIteratorConcept Iterator>
/// : MutableRandomAccessIteratorConcept<Iterator> {};
/// \endcode
template <typename Iterator>
struct MutablePixelIteratorConcept
{
void constraints()
{
gil_function_requires<PixelIteratorConcept<Iterator>>();
gil_function_requires<detail::PixelIteratorIsMutableConcept<Iterator>>();
}
};
/// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept
/// \ingroup PixelIteratorConcept
/// \brief Iterator that advances by a specified step
/// \ingroup PixelIteratorConceptStepIterator
/// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits)
/// \code
/// concept MemoryBasedIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator>
/// {
/// typename byte_to_memunit<Iterator>; where metafunction<byte_to_memunit<Iterator> >;
/// std::ptrdiff_t memunit_step(const Iterator&);
/// std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&);
/// void memunit_advance(Iterator&, std::ptrdiff_t diff);
/// Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; }
/// Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); }
/// };
/// \endcode
template <typename Iterator>
struct MemoryBasedIteratorConcept
{
void constraints()
{
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator>>();
gil_function_requires<detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator>>();
}
};
/// \ingroup PixelIteratorConceptStepIterator
/// \brief Step iterator concept
///
/// Step iterators are iterators that have a set_step method
/// \code
/// concept StepIteratorConcept<boost_concepts::ForwardTraversalConcept Iterator>
/// {
/// template <Integral D>
/// void Iterator::set_step(D step);
/// };
/// \endcode
template <typename Iterator>
struct StepIteratorConcept
{
void constraints()
{
gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator>>();
it.set_step(0);
}
Iterator it;
};
/// \ingroup PixelIteratorConceptStepIterator
/// \brief Step iterator that allows for modifying its current value
/// \code
/// concept MutableStepIteratorConcept<Mutable_ForwardIteratorConcept Iterator>
/// : StepIteratorConcept<Iterator> {};
/// \endcode
template <typename Iterator>
struct MutableStepIteratorConcept
{
void constraints()
{
gil_function_requires<StepIteratorConcept<Iterator>>();
gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator>>();
}
};
/// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept
/// \ingroup PixelIteratorConcept
/// \brief Adaptor over another iterator
/// \ingroup PixelIteratorConceptIteratorAdaptor
/// \brief Iterator adaptor is a forward iterator adapting another forward iterator.
///
/// In addition to GIL iterator requirements,
/// GIL iterator adaptors must provide the following metafunctions:
/// - \p is_iterator_adaptor<Iterator>: Returns \p std::true_type
/// - \p iterator_adaptor_get_base<Iterator>: Returns the base iterator type
/// - \p iterator_adaptor_rebind<Iterator,NewBase>: Replaces the base iterator with the new one
///
/// The adaptee can be obtained from the iterator via the "base()" method.
///
/// \code
/// concept IteratorAdaptorConcept<boost_concepts::ForwardTraversalConcept Iterator>
/// {
/// where SameType<is_iterator_adaptor<Iterator>::type, std::true_type>;
///
/// typename iterator_adaptor_get_base<Iterator>;
/// where Metafunction<iterator_adaptor_get_base<Iterator> >;
/// where boost_concepts::ForwardTraversalConcept<iterator_adaptor_get_base<Iterator>::type>;
///
/// typename another_iterator;
/// typename iterator_adaptor_rebind<Iterator,another_iterator>::type;
/// where boost_concepts::ForwardTraversalConcept<another_iterator>;
/// where IteratorAdaptorConcept<iterator_adaptor_rebind<Iterator,another_iterator>::type>;
///
/// const iterator_adaptor_get_base<Iterator>::type& Iterator::base() const;
/// };
/// \endcode
template <typename Iterator>
struct IteratorAdaptorConcept
{
void constraints()
{
gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator>>();
using base_t = typename iterator_adaptor_get_base<Iterator>::type;
gil_function_requires<boost_concepts::ForwardTraversalConcept<base_t>>();
static_assert(is_iterator_adaptor<Iterator>::value, "");
using rebind_t = typename iterator_adaptor_rebind<Iterator, void*>::type;
base_t base = it.base();
ignore_unused_variable_warning(base);
}
Iterator it;
};
/// \brief Iterator adaptor that is mutable
/// \ingroup PixelIteratorConceptIteratorAdaptor
/// \code
/// concept MutableIteratorAdaptorConcept<Mutable_ForwardIteratorConcept Iterator>
/// : IteratorAdaptorConcept<Iterator> {};
/// \endcode
template <typename Iterator>
struct MutableIteratorAdaptorConcept
{
void constraints()
{
gil_function_requires<IteratorAdaptorConcept<Iterator>>();
gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator>>();
}
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,411 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
#define BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <boost/gil/concepts/fwd.hpp>
#include <boost/gil/concepts/pixel.hpp>
#include <boost/gil/concepts/pixel_dereference.hpp>
#include <boost/gil/concepts/pixel_iterator.hpp>
#include <boost/gil/concepts/point.hpp>
#include <boost/gil/concepts/detail/utility.hpp>
#include <cstddef>
#include <iterator>
#include <type_traits>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif
namespace boost { namespace gil {
/// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
/// \ingroup PixelLocatorConcept
/// \brief N-dimensional locator
/// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
/// \ingroup PixelLocatorConcept
/// \brief 2-dimensional locator
/// \defgroup PixelLocator2DConcept PixelLocatorConcept
/// \ingroup PixelLocatorConcept
/// \brief 2-dimensional locator over pixel data
/// \ingroup LocatorNDConcept
/// \brief N-dimensional locator over immutable values
///
/// \code
/// concept RandomAccessNDLocatorConcept<Regular Loc>
/// {
/// typename value_type; // value over which the locator navigates
/// typename reference; // result of dereferencing
/// typename difference_type; where PointNDConcept<difference_type>; // return value of operator-.
/// typename const_t; // same as Loc, but operating over immutable values
/// typename cached_location_t; // type to store relative location (for efficient repeated access)
/// typename point_t = difference_type;
///
/// static const size_t num_dimensions; // dimensionality of the locator
/// where num_dimensions = point_t::num_dimensions;
///
/// // The difference_type and iterator type along each dimension. The iterators may only differ in
/// // difference_type. Their value_type must be the same as Loc::value_type
/// template <size_t D>
/// struct axis
/// {
/// typename coord_t = point_t::axis<D>::coord_t;
/// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
/// where iterator::value_type == value_type;
/// };
///
/// // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing
/// template <PixelDereferenceAdaptorConcept Deref>
/// struct add_deref
/// {
/// typename type;
/// where RandomAccessNDLocatorConcept<type>;
/// static type make(const Loc& loc, const Deref& deref);
/// };
///
/// Loc& operator+=(Loc&, const difference_type&);
/// Loc& operator-=(Loc&, const difference_type&);
/// Loc operator+(const Loc&, const difference_type&);
/// Loc operator-(const Loc&, const difference_type&);
///
/// reference operator*(const Loc&);
/// reference operator[](const Loc&, const difference_type&);
///
/// // Storing relative location for faster repeated access and accessing it
/// cached_location_t Loc::cache_location(const difference_type&) const;
/// reference operator[](const Loc&,const cached_location_t&);
///
/// // Accessing iterators along a given dimension at the current location or at a given offset
/// template <size_t D> axis<D>::iterator& Loc::axis_iterator();
/// template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
/// template <size_t D> axis<D>::iterator Loc::axis_iterator(const difference_type&) const;
/// };
/// \endcode
template <typename Loc>
struct RandomAccessNDLocatorConcept
{
void constraints()
{
gil_function_requires<Regular<Loc>>();
// TODO: Should these be concept-checked instead of ignored? --mloskot
using value_type = typename Loc::value_type;
ignore_unused_variable_warning(value_type{});
// result of dereferencing
using reference = typename Loc::reference;
//ignore_unused_variable_warning(reference{});
// result of operator-(pixel_locator, pixel_locator)
using difference_type = typename Loc::difference_type;
ignore_unused_variable_warning(difference_type{});
// type used to store relative location (to allow for more efficient repeated access)
using cached_location_t = typename Loc::cached_location_t;
ignore_unused_variable_warning(cached_location_t{});
// same as this type, but over const values
using const_t = typename Loc::const_t;
ignore_unused_variable_warning(const_t{});
// same as difference_type
using point_t = typename Loc::point_t;
ignore_unused_variable_warning(point_t{});
static std::size_t const N = Loc::num_dimensions; ignore_unused_variable_warning(N);
using first_it_type = typename Loc::template axis<0>::iterator;
using last_it_type = typename Loc::template axis<N-1>::iterator;
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
// point_t must be an N-dimensional point, each dimension of which must
// have the same type as difference_type of the corresponding iterator
gil_function_requires<PointNDConcept<point_t>>();
static_assert(point_t::num_dimensions == N, "");
static_assert(std::is_same
<
typename std::iterator_traits<first_it_type>::difference_type,
typename point_t::template axis<0>::coord_t
>::value, "");
static_assert(std::is_same
<
typename std::iterator_traits<last_it_type>::difference_type,
typename point_t::template axis<N-1>::coord_t
>::value, "");
difference_type d;
loc += d;
loc -= d;
loc = loc + d;
loc = loc - d;
reference r1 = loc[d]; ignore_unused_variable_warning(r1);
reference r2 = *loc; ignore_unused_variable_warning(r2);
cached_location_t cl = loc.cache_location(d); ignore_unused_variable_warning(cl);
reference r3 = loc[d]; ignore_unused_variable_warning(r3);
first_it_type fi = loc.template axis_iterator<0>();
fi = loc.template axis_iterator<0>(d);
last_it_type li = loc.template axis_iterator<N-1>();
li = loc.template axis_iterator<N-1>(d);
using deref_t = PixelDereferenceAdaptorArchetype<typename Loc::value_type>;
using dtype = typename Loc::template add_deref<deref_t>::type;
// TODO: infinite recursion - FIXME?
//gil_function_requires<RandomAccessNDLocatorConcept<dtype>>();
}
Loc loc;
};
/// \ingroup Locator2DConcept
/// \brief 2-dimensional locator over immutable values
///
/// \code
/// concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc>
/// {
/// where num_dimensions==2;
/// where Point2DConcept<point_t>;
///
/// typename x_iterator = axis<0>::iterator;
/// typename y_iterator = axis<1>::iterator;
/// typename x_coord_t = axis<0>::coord_t;
/// typename y_coord_t = axis<1>::coord_t;
///
/// // Only available to locators that have dynamic step in Y
/// //Loc::Loc(const Loc& loc, y_coord_t);
///
/// // Only available to locators that have dynamic step in X and Y
/// //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);
///
/// x_iterator& Loc::x();
/// x_iterator const& Loc::x() const;
/// y_iterator& Loc::y();
/// y_iterator const& Loc::y() const;
///
/// x_iterator Loc::x_at(const difference_type&) const;
/// y_iterator Loc::y_at(const difference_type&) const;
/// Loc Loc::xy_at(const difference_type&) const;
///
/// // x/y versions of all methods that can take difference type
/// x_iterator Loc::x_at(x_coord_t, y_coord_t) const;
/// y_iterator Loc::y_at(x_coord_t, y_coord_t) const;
/// Loc Loc::xy_at(x_coord_t, y_coord_t) const;
/// reference operator()(const Loc&, x_coord_t, y_coord_t);
/// cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;
///
/// bool Loc::is_1d_traversable(x_coord_t width) const;
/// y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
/// };
/// \endcode
template <typename Loc>
struct RandomAccess2DLocatorConcept
{
void constraints()
{
gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
static_assert(Loc::num_dimensions == 2, "");
using dynamic_x_step_t = typename dynamic_x_step_type<Loc>::type;
using dynamic_y_step_t = typename dynamic_y_step_type<Loc>::type;
using transposed_t = typename transposed_type<Loc>::type;
using cached_location_t = typename Loc::cached_location_t;
gil_function_requires<Point2DConcept<typename Loc::point_t>>();
using x_iterator = typename Loc::x_iterator;
using y_iterator = typename Loc::y_iterator;
using x_coord_t = typename Loc::x_coord_t;
using y_coord_t = typename Loc::y_coord_t;
x_coord_t xd = 0; ignore_unused_variable_warning(xd);
y_coord_t yd = 0; ignore_unused_variable_warning(yd);
typename Loc::difference_type d;
typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r);
dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
using dynamic_xy_step_transposed_t = typename dynamic_y_step_type
<
typename dynamic_x_step_type<transposed_t>::type
>::type;
dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
bool is_contiguous = loc.is_1d_traversable(xd);
ignore_unused_variable_warning(is_contiguous);
loc.y_distance_to(loc, xd);
loc = loc.xy_at(d);
loc = loc.xy_at(xd, yd);
x_iterator xit = loc.x_at(d);
xit = loc.x_at(xd, yd);
xit = loc.x();
y_iterator yit = loc.y_at(d);
yit = loc.y_at(xd, yd);
yit = loc.y();
cached_location_t cl = loc.cache_location(xd, yd);
ignore_unused_variable_warning(cl);
}
Loc loc;
};
/// \ingroup PixelLocator2DConcept
/// \brief GIL's 2-dimensional locator over immutable GIL pixels
/// \code
/// concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc>
/// {
/// where PixelValueConcept<value_type>;
/// where PixelIteratorConcept<x_iterator>;
/// where PixelIteratorConcept<y_iterator>;
/// where x_coord_t == y_coord_t;
///
/// typename coord_t = x_coord_t;
/// };
/// \endcode
template <typename Loc>
struct PixelLocatorConcept
{
void constraints()
{
gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
gil_function_requires<PixelIteratorConcept<typename Loc::x_iterator>>();
gil_function_requires<PixelIteratorConcept<typename Loc::y_iterator>>();
using coord_t = typename Loc::coord_t;
static_assert(std::is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value, "");
}
Loc loc;
};
namespace detail {
/// \tparam Loc Models RandomAccessNDLocatorConcept
template <typename Loc>
struct RandomAccessNDLocatorIsMutableConcept
{
void constraints()
{
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
<
typename Loc::template axis<0>::iterator
>>();
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
<
typename Loc::template axis<Loc::num_dimensions-1>::iterator
>>();
typename Loc::difference_type d; initialize_it(d);
typename Loc::value_type v; initialize_it(v);
typename Loc::cached_location_t cl = loc.cache_location(d);
*loc = v;
loc[d] = v;
loc[cl] = v;
}
Loc loc;
};
// \tparam Loc Models RandomAccess2DLocatorConcept
template <typename Loc>
struct RandomAccess2DLocatorIsMutableConcept
{
void constraints()
{
gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
typename Loc::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
typename Loc::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
typename Loc::value_type v; initialize_it(v);
loc(xd, yd) = v;
}
Loc loc;
};
} // namespace detail
/// \ingroup LocatorNDConcept
/// \brief N-dimensional locator over mutable pixels
///
/// \code
/// concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc>
/// {
/// where Mutable<reference>;
/// };
/// \endcode
template <typename Loc>
struct MutableRandomAccessNDLocatorConcept
{
void constraints()
{
gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
}
};
/// \ingroup Locator2DConcept
/// \brief 2-dimensional locator over mutable pixels
///
/// \code
/// concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc>
/// : MutableRandomAccessNDLocatorConcept<Loc> {};
/// \endcode
template <typename Loc>
struct MutableRandomAccess2DLocatorConcept
{
void constraints()
{
gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
}
};
/// \ingroup PixelLocator2DConcept
/// \brief GIL's 2-dimensional locator over mutable GIL pixels
///
/// \code
/// concept MutablePixelLocatorConcept<PixelLocatorConcept Loc>
/// : MutableRandomAccess2DLocatorConcept<Loc> {};
/// \endcode
template <typename Loc>
struct MutablePixelLocatorConcept
{
void constraints()
{
gil_function_requires<PixelLocatorConcept<Loc>>();
gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
}
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif

View File

@@ -0,0 +1,125 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_CONCEPTS_POINT_HPP
#define BOOST_GIL_CONCEPTS_POINT_HPP
#include <boost/gil/concepts/basic.hpp>
#include <boost/gil/concepts/concept_check.hpp>
#include <cstddef>
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
namespace boost { namespace gil {
// Forward declarations
template <typename T>
class point;
template <std::size_t K, typename T>
T const& axis_value(point<T> const& p);
template <std::size_t K, typename T>
T& axis_value(point<T>& p);
/// \brief N-dimensional point concept
/// \code
/// concept PointNDConcept<typename T> : Regular<T>
/// {
/// // the type of a coordinate along each axis
/// template <size_t K>
/// struct axis; where Metafunction<axis>;
///
/// const size_t num_dimensions;
///
/// // accessor/modifier of the value of each axis.
///
/// template <size_t K>
/// typename axis<K>::type const& T::axis_value() const;
///
/// template <size_t K>
/// typename axis<K>::type& T::axis_value();
/// };
/// \endcode
/// \ingroup PointConcept
///
template <typename P>
struct PointNDConcept
{
void constraints()
{
gil_function_requires<Regular<P>>();
using value_type = typename P::value_type;
ignore_unused_variable_warning(value_type{});
static const std::size_t N = P::num_dimensions;
ignore_unused_variable_warning(N);
using FT = typename P::template axis<0>::coord_t;
using LT = typename P::template axis<N - 1>::coord_t;
FT ft = gil::axis_value<0>(point);
axis_value<0>(point) = ft;
LT lt = axis_value<N - 1>(point);
axis_value<N - 1>(point) = lt;
//value_type v=point[0];
//ignore_unused_variable_warning(v);
}
P point;
};
/// \brief 2-dimensional point concept
/// \code
/// concept Point2DConcept<typename T> : PointNDConcept<T>
/// {
/// where num_dimensions == 2;
/// where SameType<axis<0>::type, axis<1>::type>;
///
/// typename value_type = axis<0>::type;
///
/// value_type const& operator[](T const&, size_t i);
/// value_type& operator[](T&, size_t i);
///
/// value_type x,y;
/// };
/// \endcode
/// \ingroup PointConcept
///
template <typename P>
struct Point2DConcept
{
void constraints()
{
gil_function_requires<PointNDConcept<P>>();
static_assert(P::num_dimensions == 2, "");
point.x = point.y;
point[0] = point[1];
}
P point;
};
}} // namespace boost::gil
#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif