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