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