123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- #ifndef BOOST_NUMERIC_UTILITY_HPP
- #define BOOST_NUMERIC_UTILITY_HPP
- #include <cstdint> // intmax_t, uintmax_t, uint8_t, ...
- #include <algorithm>
- #include <type_traits> // conditional
- #include <limits>
- #include <cassert>
- #include <utility> // pair
- #include <boost/integer.hpp> // (u)int_t<>::least, exact
- namespace boost {
- namespace safe_numerics {
- namespace utility {
- template <typename... Ts>
- struct [[deprecated]] print_types {};
- template<int N>
- struct print_value {
- enum test : char {
- value = N < 0 ? N - 256 : N + 256
- };
- };
- template <typename T>
- struct static_test{};
- template <>
- struct static_test<std::false_type>{
- [[deprecated]] static_test(){}
- };
- template<typename T>
- using static_warning = static_test<T>;
- template<typename T>
- using bits_type = std::integral_constant<
- int,
- std::numeric_limits<T>::digits
- + (std::numeric_limits<T>::is_signed ? 1 : 0)
- >;
- namespace ilog2_detail {
- template<int N>
- constexpr inline unsigned int ilog2(const typename boost::uint_t<N>::exact & t){
- using half_type = typename boost::uint_t<N/2>::exact;
- const half_type upper_half = static_cast<half_type>(t >> N/2);
- const half_type lower_half = static_cast<half_type>(t);
- return upper_half == 0 ? ilog2<N/2>(lower_half) : N/2 + ilog2<N/2>(upper_half);
- }
- template<>
- constexpr inline unsigned int ilog2<8>(const typename boost::uint_t<8>::exact & t){
- #define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
- const char LogTable256[256] = {
- static_cast<char>(-1), 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
- LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
- LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
- };
- return LogTable256[t];
- }
- }
- template<typename T>
- constexpr inline unsigned int ilog2(const T & t){
- if(t == 0)
- return 0;
- return ilog2_detail::ilog2<bits_type<T>::value>(
- static_cast<
- typename boost::uint_t<
- bits_type<T>::value
- >::least
- >(t)
- );
- }
- template<typename T>
- constexpr inline unsigned int significant_bits(const T & t){
- return 1 + ((t < 0) ? ilog2(~t) : ilog2(t));
- }
- template <class T>
- constexpr inline T max(
- const T & lhs,
- const T & rhs
- ){
- return lhs > rhs ? lhs : rhs;
- }
- template<
- std::intmax_t Min,
- std::intmax_t Max
- >
- using signed_stored_type = typename boost::int_t<
- max(
- significant_bits(Min),
- significant_bits(Max)
- ) + 1
- >::least ;
- template<
- std::uintmax_t Min,
- std::uintmax_t Max
- >
- using unsigned_stored_type = typename boost::uint_t<
- significant_bits(Max)
- >::least;
- template<typename T>
- constexpr inline std::pair<T, T>
- minmax(const std::initializer_list<T> & l){
- assert(l.size() > 0);
- const T * minimum = l.begin();
- const T * maximum = l.begin();
- for(const T * i = l.begin(); i != l.end(); ++i){
- if(*i < * minimum)
- minimum = i;
- else
- if(* maximum < *i)
- maximum = i;
- }
- return std::pair<T, T>{* minimum, * maximum};
- }
- template<typename T>
- constexpr inline T round_out(const T & t){
- if(t >= 0){
- const std::uint8_t sb = utility::significant_bits(t);
- return (sb < sizeof(T) * 8)
- ? ((T)1 << sb) - 1
- : std::numeric_limits<T>::max();
- }
- else{
- const std::uint8_t sb = utility::significant_bits(~t);
- return (sb < sizeof(T) * 8)
- ? ~(((T)1 << sb) - 1)
- : std::numeric_limits<T>::min();
- }
- }
- }
- }
- }
- #endif
|