File indexing completed on 2025-01-18 09:40:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_MATH_PROMOTION_HPP
0020 #define BOOST_MATH_PROMOTION_HPP
0021
0022 #ifdef _MSC_VER
0023 #pragma once
0024 #endif
0025
0026 #include <boost/math/tools/config.hpp>
0027 #include <type_traits>
0028
0029 #if defined __has_include
0030 # if __cplusplus > 202002L || _MSVC_LANG > 202002L
0031 # if __has_include (<stdfloat>)
0032 # include <stdfloat>
0033 # endif
0034 # endif
0035 #endif
0036
0037 namespace boost
0038 {
0039 namespace math
0040 {
0041 namespace tools
0042 {
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 template <class T>
0064 struct promote_arg
0065 {
0066 using type = typename std::conditional<std::is_integral<T>::value, double, T>::type;
0067 };
0068
0069
0070 template <> struct promote_arg<float> { using type = float; };
0071 template <> struct promote_arg<double>{ using type = double; };
0072 template <> struct promote_arg<long double> { using type = long double; };
0073 template <> struct promote_arg<int> { using type = double; };
0074
0075 #ifdef __STDCPP_FLOAT16_T__
0076 template <> struct promote_arg<std::float16_t> { using type = std::float16_t; };
0077 #endif
0078 #ifdef __STDCPP_FLOAT32_T__
0079 template <> struct promote_arg<std::float32_t> { using type = std::float32_t; };
0080 #endif
0081 #ifdef __STDCPP_FLOAT64_T__
0082 template <> struct promote_arg<std::float64_t> { using type = std::float64_t; };
0083 #endif
0084 #ifdef __STDCPP_FLOAT128_T__
0085 template <> struct promote_arg<std::float128_t> { using type = std::float128_t; };
0086 #endif
0087
0088 template <typename T>
0089 using promote_arg_t = typename promote_arg<T>::type;
0090
0091 template <class T1, class T2>
0092 struct promote_args_2
0093 {
0094
0095 using T1P = typename promote_arg<T1>::type;
0096 using T2P = typename promote_arg<T2>::type;
0097 using intermediate_type = typename std::conditional<
0098 std::is_floating_point<T1P>::value && std::is_floating_point<T2P>::value,
0099 #ifdef __STDCPP_FLOAT128_T__
0100 typename std::conditional<std::is_same<std::float128_t, T1P>::value || std::is_same<std::float128_t, T2P>::value,
0101 std::float128_t,
0102 #endif
0103 #ifdef BOOST_MATH_USE_FLOAT128
0104 typename std::conditional<std::is_same<__float128, T1P>::value || std::is_same<__float128, T2P>::value,
0105 __float128,
0106 #endif
0107 typename std::conditional<std::is_same<long double, T1P>::value || std::is_same<long double, T2P>::value,
0108 long double,
0109 #ifdef __STDCPP_FLOAT64_T__
0110 typename std::conditional<std::is_same<std::float64_t, T1P>::value || std::is_same<std::float64_t, T2P>::value,
0111 std::float64_t,
0112 #endif
0113 typename std::conditional<std::is_same<double, T1P>::value || std::is_same<double, T2P>::value,
0114 double,
0115 #ifdef __STDCPP_FLOAT32_T__
0116 typename std::conditional<std::is_same<std::float32_t, T1P>::value || std::is_same<std::float32_t, T2P>::value,
0117 std::float32_t,
0118 #endif
0119 float
0120 >::type
0121 #ifdef BOOST_MATH_USE_FLOAT128
0122 >::type
0123 #endif
0124 #ifdef __STDCPP_FLOAT128_T__
0125 >::type
0126 #endif
0127 #ifdef __STDCPP_FLOAT64_T__
0128 >::type
0129 #endif
0130 #ifdef __STDCPP_FLOAT32_T__
0131 >::type
0132 #endif
0133 >::type,
0134
0135 typename std::conditional<!std::is_floating_point<T2P>::value && std::is_convertible<T1P, T2P>::value, T2P, T1P>::type>::type;
0136
0137 #ifdef __STDCPP_FLOAT64_T__
0138
0139 using type = std::conditional_t<(sizeof(double) == sizeof(long double) && std::is_same<intermediate_type, long double>::value), std::float64_t, intermediate_type>;
0140 #else
0141 using type = intermediate_type;
0142 #endif
0143 };
0144
0145
0146 template <> struct promote_args_2<float, float> { using type = float; };
0147 template <> struct promote_args_2<double, double>{ using type = double; };
0148 template <> struct promote_args_2<long double, long double> { using type = long double; };
0149 template <> struct promote_args_2<int, int> { using type = double; };
0150 template <> struct promote_args_2<int, float> { using type = double; };
0151 template <> struct promote_args_2<float, int> { using type = double; };
0152 template <> struct promote_args_2<int, double> { using type = double; };
0153 template <> struct promote_args_2<double, int> { using type = double; };
0154 template <> struct promote_args_2<int, long double> { using type = long double; };
0155 template <> struct promote_args_2<long double, int> { using type = long double; };
0156 template <> struct promote_args_2<float, double> { using type = double; };
0157 template <> struct promote_args_2<double, float> { using type = double; };
0158 template <> struct promote_args_2<float, long double> { using type = long double; };
0159 template <> struct promote_args_2<long double, float> { using type = long double; };
0160 template <> struct promote_args_2<double, long double> { using type = long double; };
0161 template <> struct promote_args_2<long double, double> { using type = long double; };
0162
0163 #ifdef __STDCPP_FLOAT128_T__
0164 template <> struct promote_args_2<int, std::float128_t> { using type = std::float128_t; };
0165 template <> struct promote_args_2<std::float128_t, int> { using type = std::float128_t; };
0166 template <> struct promote_args_2<std::float128_t, float> { using type = std::float128_t; };
0167 template <> struct promote_args_2<float, std::float128_t> { using type = std::float128_t; };
0168 template <> struct promote_args_2<std::float128_t, double> { using type = std::float128_t; };
0169 template <> struct promote_args_2<double, std::float128_t> { using type = std::float128_t; };
0170 template <> struct promote_args_2<std::float128_t, long double> { using type = std::float128_t; };
0171 template <> struct promote_args_2<long double, std::float128_t> { using type = std::float128_t; };
0172
0173 #ifdef __STDCPP_FLOAT16_T__
0174 template <> struct promote_args_2<std::float128_t, std::float16_t> { using type = std::float128_t; };
0175 template <> struct promote_args_2<std::float16_t, std::float128_t> { using type = std::float128_t; };
0176 #endif
0177
0178 #ifdef __STDCPP_FLOAT32_T__
0179 template <> struct promote_args_2<std::float128_t, std::float32_t> { using type = std::float128_t; };
0180 template <> struct promote_args_2<std::float32_t, std::float128_t> { using type = std::float128_t; };
0181 #endif
0182
0183 #ifdef __STDCPP_FLOAT64_T__
0184 template <> struct promote_args_2<std::float128_t, std::float64_t> { using type = std::float128_t; };
0185 template <> struct promote_args_2<std::float64_t, std::float128_t> { using type = std::float128_t; };
0186 #endif
0187
0188 template <> struct promote_args_2<std::float128_t, std::float128_t> { using type = std::float128_t; };
0189 #endif
0190
0191 #ifdef __STDCPP_FLOAT64_T__
0192 template <> struct promote_args_2<int, std::float64_t> { using type = std::float64_t; };
0193 template <> struct promote_args_2<std::float64_t, int> { using type = std::float64_t; };
0194 template <> struct promote_args_2<std::float64_t, float> { using type = std::float64_t; };
0195 template <> struct promote_args_2<float, std::float64_t> { using type = std::float64_t; };
0196 template <> struct promote_args_2<std::float64_t, double> { using type = std::float64_t; };
0197 template <> struct promote_args_2<double, std::float64_t> { using type = std::float64_t; };
0198 template <> struct promote_args_2<std::float64_t, long double> { using type = long double; };
0199 template <> struct promote_args_2<long double, std::float64_t> { using type = long double; };
0200
0201 #ifdef __STDCPP_FLOAT16_T__
0202 template <> struct promote_args_2<std::float64_t, std::float16_t> { using type = std::float64_t; };
0203 template <> struct promote_args_2<std::float16_t, std::float64_t> { using type = std::float64_t; };
0204 #endif
0205
0206 #ifdef __STDCPP_FLOAT32_T__
0207 template <> struct promote_args_2<std::float64_t, std::float32_t> { using type = std::float64_t; };
0208 template <> struct promote_args_2<std::float32_t, std::float64_t> { using type = std::float64_t; };
0209 #endif
0210
0211 template <> struct promote_args_2<std::float64_t, std::float64_t> { using type = std::float64_t; };
0212 #endif
0213
0214 #ifdef __STDCPP_FLOAT32_T__
0215 template <> struct promote_args_2<int, std::float32_t> { using type = std::float32_t; };
0216 template <> struct promote_args_2<std::float32_t, int> { using type = std::float32_t; };
0217 template <> struct promote_args_2<std::float32_t, float> { using type = std::float32_t; };
0218 template <> struct promote_args_2<float, std::float32_t> { using type = std::float32_t; };
0219 template <> struct promote_args_2<std::float32_t, double> { using type = double; };
0220 template <> struct promote_args_2<double, std::float32_t> { using type = double; };
0221 template <> struct promote_args_2<std::float32_t, long double> { using type = long double; };
0222 template <> struct promote_args_2<long double, std::float32_t> { using type = long double; };
0223
0224 #ifdef __STDCPP_FLOAT16_T__
0225 template <> struct promote_args_2<std::float32_t, std::float16_t> { using type = std::float32_t; };
0226 template <> struct promote_args_2<std::float16_t, std::float32_t> { using type = std::float32_t; };
0227 #endif
0228
0229 template <> struct promote_args_2<std::float32_t, std::float32_t> { using type = std::float32_t; };
0230 #endif
0231
0232 #ifdef __STDCPP_FLOAT16_T__
0233 template <> struct promote_args_2<int, std::float16_t> { using type = std::float16_t; };
0234 template <> struct promote_args_2<std::float16_t, int> { using type = std::float16_t; };
0235 template <> struct promote_args_2<std::float16_t, float> { using type = float; };
0236 template <> struct promote_args_2<float, std::float16_t> { using type = float; };
0237 template <> struct promote_args_2<std::float16_t, double> { using type = double; };
0238 template <> struct promote_args_2<double, std::float16_t> { using type = double; };
0239 template <> struct promote_args_2<std::float16_t, long double> { using type = long double; };
0240 template <> struct promote_args_2<long double, std::float16_t> { using type = long double; };
0241
0242 template <> struct promote_args_2<std::float16_t, std::float16_t> { using type = std::float16_t; };
0243 #endif
0244
0245 template <typename T, typename U>
0246 using promote_args_2_t = typename promote_args_2<T, U>::type;
0247
0248 template <class T1, class T2=float, class T3=float, class T4=float, class T5=float, class T6=float>
0249 struct promote_args
0250 {
0251 using type = typename promote_args_2<
0252 typename std::remove_cv<T1>::type,
0253 typename promote_args_2<
0254 typename std::remove_cv<T2>::type,
0255 typename promote_args_2<
0256 typename std::remove_cv<T3>::type,
0257 typename promote_args_2<
0258 typename std::remove_cv<T4>::type,
0259 typename promote_args_2<
0260 typename std::remove_cv<T5>::type, typename std::remove_cv<T6>::type
0261 >::type
0262 >::type
0263 >::type
0264 >::type
0265 >::type;
0266
0267 #if defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
0268
0269
0270
0271 static_assert((0 == std::is_same<type, long double>::value), "Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implemented.");
0272 #endif
0273 };
0274
0275 template <class T1, class T2=float, class T3=float, class T4=float, class T5=float, class T6=float>
0276 using promote_args_t = typename promote_args<T1, T2, T3, T4, T5, T6>::type;
0277
0278
0279
0280
0281
0282
0283 template <class T1, class T2=float, class T3=float, class T4=float, class T5=float, class T6=float>
0284 struct promote_args_permissive
0285 {
0286 using type = typename promote_args_2<
0287 typename std::remove_cv<T1>::type,
0288 typename promote_args_2<
0289 typename std::remove_cv<T2>::type,
0290 typename promote_args_2<
0291 typename std::remove_cv<T3>::type,
0292 typename promote_args_2<
0293 typename std::remove_cv<T4>::type,
0294 typename promote_args_2<
0295 typename std::remove_cv<T5>::type, typename std::remove_cv<T6>::type
0296 >::type
0297 >::type
0298 >::type
0299 >::type
0300 >::type;
0301 };
0302
0303 template <class T1, class T2=float, class T3=float, class T4=float, class T5=float, class T6=float>
0304 using promote_args_permissive_t = typename promote_args_permissive<T1, T2, T3, T4, T5, T6>::type;
0305
0306 }
0307 }
0308 }
0309
0310 #endif
0311