mirror of
https://github.com/boostorg/detail.git
synced 2025-12-21 14:32:53 +01:00
1. Ported to Boost.TypeTraits primitives for type inspection and simple metaprogramming instead of local implementations. This effectively drops any workarounds for compilers without support for partial template specializations. Such compilers are long outdated. 2. Include more fine-grained headers from Boost.TypeTraits to optimize compilation times. 3. Made numeric_distance function constexpr. 4. Updated the test accordingly (i.e. replaced the use of now removed local components with Boost.TypeTraits). Also replaced lexical_cast with standard streams to further reduce dependencies. None of these changes should affect functionality.
161 lines
5.3 KiB
C++
161 lines
5.3 KiB
C++
// (C) Copyright David Abrahams 2001, Howard Hinnant 2001.
|
|
//
|
|
// 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)
|
|
//
|
|
// Template class numeric_traits<Number> --
|
|
//
|
|
// 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 <class Number> typename numeric_traits<Number>::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
|
|
// 11 Feb 2001 - Use BOOST_STATIC_CONSTANT (David Abrahams)
|
|
// 11 Feb 2001 - Rolled back ineffective Borland-specific code
|
|
// (David Abrahams)
|
|
// 10 Feb 2001 - Rolled in supposed Borland fixes from John Maddock, but
|
|
// not seeing any improvement yet (David Abrahams)
|
|
// 06 Feb 2001 - Factored if_true out into boost/detail/select_type.hpp
|
|
// (David Abrahams)
|
|
// 23 Jan 2001 - Fixed logic of difference_type selection, which was
|
|
// completely wack. In the process, added digit_traits<>
|
|
// to compute the number of digits in intmax_t even when
|
|
// not supplied by numeric_limits<>. (David Abrahams)
|
|
// 21 Jan 2001 - Created (David Abrahams)
|
|
|
|
#ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901
|
|
#define BOOST_NUMERIC_TRAITS_HPP_DWA20001901
|
|
|
|
#include <cstddef>
|
|
#include <boost/config.hpp>
|
|
#include <boost/limits.hpp>
|
|
#include <boost/cstdint.hpp>
|
|
#include <boost/type_traits/is_signed.hpp>
|
|
#include <boost/type_traits/conditional.hpp>
|
|
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
|
#include <boost/static_assert.hpp>
|
|
#include <boost/type_traits/is_integral.hpp>
|
|
#endif
|
|
|
|
namespace boost { namespace detail {
|
|
|
|
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
|
// digit_traits - compute the number of digits in a built-in integer
|
|
// type. Needed for implementations on which numeric_limits is not specialized
|
|
// for some integer types, like __int128 in libstdc++ (gcc).
|
|
template <class T, bool IsSpecialized = std::numeric_limits<T>::is_specialized>
|
|
struct digit_traits
|
|
{
|
|
BOOST_STATIC_CONSTANT(int, digits = std::numeric_limits<T>::digits);
|
|
};
|
|
|
|
// numeric_limits is not specialized; compute digits from sizeof(T)
|
|
template <class T>
|
|
struct digit_traits<T, false>
|
|
{
|
|
BOOST_STATIC_CONSTANT(int, digits = (
|
|
sizeof(T) * std::numeric_limits<unsigned char>::digits
|
|
- (boost::is_signed<T>::value ? 1 : 0))
|
|
);
|
|
};
|
|
#endif
|
|
|
|
// Template class integer_traits<Integer> -- traits of various integer types
|
|
// This should probably be rolled into boost::integer_traits one day, but I
|
|
// need it to work without <limits>
|
|
template <class Integer>
|
|
struct integer_traits
|
|
{
|
|
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
|
private:
|
|
typedef Integer integer_type;
|
|
typedef std::numeric_limits<integer_type> x;
|
|
public:
|
|
typedef typename boost::conditional<
|
|
(int(x::is_signed)
|
|
&& (!int(x::is_bounded)
|
|
// digits is the number of no-sign bits
|
|
|| (int(x::digits) + 1 >= digit_traits<boost::intmax_t>::digits))),
|
|
Integer,
|
|
|
|
typename boost::conditional<
|
|
(int(x::digits) + 1 < digit_traits<signed int>::digits),
|
|
signed int,
|
|
|
|
typename boost::conditional<
|
|
(int(x::digits) + 1 < digit_traits<signed long>::digits),
|
|
signed long,
|
|
boost::intmax_t
|
|
>::type
|
|
>::type
|
|
>::type difference_type;
|
|
#else
|
|
BOOST_STATIC_ASSERT(boost::is_integral<Integer>::value);
|
|
|
|
typedef typename boost::conditional<
|
|
(sizeof(Integer) >= sizeof(intmax_t)),
|
|
|
|
boost::conditional<
|
|
(boost::is_signed<Integer>::value),
|
|
Integer,
|
|
boost::intmax_t
|
|
>,
|
|
|
|
boost::conditional<
|
|
(sizeof(Integer) < sizeof(std::ptrdiff_t)),
|
|
std::ptrdiff_t,
|
|
boost::intmax_t
|
|
>
|
|
>::type::type difference_type;
|
|
#endif
|
|
};
|
|
|
|
// Right now, only supports integers, but should be expanded.
|
|
template <class Number>
|
|
struct numeric_traits
|
|
{
|
|
typedef typename integer_traits<Number>::difference_type difference_type;
|
|
};
|
|
|
|
template <class Number>
|
|
inline BOOST_CONSTEXPR typename numeric_traits<Number>::difference_type numeric_distance(Number x, Number y)
|
|
{
|
|
typedef typename numeric_traits<Number>::difference_type difference_type;
|
|
return difference_type(y) - difference_type(x);
|
|
}
|
|
}}
|
|
|
|
#endif // BOOST_NUMERIC_TRAITS_HPP_DWA20001901
|