#ifndef BOOST_NUMERIC_NUMERIC_HPP #define BOOST_NUMERIC_NUMERIC_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif // 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 #include #include #include #include #include #include #include #include #include #include "concept/numeric.hpp" #include "boost/concept/assert.hpp" namespace boost { namespace numeric { namespace detail { template struct log; template struct log<0, BASE> : public boost::mpl::integral_c< boost::intmax_t , 0 > {}; template struct log<-1, BASE> : public boost::mpl::integral_c< boost::intmax_t , 0 > {}; template struct log : public boost::mpl::integral_c< boost::intmax_t , (1 + log::value ) > {}; template struct ulog; template struct ulog<0, BASE> : public boost::mpl::integral_c< boost::uintmax_t , 0 > {}; template struct ulog : public boost::mpl::integral_c< boost::uintmax_t , (1 + ulog::value) > {}; } //detail // can't use is_signed type traits as these are defined ONLY for C++ // primitive types. They are are not (by design) implemented in terms // of numeric_limits so they aren't helpful to us. We leave then in the // boost/numeric namespace to distinguish them form the "official" type // traits ! template struct is_signed : public boost::mpl::integral_c< bool, std::numeric_limits::is_signed > { BOOST_CONCEPT_ASSERT((Numeric)); }; template struct is_unsigned : public boost::mpl::integral_c< bool, ! std::numeric_limits::is_signed > { BOOST_CONCEPT_ASSERT((Numeric)); }; // return the number of bits in a type excluding any sign template struct digits : public boost::mpl::integral_c::digits> { BOOST_CONCEPT_ASSERT((Numeric)); }; // return maximum bits in types T and U template struct max_digits : public boost::mpl::max< digits, digits >::type {}; // return the number of bits in a type including the sign template struct bits : public boost::mpl::plus< typename boost::mpl::integral_c::digits>, typename boost::mpl::integral_c::is_signed> > {}; // return maximum bits in types T and U template struct max_bits : public boost::mpl::max< bits, bits >::type {}; // return # of bit in the result of an addition of two types template struct addition_result_bits : public boost::mpl::plus< max_digits, // if either is signed typename boost::mpl::eval_if< typename boost::mpl::or_< is_signed, is_signed >, // add one guard bit and one sign bit boost::mpl::integral_c, // add one guard bit to detect overflow boost::mpl::integral_c >::type > {}; // return smallest type that can hold the sum of types T and U template struct addition_result_type { typedef typename boost::mpl::if_< typename boost::mpl::or_< is_signed, is_signed >, typename boost::int_t< boost::mpl::min< bits, addition_result_bits >::type::value >::least, typename boost::uint_t< boost::mpl::min< bits, addition_result_bits >::type::value >::least >::type type; }; // return # of bit in the result of an subtraction of two types template struct subtraction_result_bits : public boost::mpl::plus< max_digits, // add one guard bit and one sign bit boost::mpl::integral_c > {}; // return smallest type that can hold the difference of types T and U template struct subtraction_result_type { typedef typename boost::int_t< boost::mpl::min< bits, subtraction_result_bits >::type::value >::least type; }; // return # of bits in the result of an product of two types template struct multiply_result_bits : public boost::mpl::plus< digits, digits, // if either is signed typename boost::mpl::eval_if< typename boost::mpl::or_< is_signed, is_signed >, // add one sign bit boost::mpl::integral_c, boost::mpl::integral_c >::type > {}; // return smallest type that can hold the product of types T and U template struct multiply_result_type { typedef typename boost::mpl::eval_if< typename boost::mpl::or_< is_signed, is_signed >, typename boost::mpl::identity< typename boost::int_t< boost::mpl::min< bits, multiply_result_bits >::type::value >::least >, typename boost::mpl::identity< typename boost::uint_t< boost::mpl::min< bits, multiply_result_bits >::type::value >::least > >::type type; }; // return # of bits in the result of an quotient of two types template struct division_result_bits : public boost::mpl::plus< digits, // if either is signed typename boost::mpl::eval_if< typename boost::mpl::or_< is_signed, is_signed >, // add one sign bit boost::mpl::integral_c, boost::mpl::integral_c >::type > {}; // return smallest type that can hold the quotient of types T and U template struct division_result_type { typedef typename boost::mpl::if_< typename boost::mpl::or_< is_signed, is_signed >, typename boost::int_t< boost::mpl::min< bits, division_result_bits >::type::value >::least, typename boost::uint_t< boost::mpl::min< bits, division_result_bits >::type::value >::least >::type type; }; // return the type which results from usage of one the // operators &, |, ^, <<, >> template struct logical_result_type { typedef typename boost::mpl::if_< typename boost::mpl::or_< is_signed, is_signed >, typename boost::int_t< max_bits::value >::least, typename boost::uint_t< max_bits::value >::least >::type type; }; } // numeric } // boost #endif // BOOST_NUMERIC_NUMERIC_HPP