X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ceph%2Fsrc%2Fboost%2Fboost%2Fsafe_numerics%2Fsafe_base_operations.hpp;h=1c5d9ec50b0bc8a296fc95837a8045e9b70d3f5f;hb=20effc670b57271cb089376d6d0800990e5218d5;hp=d97ac921db97bbcca491dc2e32dfbdb5fbe67437;hpb=a71831dadd1e1f3e0fa70405511f65cc33db0498;p=ceph.git diff --git a/ceph/src/boost/boost/safe_numerics/safe_base_operations.hpp b/ceph/src/boost/boost/safe_numerics/safe_base_operations.hpp index d97ac921d..1c5d9ec50 100644 --- a/ceph/src/boost/boost/safe_numerics/safe_base_operations.hpp +++ b/ceph/src/boost/boost/safe_numerics/safe_base_operations.hpp @@ -10,7 +10,8 @@ #include #include // is_base_of, is_same, is_floating_point, conditional #include // max -#include +#include +#include #include @@ -63,7 +64,6 @@ struct validate_detail { template constexpr static R return_value(const T & t){ - constexpr const interval t_interval{ checked::cast(base_value(std::numeric_limits::min())), checked::cast(base_value(std::numeric_limits::max())) @@ -74,7 +74,6 @@ struct validate_detail { true != static_cast(r_interval.excludes(t_interval)), "can't cast from ranges that don't overlap" ); - return std::conditional< static_cast(r_interval.includes(t_interval)), exception_not_possible, @@ -90,70 +89,45 @@ validated_cast(const T & t) const { return validate_detail::return_value(t); } -template -template -constexpr Stored safe_base:: -validated_cast(const safe_literal_impl &) const { - constexpr const interval this_interval{}; - // if static values don't overlap, the program can never function - static_assert( - this_interval.includes(N), - "safe type cannot be constructed from this value" - ); - return static_cast(N); -} - ///////////////////////////////////////////////////////////////// // constructors -template - constexpr /*explicit*/ safe_base::safe_base( - const Stored & rhs, - skip_validation -) : - m_t(rhs) -{} - +// default constructor template constexpr /*explicit*/ safe_base::safe_base(){ dispatch( "safe values must be initialized" ); } - -// construct an instance of a safe type -// from an instance of a convertible underlying type. +// construct an instance of a safe type from an instance of a convertible underlying type. template -template constexpr /*explicit*/ safe_base::safe_base( - const T & t, - typename std::enable_if< - is_safe::value, - bool - >::type + const Stored & rhs, + skip_validation ) : - m_t(validated_cast(t)) + m_t(rhs) {} +// construct an instance from an instance of a convertible underlying type. template -template -constexpr /*explicit*/ safe_base::safe_base( - const T & t, - typename std::enable_if< - std::is_integral::value, - bool - >::type -) : + template< + class T, + typename std::enable_if< + std::is_convertible::value, + bool + >::type + > +constexpr /*explicit*/ safe_base::safe_base(const T &t) : m_t(validated_cast(t)) {} +// construct an instance of a safe type from a literal value template -template +template constexpr /*explicit*/ safe_base::safe_base( - - const std::integral_constant & + const safe_literal_impl & t ) : - m_t(validated_cast(value)) + m_t(validated_cast(t)) {} ///////////////////////////////////////////////////////////////// @@ -171,28 +145,18 @@ template< constexpr safe_base:: operator R () const { // if static values don't overlap, the program can never function - #if 1 constexpr const interval r_interval; constexpr const interval this_interval(Min, Max); static_assert( ! r_interval.excludes(this_interval), "safe type cannot be constructed with this type" ); - #endif - return validate_detail< R, std::numeric_limits::min(), std::numeric_limits::max(), E - >::return_value(*this); -} - -// cast to the underlying builtin type from a safe type -template -constexpr safe_base:: -operator Stored () const { - return m_t; + >::return_value(m_t); } ///////////////////////////////////////////////////////////////// @@ -487,7 +451,7 @@ private: return t_interval - u_interval; } - static constexpr const r_type_interval_t r_type_interval = get_r_type_interval(); + constexpr static const r_type_interval_t r_type_interval = get_r_type_interval(); constexpr static const interval return_interval{ r_type_interval.l.exception() @@ -609,7 +573,7 @@ private: return t_interval * u_interval; } - static constexpr const r_type_interval_t r_type_interval = get_r_type_interval(); + constexpr static const r_type_interval_t r_type_interval = get_r_type_interval(); constexpr static const interval return_interval{ r_type_interval.l.exception() @@ -697,7 +661,7 @@ private: // if exception possible using exception_policy = typename common_exception_policy::type; - constexpr static int bits = std::min( + constexpr static const int bits = std::min( std::numeric_limits::digits, std::max(std::initializer_list{ std::numeric_limits::digits, @@ -768,7 +732,7 @@ private: ); } - static constexpr const r_type_interval_t r_type_interval = get_r_type_interval(); + constexpr static const r_type_interval_t r_type_interval = get_r_type_interval(); constexpr static const interval return_interval{ r_type_interval.l.exception() @@ -852,7 +816,7 @@ private: // if exception possible using exception_policy = typename common_exception_policy::type; - constexpr static int bits = std::min( + constexpr static const int bits = std::min( std::numeric_limits::digits, std::max(std::initializer_list{ std::numeric_limits::digits, @@ -925,7 +889,7 @@ private: ); } - static constexpr const r_type_interval_t r_type_interval = get_r_type_interval(); + constexpr static const r_type_interval_t r_type_interval = get_r_type_interval(); constexpr static const interval return_interval{ r_type_interval.l.exception() @@ -1180,7 +1144,11 @@ constexpr operator!=(const T & lhs, const U & rhs) { return ! (lhs == rhs); } -///////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// +// The following operators only make sense when applied to integet types + +///////////////////////////////////////////////////////////////////////// // shift operators // left shift @@ -1237,7 +1205,7 @@ private: return (t_interval << u_interval); } - static constexpr const r_type_interval_t r_type_interval = get_r_type_interval(); + constexpr static const r_type_interval_t r_type_interval = get_r_type_interval(); constexpr static const interval return_interval{ r_type_interval.l.exception() @@ -1258,8 +1226,8 @@ private: return false; } - constexpr static auto rl = return_interval.l; - constexpr static auto ru = return_interval.u; + constexpr static const auto rl = return_interval.l; + constexpr static const auto ru = return_interval.u; public: using type = @@ -1295,10 +1263,12 @@ constexpr operator<<(const T & t, const U & u){ // INT13-CPP // C++ standards document N4618 & 5.8.2 static_assert( - std::numeric_limits::is_integer, "shifted value must be an integer" + boost::safe_numerics::Integer::value, + "shifted value must be an integer" ); static_assert( - std::numeric_limits::is_integer, "shift amount must be an integer" + boost::safe_numerics::Integer::value, + "bit shift count must be an integer" ); return left_shift_result::return_value(t, u); } @@ -1370,7 +1340,7 @@ struct right_shift_result { return (t_interval() >> u_interval()); } - static constexpr const r_type_interval_t r_type_interval = get_r_type_interval(); + constexpr static const r_type_interval_t r_type_interval = get_r_type_interval(); constexpr static const interval return_interval{ r_type_interval.l.exception() @@ -1431,10 +1401,12 @@ typename boost::lazy_enable_if_c< constexpr operator>>(const T & t, const U & u){ // INT13-CPP static_assert( - std::numeric_limits::is_integer, "shifted value must be an integer" + boost::safe_numerics::Integer::value, + "shifted value must be an integer" ); static_assert( - std::numeric_limits::is_integer, "shift amount must be an integer" + boost::safe_numerics::Integer::value, + "bit shift count must be an integer" ); return right_shift_result::return_value(t, u); } @@ -1466,20 +1438,6 @@ private: using r_type = typename std::make_unsigned::type; using r_type_interval_t = interval; - - #if 0 - // breaks compilation for earlier versions of clant - constexpr static const r_type_interval_t r_interval{ - r_type(0), - utility::round_out( - std::max( - static_cast(base_value(std::numeric_limits::max())), - static_cast(base_value(std::numeric_limits::max())) - ) - ) - }; - #endif - using exception_policy = typename common_exception_policy::type; public: @@ -1514,6 +1472,14 @@ typename boost::lazy_enable_if_c< bitwise_or_result >::type constexpr operator|(const T & t, const U & u){ + static_assert( + boost::safe_numerics::Integer::value, + "bitwise or arguments must be an integers" + ); + static_assert( + boost::safe_numerics::Integer::value, + "bitwise or arguments must be an integers" + ); return bitwise_or_result::return_value(t, u); } @@ -1541,19 +1507,6 @@ private: using r_type = typename std::make_unsigned::type; using r_type_interval_t = interval; - - #if 0 - // breaks compilation for earlier versions of clant - constexpr static const r_type_interval_t r_interval{ - r_type(0), - utility::round_out( - std::min( - static_cast(base_value(std::numeric_limits::max())), - static_cast(base_value(std::numeric_limits::max())) - ) - ) - }; - #endif using exception_policy = typename common_exception_policy::type; public: @@ -1588,6 +1541,14 @@ typename boost::lazy_enable_if_c< bitwise_and_result >::type constexpr operator&(const T & t, const U & u){ + static_assert( + boost::safe_numerics::Integer::value, + "bitwise and arguments must be an integers" + ); + static_assert( + boost::safe_numerics::Integer::value, + "bitwise and arguments must be an integers" + ); return bitwise_and_result::return_value(t, u); } @@ -1614,20 +1575,6 @@ struct bitwise_xor_result { using r_type = typename std::make_unsigned::type; using r_type_interval_t = interval; - - #if 0 - // breaks compilation for earlier versions of clant - constexpr static const r_type_interval_t r_interval{ - r_type(0), - utility::round_out( - std::max( - static_cast(base_value(std::numeric_limits::max())), - static_cast(base_value(std::numeric_limits::max())) - ) - ) - }; - #endif - using exception_policy = typename common_exception_policy::type; public: @@ -1662,6 +1609,14 @@ typename boost::lazy_enable_if_c< bitwise_xor_result >::type constexpr operator^(const T & t, const U & u){ + static_assert( + boost::safe_numerics::Integer::value, + "bitwise xor arguments must be an integers" + ); + static_assert( + boost::safe_numerics::Integer::value, + "bitwise xor arguments must be an integers" + ); return bitwise_xor_result::return_value(t, u); } @@ -1726,16 +1681,30 @@ void safe_base::input( m_t = validated_cast(x); } else{ + if(std::is_unsigned::value){ + // reading a negative number into an unsigned variable cannot result in + // a correct result. But, C++ reads the absolute value, multiplies + // it by -1 and stores the resulting value. This is crazy - but there + // it is! Oh, and it doesn't set the failbit. We fix this behavior here + is >> std::ws; + int x = is.peek(); + // if the input string starts with a '-', we know its an error + if(x == '-'){ + // set fail bit + is.setstate(std::ios_base::failbit); + } + } is >> m_t; - validated_cast(m_t); - } - if(is.fail()){ - boost::safe_numerics::dispatch< - E, - boost::safe_numerics::safe_numerics_error::domain_error - >( - "error in file input" - ); + if(is.fail()){ + boost::safe_numerics::dispatch< + E, + boost::safe_numerics::safe_numerics_error::domain_error + >( + "error in file input" + ); + } + else + validated_cast(m_t); } }