#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/integer/integer_mask.hpp>
-#include <boost/type_traits/remove_cv.hpp>
#include <cstdint>
#include <limits>
+#include <type_traits>
#ifdef BOOST_GIL_DOXYGEN_ONLY
/// \def BOOST_GIL_CONFIG_HAS_UNALIGNED_ACCESS
///////////////////////////////////////////
namespace detail {
- template <typename T, bool is_class> struct channel_traits_impl;
-
- // channel traits for custom class
- template <typename T>
- struct channel_traits_impl<T, true> {
- using value_type = typename T::value_type;
- using reference = typename T::reference;
- using pointer = typename T::pointer;
- using const_reference = typename T::const_reference;
- using const_pointer = typename T::const_pointer;
- static constexpr bool is_mutable = T::is_mutable;
- static value_type min_value() { return T::min_value(); }
- static value_type max_value() { return T::max_value(); }
- };
-
- // channel traits implementation for built-in integral or floating point channel type
- template <typename T>
- struct channel_traits_impl<T, false> {
- using value_type = T;
- using reference = T&;
- using pointer = T*;
- using const_reference = T const&;
- using const_pointer = T const*;
- static constexpr bool is_mutable = true;
- static value_type min_value() { return (std::numeric_limits<T>::min)(); }
- static value_type max_value() { return (std::numeric_limits<T>::max)(); }
- };
-
- // channel traits implementation for constant built-in scalar or floating point type
- template <typename T>
- struct channel_traits_impl<const T, false> : public channel_traits_impl<T, false> {
- using reference = const T &;
- using pointer = const T *;
- static constexpr bool is_mutable = false;
- };
-}
+
+template <typename T, bool IsClass>
+struct channel_traits_impl;
+
+// channel traits for custom class
+template <typename T>
+struct channel_traits_impl<T, true>
+{
+ using value_type = typename T::value_type;
+ using reference = typename T::reference;
+ using pointer = typename T::pointer;
+ using const_reference = typename T::const_reference;
+ using const_pointer = typename T::const_pointer;
+ static constexpr bool is_mutable = T::is_mutable;
+ static value_type min_value() { return T::min_value(); }
+ static value_type max_value() { return T::max_value(); }
+};
+
+// channel traits implementation for built-in integral or floating point channel type
+template <typename T>
+struct channel_traits_impl<T, false>
+{
+ using value_type = T;
+ using reference = T&;
+ using pointer = T*;
+ using const_reference = T const&;
+ using const_pointer = T const*;
+ static constexpr bool is_mutable = true;
+ static value_type min_value() { return (std::numeric_limits<T>::min)(); }
+ static value_type max_value() { return (std::numeric_limits<T>::max)(); }
+};
+
+// channel traits implementation for constant built-in scalar or floating point type
+template <typename T>
+struct channel_traits_impl<T const, false> : channel_traits_impl<T, false>
+{
+ using reference = T const&;
+ using pointer = T const*;
+ static constexpr bool is_mutable = false;
+};
+
+} // namespace detail
/**
\ingroup ChannelModel
\endcode
*/
template <typename T>
-struct channel_traits : public detail::channel_traits_impl<T, is_class<T>::value> {};
+struct channel_traits : detail::channel_traits_impl<T, std::is_class<T>::value> {};
// Channel traits for C++ reference type - remove the reference
-template <typename T> struct channel_traits<T&> : public channel_traits<T> {};
+template <typename T>
+struct channel_traits<T&> : channel_traits<T> {};
// Channel traits for constant C++ reference type
template <typename T>
-struct channel_traits<T const&> : public channel_traits<T>
+struct channel_traits<T const&> : channel_traits<T>
{
using reference = typename channel_traits<T>::const_reference;
using pointer = typename channel_traits<T>::const_pointer;
};
///////////////////////////////////////////
-////
//// scoped_channel_value
-////
///////////////////////////////////////////
/// \defgroup ScopedChannelValue scoped_channel_value
static value_type min_value() { return MinVal::apply(); }
static value_type max_value() { return MaxVal::apply(); }
- scoped_channel_value() {}
- scoped_channel_value(const scoped_channel_value& c) : _value(c._value) {}
- scoped_channel_value(BaseChannelValue val) : _value(val) {}
+ scoped_channel_value() = default;
+ scoped_channel_value(scoped_channel_value const& other) : value_(other.value_) {}
+ scoped_channel_value& operator=(scoped_channel_value const& other) = default;
+ scoped_channel_value(BaseChannelValue value) : value_(value) {}
+ scoped_channel_value& operator=(BaseChannelValue value)
+ {
+ value_ = value;
+ return *this;
+ }
- scoped_channel_value& operator++() { ++_value; return *this; }
- scoped_channel_value& operator--() { --_value; return *this; }
+ scoped_channel_value& operator++() { ++value_; return *this; }
+ scoped_channel_value& operator--() { --value_; return *this; }
scoped_channel_value operator++(int) { scoped_channel_value tmp=*this; this->operator++(); return tmp; }
scoped_channel_value operator--(int) { scoped_channel_value tmp=*this; this->operator--(); return tmp; }
- template <typename Scalar2> scoped_channel_value& operator+=(Scalar2 v) { _value+=v; return *this; }
- template <typename Scalar2> scoped_channel_value& operator-=(Scalar2 v) { _value-=v; return *this; }
- template <typename Scalar2> scoped_channel_value& operator*=(Scalar2 v) { _value*=v; return *this; }
- template <typename Scalar2> scoped_channel_value& operator/=(Scalar2 v) { _value/=v; return *this; }
+ template <typename Scalar2> scoped_channel_value& operator+=(Scalar2 v) { value_+=v; return *this; }
+ template <typename Scalar2> scoped_channel_value& operator-=(Scalar2 v) { value_-=v; return *this; }
+ template <typename Scalar2> scoped_channel_value& operator*=(Scalar2 v) { value_*=v; return *this; }
+ template <typename Scalar2> scoped_channel_value& operator/=(Scalar2 v) { value_/=v; return *this; }
- scoped_channel_value& operator=(BaseChannelValue v) { _value=v; return *this; }
- operator BaseChannelValue() const { return _value; }
+ operator BaseChannelValue() const { return value_; }
private:
- BaseChannelValue _value;
+ BaseChannelValue value_{};
};
template <typename T>
};
///////////////////////////////////////////
-////
//// Support for sub-byte channels. These are integral channels whose value is contained in a range of bits inside an integral type
-////
///////////////////////////////////////////
// It is necessary for packed channels to have their own value type. They cannot simply use an integral large enough to store the data. Here is why:
// That means that after getting the value of the channel we cannot properly do channel_convert, channel_invert, etc.
// - Two channels are declared compatible if they have the same value type. That means that a packed channel is incorrectly declared compatible with an integral type
namespace detail {
- // returns the smallest fast unsigned integral type that has at least NumBits bits
- template <int NumBits>
- struct min_fast_uint : public mpl::if_c< (NumBits<=8),
- uint_least8_t,
- typename mpl::if_c< (NumBits<=16),
- uint_least16_t,
- typename mpl::if_c< (NumBits<=32),
- uint_least32_t,
- uintmax_t
- >::type
+
+// returns the smallest fast unsigned integral type that has at least NumBits bits
+template <int NumBits>
+struct min_fast_uint :
+ std::conditional
+ <
+ NumBits <= 8,
+ std::uint_least8_t,
+ typename std::conditional
+ <
+ NumBits <= 16,
+ std::uint_least16_t,
+ typename std::conditional
+ <
+ NumBits <= 32,
+ std::uint_least32_t,
+ std::uintmax_t
>::type
- > {};
-
- template <int NumBits>
- struct num_value_fn : public mpl::if_c< ( NumBits < 32 )
- , uint32_t
- , uint64_t
- > {};
-
- template <int NumBits>
- struct max_value_fn : public mpl::if_c< ( NumBits <= 32 )
- , uint32_t
- , uint64_t
- > {};
-}
+ >::type
+ >
+{};
+
+template <int NumBits>
+struct num_value_fn
+ : std::conditional<NumBits < 32, std::uint32_t, std::uint64_t>
+{};
+
+template <int NumBits>
+struct max_value_fn
+ : std::conditional<NumBits <= 32, std::uint32_t, std::uint64_t>
+{};
+
+} // namespace detail
/// \defgroup PackedChannelValueModel packed_channel_value
/// \ingroup ChannelModel
/// assert(channel_traits<bits4>::min_value()==0);
/// assert(channel_traits<bits4>::max_value()==15);
/// assert(sizeof(bits4)==1);
-/// static_assert(boost::is_integral<bits4>::value, "");
+/// static_assert(gil::is_channel_integral<bits4>::value, "");
/// \endcode
/// \ingroup PackedChannelValueModel
/// \brief The value of a subbyte channel. Models: ChannelValueConcept
template <int NumBits>
-class packed_channel_value {
-
+class packed_channel_value
+{
public:
using integer_t = typename detail::min_fast_uint<NumBits>::type;
static value_type min_value() { return 0; }
static value_type max_value() { return low_bits_mask_t< NumBits >::sig_bits; }
- packed_channel_value() {}
- packed_channel_value(integer_t v) { _value = static_cast< integer_t >( v & low_bits_mask_t<NumBits>::sig_bits_fast ); }
+ packed_channel_value() = default;
+ packed_channel_value(integer_t v)
+ {
+ value_ = static_cast<integer_t>(v & low_bits_mask_t<NumBits>::sig_bits_fast);
+ }
+
template <typename Scalar>
- packed_channel_value(Scalar v) { _value = packed_channel_value( static_cast< integer_t >( v ) ); }
+ packed_channel_value(Scalar v)
+ {
+ value_ = packed_channel_value(static_cast<integer_t>(v));
+ }
static unsigned int num_bits() { return NumBits; }
- operator integer_t() const { return _value; }
+ operator integer_t() const { return value_; }
+
private:
- integer_t _value;
+ integer_t value_{};
};
namespace detail {
template <std::size_t K>
-struct static_copy_bytes {
- void operator()(const unsigned char* from, unsigned char* to) const {
+struct static_copy_bytes
+{
+ void operator()(unsigned char const* from, unsigned char* to) const
+ {
*to = *from;
- static_copy_bytes<K-1>()(++from,++to);
+ static_copy_bytes<K - 1>()(++from, ++to);
}
};
template <>
-struct static_copy_bytes<0> {
- void operator()(const unsigned char* , unsigned char*) const {}
+struct static_copy_bytes<0>
+{
+ void operator()(unsigned char const*, unsigned char*) const {}
};
-template <typename Derived, typename BitField, int NumBits, bool Mutable>
-class packed_channel_reference_base {
+template <typename Derived, typename BitField, int NumBits, bool IsMutable>
+class packed_channel_reference_base
+{
protected:
- using data_ptr_t = typename mpl::if_c<Mutable,void*,const void*>::type;
+ using data_ptr_t = typename std::conditional<IsMutable, void*, void const*>::type;
public:
data_ptr_t _data_ptr; // void* pointer to the first byte of the bit range
using pointer = value_type *;
using const_pointer = const value_type *;
static constexpr int num_bits = NumBits;
- static constexpr bool is_mutable = Mutable;
+ static constexpr bool is_mutable = IsMutable;
static value_type min_value() { return channel_traits<value_type>::min_value(); }
static value_type max_value() { return channel_traits<value_type>::max_value(); }
/// assert(data == 6); // == 3<<1 == 6
/// \endcode
-template <typename BitField, // A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like std::uint16_t
- int FirstBit, int NumBits,// Defines the sequence of bits in the data value that contain the channel
- bool Mutable> // true if the reference is mutable
+/// \tparam BitField A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like std::uint16_t
+/// \tparam Defines the sequence of bits in the data value that contain the channel
+/// \tparam true if the reference is mutable
+template <typename BitField, int FirstBit, int NumBits, bool IsMutable>
class packed_channel_reference;
-template <typename BitField, // A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like std::uint16_t
- int NumBits, // Defines the sequence of bits in the data value that contain the channel
- bool Mutable> // true if the reference is mutable
+/// \tparam A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like std::uint16_t
+/// \tparam Defines the sequence of bits in the data value that contain the channel
+/// \tparam true if the reference is mutable
+template <typename BitField, int NumBits, bool IsMutable>
class packed_dynamic_channel_reference;
/// \ingroup PackedChannelReferenceModel
/// \brief A constant subbyte channel reference whose bit offset is fixed at compile time. Models ChannelConcept
template <typename BitField, int FirstBit, int NumBits>
-class packed_channel_reference<BitField,FirstBit,NumBits,false>
- : public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false>
+class packed_channel_reference<BitField, FirstBit, NumBits, false>
+ : public detail::packed_channel_reference_base
+ <
+ packed_channel_reference<BitField, FirstBit, NumBits, false>,
+ BitField,
+ NumBits,
+ false
+ >
{
- using parent_t = detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false>;
- friend class packed_channel_reference<BitField,FirstBit,NumBits,true>;
+ using parent_t = detail::packed_channel_reference_base
+ <
+ packed_channel_reference<BitField, FirstBit, NumBits, false>,
+ BitField,
+ NumBits,
+ false
+ >;
- static const BitField channel_mask = static_cast< BitField >( parent_t::max_val ) << FirstBit;
+ friend class packed_channel_reference<BitField, FirstBit, NumBits, true>;
+
+ static const BitField channel_mask = static_cast<BitField>(parent_t::max_val) << FirstBit;
- void operator=(const packed_channel_reference&);
+ void operator=(packed_channel_reference const&);
public:
using const_reference = packed_channel_reference<BitField,FirstBit,NumBits,false> const;
using mutable_reference = packed_channel_reference<BitField,FirstBit,NumBits,true> const;
void set_from_reference(const BitField& other_bits) const { this->set_data((this->get_data() & ~channel_mask) | (other_bits & channel_mask)); }
};
-} } // namespace boost::gil
+}} // namespace boost::gil
namespace std {
// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
/// \ingroup PackedChannelReferenceModel
/// \brief swap for packed_channel_reference
-template <typename BF, int FB, int NB, bool M, typename R> inline
-void swap(const boost::gil::packed_channel_reference<BF,FB,NB,M> x, R& y) {
- boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
+template <typename BF, int FB, int NB, bool M, typename R>
+inline
+void swap(boost::gil::packed_channel_reference<BF, FB, NB, M> const x, R& y)
+{
+ boost::gil::swap_proxy
+ <
+ typename boost::gil::packed_channel_reference<BF, FB, NB, M>::value_type
+ >(x, y);
}
/// \ingroup PackedChannelReferenceModel
/// \brief swap for packed_channel_reference
-template <typename BF, int FB, int NB, bool M> inline
-void swap(typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type& x, const boost::gil::packed_channel_reference<BF,FB,NB,M> y) {
- boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
+template <typename BF, int FB, int NB, bool M>
+inline
+void swap(
+ typename boost::gil::packed_channel_reference<BF, FB, NB, M>::value_type& x,
+ boost::gil::packed_channel_reference<BF, FB, NB, M> const y)
+{
+ boost::gil::swap_proxy
+ <
+ typename boost::gil::packed_channel_reference<BF, FB, NB, M>::value_type
+ >(x,y);
}
/// \ingroup PackedChannelReferenceModel
/// \brief swap for packed_channel_reference
template <typename BF, int FB, int NB, bool M> inline
-void swap(const boost::gil::packed_channel_reference<BF,FB,NB,M> x, const boost::gil::packed_channel_reference<BF,FB,NB,M> y) {
- boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
+void swap(
+ boost::gil::packed_channel_reference<BF, FB, NB, M> const x,
+ boost::gil::packed_channel_reference<BF, FB, NB, M> const y)
+{
+ boost::gil::swap_proxy
+ <
+ typename boost::gil::packed_channel_reference<BF, FB, NB, M>::value_type
+ >(x,y);
}
+
} // namespace std
namespace boost { namespace gil {
}
} // namespace std
-namespace boost {
-
-template <int NumBits>
-struct is_integral<gil::packed_channel_value<NumBits> > : public mpl::true_ {};
-
-template <typename BitField, int FirstBit, int NumBits, bool IsMutable>
-struct is_integral<gil::packed_channel_reference<BitField,FirstBit,NumBits,IsMutable> > : public mpl::true_ {};
-
-template <typename BitField, int NumBits, bool IsMutable>
-struct is_integral<gil::packed_dynamic_channel_reference<BitField,NumBits,IsMutable> > : public mpl::true_ {};
-
-template <typename BaseChannelValue, typename MinVal, typename MaxVal>
-struct is_integral<gil::scoped_channel_value<BaseChannelValue,MinVal,MaxVal> > : public is_integral<BaseChannelValue> {};
-
-} // namespace boost
-
// \brief Determines the fundamental type which may be used, e.g., to cast from larger to smaller channel types.
namespace boost { namespace gil {
template <typename T>
{ using type = ChannelValue; };
template <typename T>
-struct base_channel_type : base_channel_type_impl<typename remove_cv<T>::type > {};
+struct base_channel_type : base_channel_type_impl<typename std::remove_cv<T>::type> {};
}} //namespace boost::gil