Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / gil / channel.hpp
index 455a76d..39ea65e 100644 (file)
 #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
@@ -69,42 +69,48 @@ namespace boost { namespace gil {
 ///////////////////////////////////////////
 
 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
@@ -125,14 +131,15 @@ struct channel_traits {
 \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;
@@ -140,9 +147,7 @@ struct channel_traits<T const&> : public channel_traits<T>
 };
 
 ///////////////////////////////////////////
-////
 ////  scoped_channel_value
-////
 ///////////////////////////////////////////
 
 /// \defgroup ScopedChannelValue scoped_channel_value
@@ -183,25 +188,30 @@ struct 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>
@@ -217,9 +227,7 @@ struct float_point_one
 };
 
 ///////////////////////////////////////////
-////
 ////  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:
@@ -227,31 +235,39 @@ struct float_point_one
 //   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
@@ -264,14 +280,14 @@ namespace detail {
 /// 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;
 
@@ -285,37 +301,49 @@ public:
     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
 
@@ -324,7 +352,7 @@ public:
     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(); }
@@ -394,28 +422,43 @@ private:
 /// 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;
@@ -470,7 +513,7 @@ private:
     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.
@@ -481,25 +524,44 @@ namespace std {
 
 /// \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 {
@@ -628,22 +690,6 @@ void swap(const boost::gil::packed_dynamic_channel_reference<BF,NB,M> x, const b
 }
 }   // 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>
@@ -670,7 +716,7 @@ struct base_channel_type_impl<scoped_channel_value<ChannelValue, MinV, MaxV> >
 { 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