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
44namespace boost { namespace gil {
45
48
52
53inline std::ptrdiff_t iround(float x)
54{
55 return static_cast<std::ptrdiff_t>(x + (x < 0.0f ? -0.5f : 0.5f));
56}
57
58inline std::ptrdiff_t iround(double x)
59{
60 return static_cast<std::ptrdiff_t>(x + (x < 0.0 ? -0.5 : 0.5));
61}
62
63inline std::ptrdiff_t ifloor(float x)
64{
65 return static_cast<std::ptrdiff_t>(std::floor(x));
66}
67
68inline std::ptrdiff_t ifloor(double x)
69{
70 return static_cast<std::ptrdiff_t>(std::floor(x));
71}
72
73inline std::ptrdiff_t iceil(float x)
74{
75 return static_cast<std::ptrdiff_t>(std::ceil(x));
76}
77
78inline std::ptrdiff_t iceil(double x)
79{
80 return static_cast<std::ptrdiff_t>(std::ceil(x));
81}
82
86
87template <typename T>
88inline T align(T val, std::size_t alignment)
89{
90 return val+(alignment - val%alignment)%alignment;
91}
92
96template
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
120template <typename D1, typename D2>
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{
132public:
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.
153template <typename OutPtr, typename In>
154BOOST_FORCEINLINE
155auto gil_reinterpret_cast(In* p) -> OutPtr
156{
157 return static_cast<OutPtr>(static_cast<void*>(p));
158}
159
160template <typename OutPtr, typename In>
161BOOST_FORCEINLINE
162auto gil_reinterpret_cast_c(In const* p) -> OutPtr const
163{
164 return static_cast<OutPtr const>(static_cast<void const*>(p));
165}
166
167namespace detail {
168
172
173template <class InputIter, class Size, class OutputIter>
174auto _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
186template <class RAIter, class Size, class OutputIter>
187inline 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
194template <class InputIter, class Size, class OutputIter>
195inline 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
201template <class InputIter, class Size, class OutputIter>
202inline 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
209template <typename T>
211{
212 using argument_type = T;
213 using result_type = T;
214 const T& operator()(const T& val) const { return val; }
215};
216
218template <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
230template <typename T>
231struct inc
232{
233 using argument_type = T;
234 using result_type = T;
235 T operator()(T x) const { return ++x; }
236};
237
239template <typename T>
240struct 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)
249template <typename Types, typename T>
250struct 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
259template
260<
261 typename ColorSpace,
262 typename ChannelMapping = mp11::mp_iota
263 <
264 std::integral_constant<int, mp11::mp_size<ColorSpace>::value>
265 >
266>
267struct 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
278template <typename Value, typename T1, typename T2>
279void swap_proxy(T1& left, T2& right)
280{
281 Value tmp = left;
282 left = right;
283 right = tmp;
284}
285
287BOOST_FORCEINLINE bool little_endian()
288{
289 short tester = 0x0001;
290 return *(char*)&tester!=0;
291}
293BOOST_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
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