annotate DEPENDENCIES/generic/include/boost/geometry/util/promote_integral.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@102 2
Chris@102 3 // Copyright (c) 2015, Oracle and/or its affiliates.
Chris@102 4
Chris@102 5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
Chris@102 6
Chris@102 7 // Licensed under the Boost Software License version 1.0.
Chris@102 8 // http://www.boost.org/users/license.html
Chris@102 9
Chris@102 10 #ifndef BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
Chris@102 11 #define BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
Chris@102 12
Chris@102 13 // For now deactivate the use of multiprecision integers
Chris@102 14 // TODO: activate it later
Chris@102 15 #define BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
Chris@102 16
Chris@102 17 #include <climits>
Chris@102 18 #include <cstddef>
Chris@102 19
Chris@102 20 #include <boost/mpl/begin.hpp>
Chris@102 21 #include <boost/mpl/deref.hpp>
Chris@102 22 #include <boost/mpl/end.hpp>
Chris@102 23 #include <boost/mpl/if.hpp>
Chris@102 24 #include <boost/mpl/list.hpp>
Chris@102 25 #include <boost/mpl/next.hpp>
Chris@102 26 #include <boost/mpl/size_t.hpp>
Chris@102 27
Chris@102 28 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
Chris@102 29 #include <boost/multiprecision/cpp_int.hpp>
Chris@102 30 #endif
Chris@102 31
Chris@102 32 #include <boost/type_traits/integral_constant.hpp>
Chris@102 33 #include <boost/type_traits/is_fundamental.hpp>
Chris@102 34 #include <boost/type_traits/is_integral.hpp>
Chris@102 35 #include <boost/type_traits/is_unsigned.hpp>
Chris@102 36
Chris@102 37
Chris@102 38 namespace boost { namespace geometry
Chris@102 39 {
Chris@102 40
Chris@102 41 #ifndef DOXYGEN_NO_DETAIL
Chris@102 42 namespace detail { namespace promote_integral
Chris@102 43 {
Chris@102 44
Chris@102 45 // meta-function that returns the bit size of a type
Chris@102 46 template
Chris@102 47 <
Chris@102 48 typename T,
Chris@102 49 bool IsFundamental = boost::is_fundamental<T>::type::value
Chris@102 50 >
Chris@102 51 struct bit_size
Chris@102 52 {};
Chris@102 53
Chris@102 54
Chris@102 55 // for fundamental types, just return CHAR_BIT * sizeof(T)
Chris@102 56 template <typename T>
Chris@102 57 struct bit_size<T, true>
Chris@102 58 : boost::mpl::size_t<(CHAR_BIT * sizeof(T))>
Chris@102 59 {};
Chris@102 60
Chris@102 61
Chris@102 62 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
Chris@102 63 // partial specialization for cpp_int
Chris@102 64 template
Chris@102 65 <
Chris@102 66 unsigned MinSize,
Chris@102 67 unsigned MaxSize,
Chris@102 68 boost::multiprecision::cpp_integer_type SignType,
Chris@102 69 boost::multiprecision::cpp_int_check_type Checked,
Chris@102 70 typename Allocator,
Chris@102 71 boost::multiprecision::expression_template_option ExpressionTemplates
Chris@102 72 >
Chris@102 73 struct bit_size
Chris@102 74 <
Chris@102 75 boost::multiprecision::number
Chris@102 76 <
Chris@102 77 boost::multiprecision::cpp_int_backend
Chris@102 78 <
Chris@102 79 MinSize, MaxSize, SignType, Checked, Allocator
Chris@102 80 >,
Chris@102 81 ExpressionTemplates
Chris@102 82 >,
Chris@102 83 false
Chris@102 84 > : boost::mpl::size_t<MaxSize>
Chris@102 85 {};
Chris@102 86 #endif // BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
Chris@102 87
Chris@102 88
Chris@102 89 template
Chris@102 90 <
Chris@102 91 typename T,
Chris@102 92 typename Iterator,
Chris@102 93 typename EndIterator,
Chris@102 94 std::size_t MinSize
Chris@102 95 >
Chris@102 96 struct promote_to_larger
Chris@102 97 {
Chris@102 98 typedef typename boost::mpl::deref<Iterator>::type current_type;
Chris@102 99
Chris@102 100 typedef typename boost::mpl::if_c
Chris@102 101 <
Chris@102 102 (bit_size<current_type>::type::value >= MinSize),
Chris@102 103 current_type,
Chris@102 104 typename promote_to_larger
Chris@102 105 <
Chris@102 106 T,
Chris@102 107 typename boost::mpl::next<Iterator>::type,
Chris@102 108 EndIterator,
Chris@102 109 MinSize
Chris@102 110 >::type
Chris@102 111 >::type type;
Chris@102 112 };
Chris@102 113
Chris@102 114 // The following specialization is required to finish the loop over
Chris@102 115 // all list elements
Chris@102 116 template <typename T, typename EndIterator, std::size_t MinSize>
Chris@102 117 struct promote_to_larger<T, EndIterator, EndIterator, MinSize>
Chris@102 118 {
Chris@102 119 // if promotion fails, keep the number T
Chris@102 120 // (and cross fingers that overflow will not occur)
Chris@102 121 typedef T type;
Chris@102 122 };
Chris@102 123
Chris@102 124 }} // namespace detail::promote_integral
Chris@102 125 #endif // DOXYGEN_NO_DETAIL
Chris@102 126
Chris@102 127
Chris@102 128
Chris@102 129 /*!
Chris@102 130 \brief Meta-function to define an integral type with size
Chris@102 131 than is (roughly) twice the bit size of T
Chris@102 132 \ingroup utility
Chris@102 133 \details
Chris@102 134 This meta-function tries to promote the fundamental integral type T
Chris@102 135 to a another integral type with size (roughly) twice the bit size of T.
Chris@102 136
Chris@102 137 To do this, two times the bit size of T is tested against the bit sizes of:
Chris@102 138 short, int, long, boost::long_long_type, boost::int128_t
Chris@102 139 and the one that first matches is chosen.
Chris@102 140
Chris@102 141 For unsigned types the bit size of T is tested against the bit
Chris@102 142 sizes of the types above, if T is promoted to a signed type, or
Chris@102 143 the bit sizes of
Chris@102 144 unsigned short, unsigned int, unsigned long, std::size_t,
Chris@102 145 boost::ulong_long_type, boost::uint128_t
Chris@102 146 if T is promoted to an unsigned type.
Chris@102 147
Chris@102 148 By default an unsigned type is promoted to a signed type.
Chris@102 149 This behavior is controlled by the PromoteUnsignedToUnsigned
Chris@102 150 boolean template parameter, whose default value is "false".
Chris@102 151 To promote an unsigned type to an unsigned type set the value of
Chris@102 152 this template parameter to "true".
Chris@102 153
Chris@102 154 If the macro BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER is not
Chris@102 155 defined, boost's multiprecision integer cpp_int<> is used as a
Chris@102 156 last resort.
Chris@102 157
Chris@102 158 If BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER is defined and an
Chris@102 159 appropriate type cannot be detected, the input type is returned as is.
Chris@102 160
Chris@102 161 Finally, if the passed type is either a floating-point type or a
Chris@102 162 user-defined type it is returned as is.
Chris@102 163
Chris@102 164 \note boost::long_long_type and boost::ulong_long_type are
Chris@102 165 considered only if the macro BOOST_HAS_LONG_LONG is defined
Chris@102 166
Chris@102 167 \note boost::int128_type and boost::uint128_type are considered
Chris@102 168 only if the macros BOOST_HAS_INT128 and BOOST_GEOMETRY_ENABLE_INT128
Chris@102 169 are defined
Chris@102 170 */
Chris@102 171 template
Chris@102 172 <
Chris@102 173 typename T,
Chris@102 174 bool PromoteUnsignedToUnsigned = false,
Chris@102 175 bool UseCheckedInteger = false,
Chris@102 176 bool IsIntegral = boost::is_integral<T>::type::value
Chris@102 177 >
Chris@102 178 class promote_integral
Chris@102 179 {
Chris@102 180 private:
Chris@102 181 static bool const is_unsigned = boost::is_unsigned<T>::type::value;
Chris@102 182
Chris@102 183 typedef detail::promote_integral::bit_size<T> bit_size_type;
Chris@102 184
Chris@102 185 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
Chris@102 186 // Define the proper check policy for the multiprecision integer
Chris@102 187 typedef typename boost::mpl::if_c
Chris@102 188 <
Chris@102 189 UseCheckedInteger,
Chris@102 190 boost::integral_constant
Chris@102 191 <
Chris@102 192 boost::multiprecision::cpp_int_check_type,
Chris@102 193 boost::multiprecision::checked
Chris@102 194 >,
Chris@102 195 boost::integral_constant
Chris@102 196 <
Chris@102 197 boost::multiprecision::cpp_int_check_type,
Chris@102 198 boost::multiprecision::unchecked
Chris@102 199 >
Chris@102 200 >::type check_policy_type;
Chris@102 201
Chris@102 202 // Meta-function to get the multiprecision integer type for the
Chris@102 203 // given size and sign type (signed/unsigned)
Chris@102 204 template
Chris@102 205 <
Chris@102 206 unsigned int Size,
Chris@102 207 boost::multiprecision::cpp_integer_type SignType
Chris@102 208 >
Chris@102 209 struct multiprecision_integer_type
Chris@102 210 {
Chris@102 211 typedef boost::multiprecision::number
Chris@102 212 <
Chris@102 213 boost::multiprecision::cpp_int_backend
Chris@102 214 <
Chris@102 215 Size,
Chris@102 216 Size,
Chris@102 217 SignType,
Chris@102 218 check_policy_type::value,
Chris@102 219 void
Chris@102 220 >
Chris@102 221 > type;
Chris@102 222 };
Chris@102 223 #endif
Chris@102 224
Chris@102 225 // Define the minimum size (in bits) needed for the promoted type
Chris@102 226 // If T is the input type and P the promoted type, then the
Chris@102 227 // minimum number of bits for P are (below b stands for the number
Chris@102 228 // of bits of T):
Chris@102 229 // * if T is unsigned and P is unsigned: 2 * b
Chris@102 230 // * if T is signed and P is signed: 2 * b - 1
Chris@102 231 // * if T is unsigned and P is signed: 2 * b + 1
Chris@102 232 typedef typename boost::mpl::if_c
Chris@102 233 <
Chris@102 234 (PromoteUnsignedToUnsigned && is_unsigned),
Chris@102 235 boost::mpl::size_t<(2 * bit_size_type::value)>,
Chris@102 236 typename boost::mpl::if_c
Chris@102 237 <
Chris@102 238 is_unsigned,
Chris@102 239 boost::mpl::size_t<(2 * bit_size_type::value + 1)>,
Chris@102 240 boost::mpl::size_t<(2 * bit_size_type::value - 1)>
Chris@102 241 >::type
Chris@102 242 >::type min_bit_size_type;
Chris@102 243
Chris@102 244 // Define the list of signed integral types we are going to use
Chris@102 245 // for promotion
Chris@102 246 typedef boost::mpl::list
Chris@102 247 <
Chris@102 248 short, int, long
Chris@102 249 #if defined(BOOST_HAS_LONG_LONG)
Chris@102 250 , boost::long_long_type
Chris@102 251 #endif
Chris@102 252 #if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
Chris@102 253 , boost::int128_type
Chris@102 254 #endif
Chris@102 255 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
Chris@102 256 , typename multiprecision_integer_type
Chris@102 257 <
Chris@102 258 min_bit_size_type::value,
Chris@102 259 boost::multiprecision::signed_magnitude
Chris@102 260 >::type
Chris@102 261 #endif
Chris@102 262 > signed_integral_types;
Chris@102 263
Chris@102 264 // Define the list of unsigned integral types we are going to use
Chris@102 265 // for promotion
Chris@102 266 typedef boost::mpl::list
Chris@102 267 <
Chris@102 268 unsigned short, unsigned int, unsigned long, std::size_t
Chris@102 269 #if defined(BOOST_HAS_LONG_LONG)
Chris@102 270 , boost::ulong_long_type
Chris@102 271 #endif
Chris@102 272 #if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
Chris@102 273 , boost::uint128_type
Chris@102 274 #endif
Chris@102 275 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
Chris@102 276 , typename multiprecision_integer_type
Chris@102 277 <
Chris@102 278 min_bit_size_type::value,
Chris@102 279 boost::multiprecision::unsigned_magnitude
Chris@102 280 >::type
Chris@102 281 #endif
Chris@102 282 > unsigned_integral_types;
Chris@102 283
Chris@102 284 // Define the list of integral types that will be used for
Chris@102 285 // promotion (depending in whether we was to promote unsigned to
Chris@102 286 // unsigned or not)
Chris@102 287 typedef typename boost::mpl::if_c
Chris@102 288 <
Chris@102 289 (is_unsigned && PromoteUnsignedToUnsigned),
Chris@102 290 unsigned_integral_types,
Chris@102 291 signed_integral_types
Chris@102 292 >::type integral_types;
Chris@102 293
Chris@102 294 public:
Chris@102 295 typedef typename detail::promote_integral::promote_to_larger
Chris@102 296 <
Chris@102 297 T,
Chris@102 298 typename boost::mpl::begin<integral_types>::type,
Chris@102 299 typename boost::mpl::end<integral_types>::type,
Chris@102 300 min_bit_size_type::value
Chris@102 301 >::type type;
Chris@102 302 };
Chris@102 303
Chris@102 304
Chris@102 305 template <typename T, bool PromoteUnsignedToUnsigned, bool UseCheckedInteger>
Chris@102 306 class promote_integral
Chris@102 307 <
Chris@102 308 T, PromoteUnsignedToUnsigned, UseCheckedInteger, false
Chris@102 309 >
Chris@102 310 {
Chris@102 311 public:
Chris@102 312 typedef T type;
Chris@102 313 };
Chris@102 314
Chris@102 315
Chris@102 316 }} // namespace boost::geometry
Chris@102 317
Chris@102 318 #endif // BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP