File indexing completed on 2025-01-18 09:36:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
0012 #define BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
0013
0014
0015
0016 #define BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
0017
0018
0019 #include <climits>
0020 #include <cstddef>
0021 #include <type_traits>
0022
0023 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
0024 #include <boost/multiprecision/cpp_int.hpp>
0025 #endif
0026
0027
0028 namespace boost { namespace geometry
0029 {
0030
0031 #ifndef DOXYGEN_NO_DETAIL
0032 namespace detail { namespace promote_integral
0033 {
0034
0035
0036 template
0037 <
0038 typename T,
0039 bool IsFundamental = std::is_fundamental<T>::value
0040 >
0041 struct bit_size
0042 {};
0043
0044
0045
0046 template <typename T>
0047 struct bit_size<T, true>
0048 : std::integral_constant<std::size_t, (CHAR_BIT * sizeof(T))>
0049 {};
0050
0051
0052 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
0053
0054 template
0055 <
0056 unsigned MinSize,
0057 unsigned MaxSize,
0058 boost::multiprecision::cpp_integer_type SignType,
0059 boost::multiprecision::cpp_int_check_type Checked,
0060 typename Allocator,
0061 boost::multiprecision::expression_template_option ExpressionTemplates
0062 >
0063 struct bit_size
0064 <
0065 boost::multiprecision::number
0066 <
0067 boost::multiprecision::cpp_int_backend
0068 <
0069 MinSize, MaxSize, SignType, Checked, Allocator
0070 >,
0071 ExpressionTemplates
0072 >,
0073 false
0074 >
0075 : std::integral_constant<std::size_t, MaxSize>
0076 {};
0077 #endif
0078
0079
0080 template <typename T, std::size_t MinSize, typename ...Ts>
0081 struct promote_to_larger
0082 {
0083
0084
0085 typedef T type;
0086 };
0087
0088 template <typename T, std::size_t MinSize, typename CurrentT, typename ...Ts>
0089 struct promote_to_larger<T, MinSize, CurrentT, Ts...>
0090 {
0091 typedef std::conditional_t
0092 <
0093 (bit_size<CurrentT>::value >= MinSize),
0094 CurrentT,
0095 typename promote_to_larger<T, MinSize, Ts...>::type
0096 > type;
0097 };
0098
0099 template <typename ...Ts>
0100 struct integral_types {};
0101
0102 template <typename T, std::size_t MinSize, typename ...Ts>
0103 struct promote_to_larger<T, MinSize, integral_types<Ts...>>
0104 : promote_to_larger<T, MinSize, Ts...>
0105 {};
0106
0107
0108 }}
0109 #endif
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 template
0153 <
0154 typename T,
0155 bool PromoteUnsignedToUnsigned = false,
0156 bool UseCheckedInteger = false,
0157 bool IsIntegral = std::is_integral<T>::value
0158 >
0159 class promote_integral
0160 {
0161 private:
0162 static bool const is_unsigned = std::is_unsigned<T>::value;
0163
0164 typedef detail::promote_integral::bit_size<T> bit_size_type;
0165
0166 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
0167
0168 typedef std::conditional_t
0169 <
0170 UseCheckedInteger,
0171 std::integral_constant
0172 <
0173 boost::multiprecision::cpp_int_check_type,
0174 boost::multiprecision::checked
0175 >,
0176 std::integral_constant
0177 <
0178 boost::multiprecision::cpp_int_check_type,
0179 boost::multiprecision::unchecked
0180 >
0181 > check_policy_type;
0182
0183
0184
0185 template
0186 <
0187 unsigned int Size,
0188 boost::multiprecision::cpp_integer_type SignType
0189 >
0190 struct multiprecision_integer_type
0191 {
0192 typedef boost::multiprecision::number
0193 <
0194 boost::multiprecision::cpp_int_backend
0195 <
0196 Size,
0197 Size,
0198 SignType,
0199 check_policy_type::value,
0200 void
0201 >
0202 > type;
0203 };
0204 #endif
0205
0206
0207
0208
0209
0210
0211
0212
0213 typedef std::conditional_t
0214 <
0215 (PromoteUnsignedToUnsigned && is_unsigned),
0216 std::integral_constant<std::size_t, (2 * bit_size_type::value)>,
0217 std::conditional_t
0218 <
0219 is_unsigned,
0220 std::integral_constant<std::size_t, (2 * bit_size_type::value + 1)>,
0221 std::integral_constant<std::size_t, (2 * bit_size_type::value - 1)>
0222 >
0223 > min_bit_size_type;
0224
0225
0226
0227 typedef detail::promote_integral::integral_types
0228 <
0229 short,
0230 int,
0231 long,
0232 long long
0233 #if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
0234 , boost::int128_type
0235 #endif
0236 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
0237 , typename multiprecision_integer_type
0238 <
0239 min_bit_size_type::value,
0240 boost::multiprecision::signed_magnitude
0241 >::type
0242 #endif
0243 > signed_integral_types;
0244
0245
0246
0247 typedef detail::promote_integral::integral_types
0248 <
0249 unsigned short,
0250 unsigned int,
0251 unsigned long,
0252 std::size_t,
0253 unsigned long long
0254 #if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
0255 , boost::uint128_type
0256 #endif
0257 #if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
0258 , typename multiprecision_integer_type
0259 <
0260 min_bit_size_type::value,
0261 boost::multiprecision::unsigned_magnitude
0262 >::type
0263 #endif
0264 > unsigned_integral_types;
0265
0266
0267
0268
0269 typedef std::conditional_t
0270 <
0271 (is_unsigned && PromoteUnsignedToUnsigned),
0272 unsigned_integral_types,
0273 signed_integral_types
0274 > integral_types;
0275
0276 public:
0277 typedef typename detail::promote_integral::promote_to_larger
0278 <
0279 T,
0280 min_bit_size_type::value,
0281 integral_types
0282 >::type type;
0283 };
0284
0285
0286 template <typename T, bool PromoteUnsignedToUnsigned, bool UseCheckedInteger>
0287 class promote_integral
0288 <
0289 T, PromoteUnsignedToUnsigned, UseCheckedInteger, false
0290 >
0291 {
0292 public:
0293 typedef T type;
0294 };
0295
0296
0297 }}
0298
0299 #endif