Boost GIL


utilities.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_UTILITIES_HPP
9 #define BOOST_GIL_UTILITIES_HPP
10 
11 #include <boost/gil/detail/mp11.hpp>
12 
13 #include <boost/config.hpp>
14 
15 #if defined(BOOST_CLANG)
16 #pragma clang diagnostic push
17 #pragma clang diagnostic ignored "-Wconversion"
18 #endif
19 
20 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
21 #pragma GCC diagnostic push
22 #pragma GCC diagnostic ignored "-Wconversion"
23 #endif
24 
25 #include <boost/iterator/iterator_adaptor.hpp>
26 #include <boost/iterator/iterator_facade.hpp>
27 
28 #if defined(BOOST_CLANG)
29 #pragma clang diagnostic pop
30 #endif
31 
32 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
33 #pragma GCC diagnostic pop
34 #endif
35 
36 #include <algorithm>
37 #include <cmath>
38 #include <cstddef>
39 #include <functional>
40 #include <iterator>
41 #include <utility>
42 #include <type_traits>
43 
44 namespace boost { namespace gil {
45 
48 
52 
53 inline std::ptrdiff_t iround(float x)
54 {
55  return static_cast<std::ptrdiff_t>(x + (x < 0.0f ? -0.5f : 0.5f));
56 }
57 
58 inline std::ptrdiff_t iround(double x)
59 {
60  return static_cast<std::ptrdiff_t>(x + (x < 0.0 ? -0.5 : 0.5));
61 }
62 
63 inline std::ptrdiff_t ifloor(float x)
64 {
65  return static_cast<std::ptrdiff_t>(std::floor(x));
66 }
67 
68 inline std::ptrdiff_t ifloor(double x)
69 {
70  return static_cast<std::ptrdiff_t>(std::floor(x));
71 }
72 
73 inline std::ptrdiff_t iceil(float x)
74 {
75  return static_cast<std::ptrdiff_t>(std::ceil(x));
76 }
77 
78 inline std::ptrdiff_t iceil(double x)
79 {
80  return static_cast<std::ptrdiff_t>(std::ceil(x));
81 }
82 
86 
87 template <typename T>
88 inline T align(T val, std::size_t alignment)
89 {
90  return val+(alignment - val%alignment)%alignment;
91 }
92 
96 template
97 <
98  typename ConstT,
99  typename Value,
100  typename Reference,
101  typename ConstReference,
102  typename ArgType,
103  typename ResultType,
104  bool IsMutable
105 >
107 {
108  using argument_type = ArgType;
109  using result_type = ResultType;
110  using const_t = ConstT;
111  using value_type = Value;
112  using reference = Reference;
113  using const_reference = ConstReference;
114  static constexpr bool is_mutable = IsMutable;
115 };
116 
120 template <typename D1, typename D2>
121 class deref_compose : public deref_base
122 <
123  deref_compose<typename D1::const_t, typename D2::const_t>,
124  typename D1::value_type,
125  typename D1::reference,
126  typename D1::const_reference,
127  typename D2::argument_type,
128  typename D1::result_type,
129  D1::is_mutable && D2::is_mutable
130 >
131 {
132 public:
133  D1 _fn1;
134  D2 _fn2;
135 
136  using argument_type = typename D2::argument_type;
137  using result_type = typename D1::result_type;
138 
139  deref_compose() = default;
140  deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {}
141  deref_compose(const deref_compose& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
142 
143  template <typename _D1, typename _D2>
145  : _fn1(dc._fn1), _fn2(dc._fn2)
146  {}
147 
148  result_type operator()(argument_type x) const { return _fn1(_fn2(x)); }
149  result_type operator()(argument_type x) { return _fn1(_fn2(x)); }
150 };
151 
152 // reinterpret_cast is implementation-defined. Static cast is not.
153 template <typename OutPtr, typename In>
154 BOOST_FORCEINLINE
155 auto gil_reinterpret_cast(In* p) -> OutPtr
156 {
157  return static_cast<OutPtr>(static_cast<void*>(p));
158 }
159 
160 template <typename OutPtr, typename In>
161 BOOST_FORCEINLINE
162 auto gil_reinterpret_cast_c(In const* p) -> OutPtr const
163 {
164  return static_cast<OutPtr const>(static_cast<void const*>(p));
165 }
166 
167 namespace detail {
168 
172 
173 template <class InputIter, class Size, class OutputIter>
174 auto _copy_n(InputIter first, Size count, OutputIter result, std::input_iterator_tag)
175  -> std::pair<InputIter, OutputIter>
176 {
177  for ( ; count > 0; --count)
178  {
179  *result = *first;
180  ++first;
181  ++result;
182  }
183  return std::pair<InputIter, OutputIter>(first, result);
184 }
185 
186 template <class RAIter, class Size, class OutputIter>
187 inline auto _copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag)
188  -> std::pair<RAIter, OutputIter>
189 {
190  RAIter last = first + count;
191  return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result));
192 }
193 
194 template <class InputIter, class Size, class OutputIter>
195 inline auto _copy_n(InputIter first, Size count, OutputIter result)
196  -> std::pair<InputIter, OutputIter>
197 {
198  return _copy_n(first, count, result, typename std::iterator_traits<InputIter>::iterator_category());
199 }
200 
201 template <class InputIter, class Size, class OutputIter>
202 inline auto copy_n(InputIter first, Size count, OutputIter result)
203  -> std::pair<InputIter, OutputIter>
204 {
205  return detail::_copy_n(first, count, result);
206 }
207 
209 template <typename T>
210 struct identity
211 {
212  using argument_type = T;
213  using result_type = T;
214  const T& operator()(const T& val) const { return val; }
215 };
216 
218 template <typename T1, typename T2>
220  using first_argument_type = T1;
221  using second_argument_type = T2;
222  using result_type = T1;
223  T1 operator()(T1 f1, T2 f2) const
224  {
225  return f1+f2;
226  }
227 };
228 
230 template <typename T>
231 struct inc
232 {
233  using argument_type = T;
234  using result_type = T;
235  T operator()(T x) const { return ++x; }
236 };
237 
239 template <typename T>
240 struct dec
241 {
242  using argument_type = T;
243  using result_type = T;
244  T operator()(T x) const { return --x; }
245 };
246 
248 // a given Boost.MP11-compatible list (or size if the type is not present)
249 template <typename Types, typename T>
250 struct type_to_index : mp11::mp_find<Types, T>
251 {
252  static_assert(mp11::mp_contains<Types, T>::value, "T should be element of Types");
253 };
254 
255 } // namespace detail
256 
259 template
260 <
261  typename ColorSpace,
262  typename ChannelMapping = mp11::mp_iota
263  <
264  std::integral_constant<int, mp11::mp_size<ColorSpace>::value>
265  >
266 >
267 struct layout
268 {
269  using color_space_t = ColorSpace;
270  using channel_mapping_t = ChannelMapping;
271 
272  static_assert(mp11::mp_size<ColorSpace>::value > 0,
273  "color space should not be empty sequence");
274 };
275 
278 template <typename Value, typename T1, typename T2>
279 void swap_proxy(T1& left, T2& right)
280 {
281  Value tmp = left;
282  left = right;
283  right = tmp;
284 }
285 
287 BOOST_FORCEINLINE bool little_endian()
288 {
289  short tester = 0x0001;
290  return *(char*)&tester!=0;
291 }
293 BOOST_FORCEINLINE bool big_endian()
294 {
295  return !little_endian();
296 }
297 
298 }} // namespace boost::gil
299 
300 #endif
Composes two dereference function objects. Similar to std::unary_compose but needs to pull some alias...
Definition: utilities.hpp:131
BOOST_FORCEINLINE auto copy(boost::gil::pixel< T, CS > *first, boost::gil::pixel< T, CS > *last, boost::gil::pixel< T, CS > *dst) -> boost::gil::pixel< T, CS > *
Copy when both src and dst are interleaved and of the same type can be just memmove.
Definition: algorithm.hpp:145
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36
Helper base class for pixel dereference adaptors.
Definition: utilities.hpp:107
operator– wrapped in a function object
Definition: utilities.hpp:241
identity taken from SGI STL.
Definition: utilities.hpp:211
operator++ wrapped in a function object
Definition: utilities.hpp:232
plus function object whose arguments may be of different type.
Definition: utilities.hpp:219
Returns the index corresponding to the first occurrence of a given given type in.
Definition: utilities.hpp:251
Represents a color space and ordering of channels in memory.
Definition: utilities.hpp:268