File indexing completed on 2025-01-18 09:42:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #ifndef BOOST_OLD_NUMERIC_CAST_HPP
0049 #define BOOST_OLD_NUMERIC_CAST_HPP
0050
0051 # include <boost/config.hpp>
0052 # include <cassert>
0053 # include <typeinfo>
0054 # include <boost/type.hpp>
0055 # include <boost/limits.hpp>
0056 # include <boost/numeric/conversion/converter_policies.hpp>
0057
0058 namespace boost
0059 {
0060 using numeric::bad_numeric_cast;
0061
0062
0063
0064
0065
0066
0067
0068 #if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_SGI_CPP_LIMITS)
0069
0070 namespace detail
0071 {
0072 template <class T>
0073 struct signed_numeric_limits : std::numeric_limits<T>
0074 {
0075 static inline T min BOOST_PREVENT_MACRO_SUBSTITUTION ()
0076 {
0077 return (std::numeric_limits<T>::min)() >= 0
0078
0079 ? static_cast<T>(-(std::numeric_limits<T>::max)())
0080 : (std::numeric_limits<T>::min)();
0081 };
0082 };
0083
0084
0085 template <class T, bool specialized>
0086 struct fixed_numeric_limits_base
0087 : public if_true< std::numeric_limits<T>::is_signed >
0088 ::BOOST_NESTED_TEMPLATE then< signed_numeric_limits<T>,
0089 std::numeric_limits<T>
0090 >::type
0091 {};
0092
0093 template <class T>
0094 struct fixed_numeric_limits
0095 : fixed_numeric_limits_base<T,(std::numeric_limits<T>::is_specialized)>
0096 {};
0097
0098 # ifdef BOOST_HAS_LONG_LONG
0099
0100
0101
0102 template <>
0103 struct fixed_numeric_limits_base< ::boost::long_long_type, false>
0104 {
0105 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
0106 BOOST_STATIC_CONSTANT(bool, is_signed = true);
0107 static ::boost::long_long_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
0108 {
0109 # ifdef LONGLONG_MAX
0110 return LONGLONG_MAX;
0111 # else
0112 return 9223372036854775807LL;
0113 # endif
0114 }
0115
0116 static ::boost::long_long_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
0117 {
0118 # ifdef LONGLONG_MIN
0119 return LONGLONG_MIN;
0120 # else
0121 return -( 9223372036854775807LL )-1;
0122 # endif
0123 }
0124 };
0125
0126 template <>
0127 struct fixed_numeric_limits_base< ::boost::ulong_long_type, false>
0128 {
0129 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
0130 BOOST_STATIC_CONSTANT(bool, is_signed = false);
0131 static ::boost::ulong_long_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
0132 {
0133 # ifdef ULONGLONG_MAX
0134 return ULONGLONG_MAX;
0135 # else
0136 return 0xffffffffffffffffULL;
0137 # endif
0138 }
0139
0140 static ::boost::ulong_long_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
0141 };
0142 # endif
0143 }
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 template <bool x_is_signed, bool y_is_signed>
0155 struct less_than_type_min
0156 {
0157 template <class X, class Y>
0158 static bool check(X x, Y y_min)
0159 { return x < y_min; }
0160 };
0161
0162 template <>
0163 struct less_than_type_min<false, true>
0164 {
0165 template <class X, class Y>
0166 static bool check(X, Y)
0167 { return false; }
0168 };
0169
0170 template <>
0171 struct less_than_type_min<true, false>
0172 {
0173 template <class X, class Y>
0174 static bool check(X x, Y)
0175 { return x < 0; }
0176 };
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 template <bool same_sign, bool x_is_signed>
0188 struct greater_than_type_max;
0189
0190 template<>
0191 struct greater_than_type_max<true, true>
0192 {
0193 template <class X, class Y>
0194 static inline bool check(X x, Y y_max)
0195 { return x > y_max; }
0196 };
0197
0198 template <>
0199 struct greater_than_type_max<false, true>
0200 {
0201
0202
0203 template <class X, class Y>
0204 static inline bool check(X x, Y)
0205 { return x >= 0 && static_cast<X>(static_cast<Y>(x)) != x; }
0206 };
0207
0208 template<>
0209 struct greater_than_type_max<true, false>
0210 {
0211 template <class X, class Y>
0212 static inline bool check(X x, Y y_max)
0213 { return x > y_max; }
0214 };
0215
0216 template <>
0217 struct greater_than_type_max<false, false>
0218 {
0219
0220
0221 template <class X, class Y>
0222 static inline bool check(X x, Y)
0223 { return static_cast<X>(static_cast<Y>(x)) != x; }
0224 };
0225
0226 #else
0227
0228 namespace detail
0229 {
0230 # if BOOST_MSVC
0231 # pragma warning(push)
0232 # pragma warning(disable : 4018)
0233 # pragma warning(disable : 4146)
0234 #elif defined(BOOST_BORLANDC)
0235 # pragma option push -w-8041
0236 # endif
0237
0238
0239 template <class T>
0240 struct fixed_numeric_limits : public std::numeric_limits<T>
0241 {
0242 static inline T min BOOST_PREVENT_MACRO_SUBSTITUTION ()
0243 {
0244 return std::numeric_limits<T>::is_signed && (std::numeric_limits<T>::min)() >= 0
0245 ? T(-(std::numeric_limits<T>::max)()) : (std::numeric_limits<T>::min)();
0246 }
0247 };
0248
0249 # if BOOST_MSVC
0250 # pragma warning(pop)
0251 #elif defined(BOOST_BORLANDC)
0252 # pragma option pop
0253 # endif
0254 }
0255
0256 #endif
0257
0258 template<typename Target, typename Source>
0259 inline Target numeric_cast(Source arg)
0260 {
0261
0262 typedef detail::fixed_numeric_limits<Source> arg_traits;
0263 typedef detail::fixed_numeric_limits<Target> result_traits;
0264
0265 #if defined(BOOST_STRICT_CONFIG) \
0266 || (!defined(__HP_aCC) || __HP_aCC > 33900) \
0267 && (!defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) \
0268 || defined(BOOST_SGI_CPP_LIMITS))
0269
0270
0271
0272 typedef bool argument_must_be_numeric[arg_traits::is_specialized];
0273 typedef bool result_must_be_numeric[result_traits::is_specialized];
0274
0275 const bool arg_is_signed = arg_traits::is_signed;
0276 const bool result_is_signed = result_traits::is_signed;
0277 const bool same_sign = arg_is_signed == result_is_signed;
0278
0279 if (less_than_type_min<arg_is_signed, result_is_signed>::check(arg, (result_traits::min)())
0280 || greater_than_type_max<same_sign, arg_is_signed>::check(arg, (result_traits::max)())
0281 )
0282
0283 #else
0284
0285 # if BOOST_MSVC
0286 # pragma warning(push)
0287 # pragma warning(disable : 4018)
0288 #elif defined(BOOST_BORLANDC)
0289 #pragma option push -w-8012
0290 # endif
0291 if ((arg < 0 && !result_traits::is_signed)
0292 || (arg_traits::is_signed && arg < (result_traits::min)())
0293 || arg > (result_traits::max)())
0294 # if BOOST_MSVC
0295 # pragma warning(pop)
0296 #elif defined(BOOST_BORLANDC)
0297 #pragma option pop
0298 # endif
0299 #endif
0300 {
0301 throw bad_numeric_cast();
0302 }
0303 return static_cast<Target>(arg);
0304 }
0305
0306 }
0307
0308 #endif