Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / gil / concepts / channel.hpp
1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 #ifndef BOOST_GIL_CONCEPTS_CHANNEL_HPP
9 #define BOOST_GIL_CONCEPTS_CHANNEL_HPP
10
11 #include <boost/gil/concepts/basic.hpp>
12 #include <boost/gil/concepts/concept_check.hpp>
13 #include <boost/gil/concepts/fwd.hpp>
14
15 #include <boost/concept_check.hpp>
16
17 #include <utility> // std::swap
18 #include <type_traits>
19
20 #if defined(BOOST_CLANG)
21 #pragma clang diagnostic push
22 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
23 #endif
24
25 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
26 #pragma GCC diagnostic push
27 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
28 #endif
29
30 namespace boost { namespace gil {
31
32 // Forward declarations
33 template <typename T>
34 struct channel_traits;
35
36 template <typename DstT, typename SrcT>
37 auto channel_convert(SrcT const& val)
38     -> typename channel_traits<DstT>::value_type;
39
40 /// \ingroup ChannelConcept
41 /// \brief A channel is the building block of a color.
42 /// Color is defined as a mixture of primary colors and a channel defines
43 /// the degree to which each primary color is used in the mixture.
44 ///
45 /// For example, in the RGB color space, using 8-bit unsigned channels,
46 /// the color red is defined as [255 0 0], which means maximum of Red,
47 /// and no Green and Blue.
48 ///
49 /// Built-in scalar types, such as \p int and \p float, are valid GIL channels.
50 /// In more complex scenarios, channels may be represented as bit ranges or
51 /// even individual bits.
52 /// In such cases special classes are needed to represent the value and
53 /// reference to a channel.
54 ///
55 /// Channels have a traits class, \p channel_traits, which defines their
56 /// associated types as well as their operating ranges.
57 ///
58 /// \code
59 /// concept ChannelConcept<typename T> : EqualityComparable<T>
60 /// {
61 ///     typename value_type      = T;        // use channel_traits<T>::value_type to access it
62 ///     typename reference       = T&;       // use channel_traits<T>::reference to access it
63 ///     typename pointer         = T*;       // use channel_traits<T>::pointer to access it
64 ///     typename const_reference = const T&; // use channel_traits<T>::const_reference to access it
65 ///     typename const_pointer   = const T*; // use channel_traits<T>::const_pointer to access it
66 ///     static const bool is_mutable;        // use channel_traits<T>::is_mutable to access it
67 ///
68 ///     static T min_value();                // use channel_traits<T>::min_value to access it
69 ///     static T max_value();                // use channel_traits<T>::min_value to access it
70 /// };
71 /// \endcode
72 template <typename T>
73 struct ChannelConcept
74 {
75     void constraints()
76     {
77         gil_function_requires<boost::EqualityComparableConcept<T>>();
78
79         using v = typename channel_traits<T>::value_type;
80         using r = typename channel_traits<T>::reference;
81         using p = typename channel_traits<T>::pointer;
82         using cr = typename channel_traits<T>::const_reference;
83         using cp = typename channel_traits<T>::const_pointer;
84
85         channel_traits<T>::min_value();
86         channel_traits<T>::max_value();
87     }
88
89      T c;
90 };
91
92 namespace detail
93 {
94
95 /// \tparam T models ChannelConcept
96 template <typename T>
97 struct ChannelIsMutableConcept
98 {
99     void constraints()
100     {
101         c1 = c2;
102         using std::swap;
103         swap(c1, c2);
104     }
105     T c1;
106     T c2;
107 };
108
109 } // namespace detail
110
111 /// \brief A channel that allows for modifying its value
112 /// \code
113 /// concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
114 /// \endcode
115 /// \ingroup ChannelConcept
116 template <typename T>
117 struct MutableChannelConcept
118 {
119     void constraints()
120     {
121         gil_function_requires<ChannelConcept<T>>();
122         gil_function_requires<detail::ChannelIsMutableConcept<T>>();
123     }
124 };
125
126 /// \brief A channel that supports default construction.
127 /// \code
128 /// concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
129 /// \endcode
130 /// \ingroup ChannelConcept
131 template <typename T>
132 struct ChannelValueConcept
133 {
134     void constraints()
135     {
136         gil_function_requires<ChannelConcept<T>>();
137         gil_function_requires<Regular<T>>();
138     }
139 };
140
141 /// \brief Predicate metafunction returning whether two channels are compatible
142 ///
143 /// Channels are considered compatible if their value types
144 /// (ignoring constness and references) are the same.
145 ///
146 /// Example:
147 ///
148 /// \code
149 /// static_assert(channels_are_compatible<uint8_t, const uint8_t&>::value, "");
150 /// \endcode
151 /// \ingroup ChannelAlgorithm
152 template <typename T1, typename T2>  // Models GIL Pixel
153 struct channels_are_compatible
154     : std::is_same
155         <
156             typename channel_traits<T1>::value_type,
157             typename channel_traits<T2>::value_type
158         >
159 {
160 };
161
162 /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
163 ///
164 /// \code
165 /// concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2>
166 /// {
167 ///     where SameType<T1::value_type, T2::value_type>;
168 /// };
169 /// \endcode
170 /// \ingroup ChannelConcept
171 template <typename Channel1, typename Channel2>
172 struct ChannelsCompatibleConcept
173 {
174     void constraints()
175     {
176         static_assert(channels_are_compatible<Channel1, Channel2>::value, "");
177     }
178 };
179
180 /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels.
181 ///
182 /// Convertibility is non-symmetric and implies that one channel can be
183 /// converted to another. Conversion is explicit and often lossy operation.
184 ///
185 /// concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel>
186 /// {
187 ///     DstChannel channel_convert(const SrcChannel&);
188 /// };
189 /// \endcode
190 /// \ingroup ChannelConcept
191 template <typename SrcChannel, typename DstChannel>
192 struct ChannelConvertibleConcept
193 {
194     void constraints()
195     {
196         gil_function_requires<ChannelConcept<SrcChannel>>();
197         gil_function_requires<MutableChannelConcept<DstChannel>>();
198         dst = channel_convert<DstChannel, SrcChannel>(src);
199         ignore_unused_variable_warning(dst);
200     }
201     SrcChannel src;
202     DstChannel dst;
203 };
204
205 }} // namespace boost::gil
206
207 #if defined(BOOST_CLANG)
208 #pragma clang diagnostic pop
209 #endif
210
211 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
212 #pragma GCC diagnostic pop
213 #endif
214
215 #endif