From 37d08acea167734a19332961e8987a223b06ca5c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 22 Jan 2001 04:08:29 +0000 Subject: [PATCH] Initial checkin [SVN r8702] --- include/boost/detail/numeric_traits.hpp | 164 ++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 include/boost/detail/numeric_traits.hpp diff --git a/include/boost/detail/numeric_traits.hpp b/include/boost/detail/numeric_traits.hpp new file mode 100644 index 0000000..0a96f06 --- /dev/null +++ b/include/boost/detail/numeric_traits.hpp @@ -0,0 +1,164 @@ +// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +// Template class is_signed and its documentation is: +// (C) Copyright Howard Hinnant 2001. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +// Template class numeric_traits -- +// +// Supplies: +// +// typedef difference_type -- a type used to represent the difference +// between any two values of Number. +// +// Support: +// 1. Not all specializations are supplied +// +// 2. Use of specializations that are not supplied will cause a +// compile-time error +// +// 3. Users are free to specialize numeric_traits for any type. +// +// 4. Right now, specializations are only supplied for integer types. +// +// 5. On implementations which do not supply compile-time constants in +// std::numeric_limits<>, only specializations for built-in integer types +// are supplied. +// +// 6. Handling of numbers whose range of representation is at least as +// great as boost::intmax_t can cause some differences to be +// unrepresentable in difference_type: +// +// Number difference_type +// ------ --------------- +// signed Number +// unsigned intmax_t +// +// template typename numeric_traits::difference_type +// numeric_distance(Number x, Number y) +// computes (y - x), attempting to avoid overflows. +// + +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 21 Jan 2001 - Created + +#ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901 +# define BOOST_NUMERIC_TRAITS_HPP_DWA20001901 + +# include +# include +# include +# include +# ifndef BOOST_NO_LIMITS +# include +# endif + +namespace boost { namespace detail { + + // Template class if_true -- select among 2 types based on a bool constant expression + // Usage: + // typename if_true<(bool_const_expression)>::template then::type + template struct if_true; + + template <> + struct if_true + { + template + struct then { typedef T1 type; }; + }; + + template <> + struct if_true + { + template + struct then { typedef T2 type; }; + }; + + // Template class is_signed -- determine whether a numeric type is signed + // Requires that T is constructable from the literals -1 and 0. Compile-time + // error results if that requirement is not met (and thus signedness is not + // likely to have meaning for that type). + template + struct is_signed + { + enum { value = (Number(-1) < Number(0)) }; + }; + + // Template class integer_traits -- traits of various integer types + // This should probably be rolled into boost::integer_traits one day, but I +// need it to work without + template + struct integer_traits + { +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + private: + typedef Integer integer_type; + typedef std::numeric_limits x; +# ifdef BOOST_MSVC + enum { is_integer = x::is_integer }; +# endif + public: +# ifndef BOOST_MSVC // for some reason, this asserts when it shouldn't + BOOST_STATIC_ASSERT(x::is_integer); +# else + BOOST_STATIC_ASSERT(is_integer); +# endif + typedef typename + if_true= std::numeric_limits::digits)>::template then< + Integer, + + typename if_true<(x::digits < std::numeric_limits::digits)>::template then< + signed int, + + typename if_true<(x::digits < std::numeric_limits::digits)>::template then< + signed long, + + // else + intmax_t + >::type>::type>::type difference_type; +# else + BOOST_STATIC_ASSERT(boost::is_integral::value); + + typedef typename + if_true<(sizeof(Integer) >= sizeof(intmax_t))>::template then< + + typename if_true::value>::template then< + Integer, + intmax_t + >::type, + + typename if_true<(sizeof(Integer) < sizeof(std::ptrdiff_t))>::template then< + std::ptrdiff_t, + intmax_t + >::type + >::type difference_type; +# endif + }; + + // Right now, only supports integers, but should be expanded. + template + struct numeric_traits + { + typedef typename integer_traits::difference_type difference_type; + }; + + template + typename numeric_traits::difference_type numeric_distance(Number x, Number y) + { + typedef typename numeric_traits::difference_type difference_type; + return difference_type(y) - difference_type(x); + } +}} + +#endif // BOOST_NUMERIC_TRAITS_HPP_DWA20001901