]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/gil/promote_integral.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / gil / promote_integral.hpp
CommitLineData
92f5a8d4
TL
1// Boost.GIL (Generic Image Library)
2//
3// Copyright (c) 2015, Oracle and/or its affiliates.
4// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
f67539c2
TL
5//
6// Copyright (c) 2020, Debabrata Mandal <mandaldebabrata123@gmail.com>
92f5a8d4
TL
7//
8// Licensed under the Boost Software License version 1.0.
9// http://www.boost.org/users/license.html
10//
11// Source: Boost.Geometry (aka GGL, Generic Geometry Library)
12// Modifications: adapted for Boost.GIL
13// - Rename namespace boost::geometry to boost::gil
14// - Rename include guards
15// - Remove support for boost::multiprecision types
16// - Remove support for 128-bit integer types
f67539c2 17// - Replace mpl meta functions with mp11 equivalents
92f5a8d4
TL
18//
19#ifndef BOOST_GIL_PROMOTE_INTEGRAL_HPP
20#define BOOST_GIL_PROMOTE_INTEGRAL_HPP
21
f67539c2 22#include <boost/mp11/list.hpp>
92f5a8d4
TL
23
24#include <climits>
25#include <cstddef>
26#include <type_traits>
27
28namespace boost { namespace gil
29{
30
31namespace detail { namespace promote_integral
32{
33
34// meta-function that returns the bit size of a type
35template
36<
37 typename T,
38 bool IsFundamental = std::is_fundamental<T>::value
39>
40struct bit_size {};
41
42// for fundamental types, just return CHAR_BIT * sizeof(T)
43template <typename T>
44struct bit_size<T, true> : std::integral_constant<std::size_t, (CHAR_BIT * sizeof(T))> {};
45
46template
47<
48 typename T,
f67539c2 49 typename IntegralTypes,
92f5a8d4
TL
50 std::size_t MinSize
51>
52struct promote_to_larger
53{
f67539c2
TL
54 using current_type = boost::mp11::mp_first<IntegralTypes>;
55 using list_after_front = boost::mp11::mp_rest<IntegralTypes>;
92f5a8d4
TL
56
57 using type = typename std::conditional
58 <
59 (bit_size<current_type>::value >= MinSize),
60 current_type,
61 typename promote_to_larger
62 <
63 T,
f67539c2 64 list_after_front,
92f5a8d4
TL
65 MinSize
66 >::type
67 >::type;
68};
69
70// The following specialization is required to finish the loop over
71// all list elements
f67539c2
TL
72template <typename T, std::size_t MinSize>
73struct promote_to_larger<T, boost::mp11::mp_list<>, MinSize>
92f5a8d4
TL
74{
75 // if promotion fails, keep the number T
76 // (and cross fingers that overflow will not occur)
77 using type = T;
78};
79
80}} // namespace detail::promote_integral
81
82/*!
83 \brief Meta-function to define an integral type with size
84 than is (roughly) twice the bit size of T
85 \ingroup utility
86 \details
87 This meta-function tries to promote the fundamental integral type T
88 to a another integral type with size (roughly) twice the bit size of T.
89
90 To do this, two times the bit size of T is tested against the bit sizes of:
91 short, int, long, boost::long_long_type, boost::int128_t
92 and the one that first matches is chosen.
93
94 For unsigned types the bit size of T is tested against the bit
95 sizes of the types above, if T is promoted to a signed type, or
96 the bit sizes of
97 unsigned short, unsigned int, unsigned long, std::size_t,
98 boost::ulong_long_type, boost::uint128_t
99 if T is promoted to an unsigned type.
100
101 By default an unsigned type is promoted to a signed type.
102 This behavior is controlled by the PromoteUnsignedToUnsigned
103 boolean template parameter, whose default value is "false".
104 To promote an unsigned type to an unsigned type set the value of
105 this template parameter to "true".
106
107 Finally, if the passed type is either a floating-point type or a
108 user-defined type it is returned as is.
109
110 \note boost::long_long_type and boost::ulong_long_type are
111 considered only if the macro BOOST_HAS_LONG_LONG is defined
112
113*/
114template
115<
116 typename T,
117 bool PromoteUnsignedToUnsigned = false,
118 bool UseCheckedInteger = false,
119 bool IsIntegral = std::is_integral<T>::value
120>
121class promote_integral
122{
123private:
124 static bool const is_unsigned = std::is_unsigned<T>::value;
125
126 using bit_size_type = detail::promote_integral::bit_size<T>;
127
128 // Define the minimum size (in bits) needed for the promoted type
129 // If T is the input type and P the promoted type, then the
130 // minimum number of bits for P are (below b stands for the number
131 // of bits of T):
132 // * if T is unsigned and P is unsigned: 2 * b
133 // * if T is signed and P is signed: 2 * b - 1
134 // * if T is unsigned and P is signed: 2 * b + 1
135 using min_bit_size_type = typename std::conditional
136 <
137 (PromoteUnsignedToUnsigned && is_unsigned),
138 std::integral_constant<std::size_t, (2 * bit_size_type::value)>,
139 typename std::conditional
140 <
141 is_unsigned,
142 std::integral_constant<std::size_t, (2 * bit_size_type::value + 1)>,
143 std::integral_constant<std::size_t, (2 * bit_size_type::value - 1)>
144 >::type
145 >::type;
146
147 // Define the list of signed integral types we are going to use
148 // for promotion
f67539c2 149 using signed_integral_types = boost::mp11::mp_list
92f5a8d4
TL
150 <
151 short, int, long
152#if defined(BOOST_HAS_LONG_LONG)
153 , boost::long_long_type
154#endif
155 >;
156
157 // Define the list of unsigned integral types we are going to use
158 // for promotion
f67539c2 159 using unsigned_integral_types = boost::mp11::mp_list
92f5a8d4
TL
160 <
161 unsigned short, unsigned int, unsigned long, std::size_t
162#if defined(BOOST_HAS_LONG_LONG)
163 , boost::ulong_long_type
164#endif
165 >;
166
167 // Define the list of integral types that will be used for
168 // promotion (depending in whether we was to promote unsigned to
169 // unsigned or not)
170 using integral_types = typename std::conditional
171 <
172 (is_unsigned && PromoteUnsignedToUnsigned),
173 unsigned_integral_types,
174 signed_integral_types
175 >::type;
176
177public:
178 using type = typename detail::promote_integral::promote_to_larger
179 <
180 T,
f67539c2 181 integral_types,
92f5a8d4
TL
182 min_bit_size_type::value
183 >::type;
184};
185
186
187template <typename T, bool PromoteUnsignedToUnsigned, bool UseCheckedInteger>
188class promote_integral
189 <
190 T, PromoteUnsignedToUnsigned, UseCheckedInteger, false
191 >
192{
193public:
194 using type = T;
195};
196
197}} // namespace boost::gil
198
199#endif // BOOST_GIL_PROMOTE_INTEGRAL_HPP