![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /usr/include/boost/safe_numerics/ |
Upload File : |
#ifndef BOOST_NUMERIC_SAFE_COMPARE_HPP #define BOOST_NUMERIC_SAFE_COMPARE_HPP // Copyright (c) 2012 Robert Ramey // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <type_traits> #include <limits> namespace boost { namespace safe_numerics { namespace safe_compare { //////////////////////////////////////////////////// // safe comparison on primitive integral types namespace safe_compare_detail { template<typename T> using make_unsigned = typename std::conditional< std::is_signed<T>::value, std::make_unsigned<T>, T >::type; // both arguments unsigned or signed template<bool TS, bool US> struct less_than { template<class T, class U> constexpr static bool invoke(const T & t, const U & u){ return t < u; } }; // T unsigned, U signed template<> struct less_than<false, true> { template<class T, class U> constexpr static bool invoke(const T & t, const U & u){ return (u < 0) ? false : less_than<false, false>::invoke( t, static_cast<const typename make_unsigned<U>::type &>(u) ) ; } }; // T signed, U unsigned template<> struct less_than<true, false> { template<class T, class U> constexpr static bool invoke(const T & t, const U & u){ return (t < 0) ? true : less_than<false, false>::invoke( static_cast<const typename make_unsigned<T>::type &>(t), u ) ; } }; } // safe_compare_detail template<class T, class U> typename std::enable_if< std::is_integral<T>::value && std::is_integral<U>::value, bool >::type constexpr less_than(const T & lhs, const U & rhs) { return safe_compare_detail::less_than< std::is_signed<T>::value, std::is_signed<U>::value >::template invoke(lhs, rhs); } template<class T, class U> typename std::enable_if< std::is_floating_point<T>::value && std::is_floating_point<U>::value, bool >::type constexpr less_than(const T & lhs, const U & rhs) { return lhs < rhs; } template<class T, class U> constexpr bool greater_than(const T & lhs, const U & rhs) { return less_than(rhs, lhs); } template<class T, class U> constexpr bool less_than_equal(const T & lhs, const U & rhs) { return ! greater_than(lhs, rhs); } template<class T, class U> constexpr bool greater_than_equal(const T & lhs, const U & rhs) { return ! less_than(lhs, rhs); } namespace safe_compare_detail { // both arguments unsigned or signed template<bool TS, bool US> struct equal { template<class T, class U> constexpr static bool invoke(const T & t, const U & u){ return t == u; } }; // T unsigned, U signed template<> struct equal<false, true> { template<class T, class U> constexpr static bool invoke(const T & t, const U & u){ return (u < 0) ? false : equal<false, false>::invoke( t, static_cast<const typename make_unsigned<U>::type &>(u) ) ; } }; // T signed, U unsigned template<> struct equal<true, false> { template<class T, class U> constexpr static bool invoke(const T & t, const U & u){ return (t < 0) ? false : equal<false, false>::invoke( static_cast<const typename make_unsigned<T>::type &>(t), u ) ; } }; } // safe_compare_detail template<class T, class U> typename std::enable_if< std::is_integral<T>::value && std::is_integral<U>::value, bool >::type constexpr equal(const T & lhs, const U & rhs) { return safe_compare_detail::equal< std::numeric_limits<T>::is_signed, std::numeric_limits<U>::is_signed >::template invoke(lhs, rhs); } template<class T, class U> typename std::enable_if< std::is_floating_point<T>::value && std::is_floating_point<U>::value, bool >::type constexpr equal(const T & lhs, const U & rhs) { return lhs == rhs; } template<class T, class U> constexpr bool not_equal(const T & lhs, const U & rhs) { return ! equal(lhs, rhs); } } // safe_compare } // safe_numerics } // boost #endif // BOOST_NUMERIC_SAFE_COMPARE_HPP