|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r73675 - in trunk: boost/numeric/conversion boost/numeric/conversion/detail boost/numeric/conversion/detail/preprocessed libs/numeric/conversion/doc libs/numeric/conversion/test libs/numeric/conversion/test/compile_fail
From: blkohn_at_[hidden]
Date: 2011-08-11 15:08:09
Author: brandon.kohn
Date: 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
New Revision: 73675
URL: http://svn.boost.org/trac/boost/changeset/73675
Log:
Added numeric_cast_traits to the numeric conversion library. Tested on msvc-10.0 and gcc-4.3.4/cygwin.
Added:
trunk/boost/numeric/conversion/detail/numeric_cast_traits.hpp (contents, props changed)
trunk/boost/numeric/conversion/detail/preprocessed/
trunk/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits.hpp (contents, props changed)
trunk/boost/numeric/conversion/numeric_cast_traits.hpp (contents, props changed)
trunk/libs/numeric/conversion/test/compile_fail/
trunk/libs/numeric/conversion/test/compile_fail/built_in_numeric_cast_traits.cpp (contents, props changed)
trunk/libs/numeric/conversion/test/numeric_cast_traits_test.cpp (contents, props changed)
Text files modified:
trunk/boost/numeric/conversion/cast.hpp | 32 ++-
trunk/libs/numeric/conversion/doc/numeric_cast.qbk | 45 ++++
trunk/libs/numeric/conversion/doc/requirements.qbk | 344 +++++++++++++++++++++++++++++++++++++++
trunk/libs/numeric/conversion/test/Jamfile.v2 | 15 +
4 files changed, 414 insertions(+), 22 deletions(-)
Modified: trunk/boost/numeric/conversion/cast.hpp
==============================================================================
--- trunk/boost/numeric/conversion/cast.hpp (original)
+++ trunk/boost/numeric/conversion/cast.hpp 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -16,6 +16,7 @@
// 30 Oct 2001 Some fixes suggested by Daryle Walker (Fernando Cacciola)
// 25 Oct 2001 Initial boostification (Fernando Cacciola)
// 23 Jan 2004 Inital add to cvs (post review)s
+// 22 Jun 2011 Added support for specializing cast policies via numeric_cast_traits (Brandon Kohn).
//
#ifndef BOOST_NUMERIC_CONVERSION_CAST_25OCT2001_HPP
#define BOOST_NUMERIC_CONVERSION_CAST_25OCT2001_HPP
@@ -30,22 +31,31 @@
#include <boost/type.hpp>
#include <boost/numeric/conversion/converter.hpp>
+#include <boost/numeric/conversion/numeric_cast_traits.hpp>
namespace boost
{
- template<typename Target, typename Source>
- inline
- Target numeric_cast ( Source arg )
- {
- typedef boost::numeric::converter<Target,Source> Converter ;
- return Converter::convert(arg);
- }
-
- using numeric::bad_numeric_cast;
-
+ template <typename Target, typename Source>
+ inline Target numeric_cast( Source arg )
+ {
+ typedef numeric::conversion_traits<Target, Source> conv_traits;
+ typedef numeric::numeric_cast_traits<Target, Source> cast_traits;
+ typedef boost::numeric::converter
+ <
+ Target,
+ Source,
+ conv_traits,
+ typename cast_traits::overflow_policy,
+ typename cast_traits::rounding_policy,
+ boost::numeric::raw_converter< conv_traits >,
+ typename cast_traits::range_checking_policy
+ > converter;
+ return converter::convert(arg);
+ }
+
+ using numeric::bad_numeric_cast;
} // namespace boost
#endif
-
#endif
Added: trunk/boost/numeric/conversion/detail/numeric_cast_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/numeric/conversion/detail/numeric_cast_traits.hpp 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -0,0 +1,103 @@
+//
+//! Copyright © 2011
+//! Brandon Kohn
+//
+// 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)
+//
+#if !defined(BOOST_NUMERIC_CONVERSION_DONT_USE_PREPROCESSED_FILES)
+ #include <boost/numeric/conversion/detail/preprocessed/numeric_cast_traits.hpp>
+#elif !BOOST_PP_IS_ITERATING
+
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/seq/elem.hpp>
+ #include <boost/preprocessor/seq/size.hpp>
+
+ #if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 2, line: 0, output: "preprocessed/numeric_cast_traits.hpp")
+ #endif
+
+//
+//! Copyright © 2011
+//! Brandon Kohn
+//
+// 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)
+//
+ #if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 1)
+ #endif
+
+ //! Generate the specializations for the built-in types.
+ #if !defined( BOOST_NO_INT64_T )
+ #define BOOST_NUMERIC_CONVERSION_BUILTIN_TYPES() \
+ (char) \
+ (boost::int8_t) \
+ (boost::uint8_t) \
+ (boost::int16_t) \
+ (boost::uint16_t) \
+ (boost::int32_t) \
+ (boost::uint32_t) \
+ (boost::int64_t) \
+ (boost::uint64_t) \
+ (float) \
+ (double) \
+ (long double) \
+ /***/
+ #else
+ #define BOOST_NUMERIC_CONVERSION_BUILTIN_TYPES() \
+ (char) \
+ (boost::int8_t) \
+ (boost::uint8_t) \
+ (boost::int16_t) \
+ (boost::uint16_t) \
+ (boost::int32_t) \
+ (boost::uint32_t) \
+ (float) \
+ (double) \
+ (long double) \
+ /***/
+ #endif
+
+namespace boost { namespace numeric {
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_NUMERIC_CONVERSION_BUILTIN_TYPES())), <boost/numeric/conversion/detail/numeric_cast_traits.hpp>))
+ #include BOOST_PP_ITERATE()
+
+}}//namespace boost::numeric;
+
+ #if defined(__WAVE__) && defined(BOOST_NUMERIC_CONVERSION_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(output: null)
+ #endif
+
+ #undef BOOST_NUMERIC_CONVERSION_BUILTIN_TYPES
+
+#elif BOOST_PP_ITERATION_DEPTH() == 1
+
+ #define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_NUMERIC_CONVERSION_BUILTIN_TYPES())), <boost/numeric/conversion/detail/numeric_cast_traits.hpp>))
+ #include BOOST_PP_ITERATE()
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+ //! Generate default traits for the specified source and target.
+ #define BOOST_NUMERIC_CONVERSION_A BOOST_PP_FRAME_ITERATION(1)
+ #define BOOST_NUMERIC_CONVERSION_B BOOST_PP_FRAME_ITERATION(2)
+
+ template <>
+ struct numeric_cast_traits
+ <
+ BOOST_PP_SEQ_ELEM(BOOST_NUMERIC_CONVERSION_A, BOOST_NUMERIC_CONVERSION_BUILTIN_TYPES())
+ , BOOST_PP_SEQ_ELEM(BOOST_NUMERIC_CONVERSION_B, BOOST_NUMERIC_CONVERSION_BUILTIN_TYPES())
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<BOOST_PP_SEQ_ELEM(BOOST_NUMERIC_CONVERSION_B, BOOST_NUMERIC_CONVERSION_BUILTIN_TYPES())> rounding_policy;
+ };
+
+ #undef BOOST_NUMERIC_CONVERSION_A
+ #undef BOOST_NUMERIC_CONVERSION_B
+
+#endif//! Depth 2.
Added: trunk/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits.hpp 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -0,0 +1,1751 @@
+//
+//! Copyright © 2011
+//! Brandon Kohn
+//
+// 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)
+//
+
+namespace boost { namespace numeric {
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ char
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int8_t
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint8_t
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int16_t
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint16_t
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int32_t
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint32_t
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::int64_t
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ boost::uint64_t
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ float
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ double
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , char
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<char> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , boost::int8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , boost::uint8_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint8_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , boost::int16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , boost::uint16_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint16_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , boost::int32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , boost::uint32_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint32_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , boost::int64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::int64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , boost::uint64_t
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<boost::uint64_t> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , float
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<float> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<double> rounding_policy;
+ };
+
+ template <>
+ struct numeric_cast_traits
+ <
+ long double
+ , long double
+ >
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<long double> rounding_policy;
+ };
+
+}}
Added: trunk/boost/numeric/conversion/numeric_cast_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/numeric/conversion/numeric_cast_traits.hpp 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -0,0 +1,31 @@
+//
+//! Copyright © 2011
+//! Brandon Kohn
+//
+// 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)
+//
+#ifndef BOOST_NUMERIC_CAST_TRAITS_HPP
+#define BOOST_NUMERIC_CAST_TRAITS_HPP
+
+#include <boost/numeric/conversion/converter_policies.hpp>
+
+namespace boost { namespace numeric {
+
+ template <typename Target, typename Source, typename EnableIf = void>
+ struct numeric_cast_traits
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<Source> rounding_policy;
+ };
+
+}}//namespace boost::numeric;
+
+#if !defined( BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS )
+#include <boost/cstdint.hpp>
+#include <boost/numeric/conversion/detail/numeric_cast_traits.hpp>
+#endif//!defined BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS
+
+#endif//BOOST_NUMERIC_CAST_TRAITS_HPP
Modified: trunk/libs/numeric/conversion/doc/numeric_cast.qbk
==============================================================================
--- trunk/libs/numeric/conversion/doc/numeric_cast.qbk (original)
+++ trunk/libs/numeric/conversion/doc/numeric_cast.qbk 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -34,7 +34,7 @@
aforementioned unsigned to unsigned) makes any code that may produce
positive or negative overflows exposed to portability issues.
-`numeric_cast` adheres to the rules for implicit conversions mandated by
+By default `numeric_cast` adheres to the rules for implicit conversions mandated by
the C++ Standard, such as truncating floating point types when converting
to integral types. The implementation must guarantee that for a conversion
to a type that can hold all possible values of the source type, there will
@@ -43,17 +43,28 @@
[endsect]
[section numeric_cast]
-
- template<typename Target, typename Source> inline
- typename boost::numeric::converter<Target,Source>::result_type
- numeric_cast ( Source arg )
+
+ template <typename Target, typename Source> inline
+ Target numeric_cast( Source arg )
{
- return boost::numeric::converter<Target,Source>::convert(arg);
+ typedef conversion_traits<Target, Source> conv_traits;
+ typedef numeric_cast_traits<Target, Source> cast_traits;
+ typedef converter
+ <
+ Target,
+ Source,
+ conv_traits,
+ typename cast_traits::overflow_policy,
+ typename cast_traits::rounding_policy,
+ raw_converter<conv_traits>,
+ typename cast_traits::range_checking_policy
+ > converter;
+ return converter::convert(arg);
}
`numeric_cast` returns the result of converting a value of type Source
-to a value of type Target. If out-of-range is detected, an exception is
-thrown (see
+to a value of type Target. If out-of-range is detected, an overflow policy
+is executed whose default behavior is to throw an an exception (see
[link numeric_conversion_bad_numeric_cast bad_numeric_cast],
[link numeric_conversion_negative_overflow negative_overflow] and
[link numeric_conversion_possitive_overflow positive_overflow]
@@ -61,6 +72,24 @@
[endsect]
+[section numeric_cast_traits]
+
+ template <typename Target, typename Source, typename EnableIf = void>
+ struct numeric_cast_traits
+ {
+ typedef def_overflow_handler overflow_policy;
+ typedef UseInternalRangeChecker range_checking_policy;
+ typedef Trunc<Source> rounding_policy;
+ };
+
+The behavior of `numeric_cast` may be tailored for custom numeric types through
+the specialization of `numeric_cast_traits`. (see
+[link boost_numericconversion.type_requirements_and_user_defined_types_support User Defined Types]
+for details.
+)
+
+[endsect]
+
[section Examples]
The following example performs some typical conversions between numeric types:
Modified: trunk/libs/numeric/conversion/doc/requirements.qbk
==============================================================================
--- trunk/libs/numeric/conversion/doc/requirements.qbk (original)
+++ trunk/libs/numeric/conversion/doc/requirements.qbk 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -94,17 +94,355 @@
However, this internal logic is disabled when either type is User Defined.
In this case, the user can specify an ['external] range checking policy which will be
-used in place of the internal code. See
-[link boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker UserRangeChecker] policy for details.
+used in place of the internal code. See
+[link boost_numericconversion.type_requirements_and_user_defined_types_support.udts_with_numeric_cast numeric_cast_traits]
+for details on using UDTs with `numeric_cast`.
The converter class performs the actual conversion using a Raw Converter policy.
The default raw converter simply performs a `static_cast<Target>(source)`.
However, if the a UDT is involved, the `static_cast` might not work. In this case,
the user can implement and pass a different raw converter policy.
-See [link boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter RawConverter] policy for details
+See [link boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter RawConverter] policy for details.
[endsect]
+[section UDTs with numeric_cast]
+
+In order to employ UDTs with `numeric_cast`, the user should define
+a `numeric_cast_traits` specialization on the UDT for each conversion.
+Here is an example of specializations for converting between the UDT
+and any other type:
+
+ namespace boost { namespace numeric {
+ template <typename Source>
+ struct numeric_cast_traits<UDT, Source>
+ {
+ typedef conversion_traits<UDT, Source> conv_traits;
+
+ //! The following are required:
+ typedef YourOverflowHandlerPolicy overflow_policy;
+ typedef YourRangeCheckerPolicy<conv_traits> range_checking_policy;
+ typedef YourFloat2IntRounderPolicy<Source> rounding_policy;
+ };
+ template <typename Target>
+ struct numeric_cast_traits<Target, UDT>
+ {
+ typedef conversion_traits<Target, UDT> conv_traits;
+
+ //! The following are required:
+ typedef YourOverflowHandlerPolicy overflow_policy;
+ typedef YourRangeCheckerPolicy<conv_traits> range_checking_policy;
+ typedef YourFloat2IntRounderPolicy<UDT> rounding_policy;
+ };
+ }}//namespace boost::numeric;
+
+These specializations are already defined with default values for the built-in
+numeric types. It is possible to disable the generation of specializations for
+built-in types by defining `BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS`.
+For details on defining custom policies see [link boost_numericconversion.numeric_converter_policy_classes Converter Policies].
+
+Here is a full example of how to define a custom UDT for use with `numeric_cast`:
+
+ //! Define a simple custom number
+ struct Double
+ : boost::ordered_field_operators
+ <
+ Double
+ , boost::ordered_field_operators2< Double, long double
+ , boost::ordered_field_operators2< Double, double
+ , boost::ordered_field_operators2< Double, float
+ , boost::ordered_field_operators2< Double, int
+ , boost::ordered_field_operators2< Double, unsigned int
+ , boost::ordered_field_operators2< Double, long
+ , boost::ordered_field_operators2< Double, unsigned long
+ , boost::ordered_field_operators2< Double, long long
+ , boost::ordered_field_operators2< Double, unsigned long long
+ , boost::ordered_field_operators2< Double, char
+ , boost::ordered_field_operators2< Double, unsigned char
+ , boost::ordered_field_operators2< Double, short
+ , boost::ordered_field_operators2< Double, unsigned short
+ > > > > > > > > > > > > > >
+ {
+ Double()
+ : v(0)
+ {}
+
+ template <typename T>
+ explicit Double( T v )
+ : v(static_cast<double>(v))
+ {}
+
+ template <typename T>
+ Double& operator= ( T t )
+ {
+ v = static_cast<double>(t);
+ return *this;
+ }
+
+ bool operator < ( const Double& rhs ) const
+ {
+ return v < rhs.v;
+ }
+
+ template <typename T>
+ bool operator < ( T rhs ) const
+ {
+ return v < static_cast<double>(rhs);
+ }
+
+ bool operator > ( const Double& rhs ) const
+ {
+ return v > rhs.v;
+ }
+
+ template <typename T>
+ bool operator > ( T rhs ) const
+ {
+ return v > static_cast<double>(rhs);
+ }
+
+ bool operator ==( const Double& rhs ) const
+ {
+ return v == rhs.v;
+ }
+
+ template <typename T>
+ bool operator == ( T rhs ) const
+ {
+ return v == static_cast<double>(rhs);
+ }
+
+ bool operator !() const
+ {
+ return v == 0;
+ }
+
+ Double operator -() const
+ {
+ return Double(-v);
+ }
+
+ Double& operator +=( const Double& t )
+ {
+ v += t.v;
+ return *this;
+ }
+
+ template <typename T>
+ Double& operator +=( T t )
+ {
+ v += static_cast<double>(t);
+ return *this;
+ }
+
+ Double& operator -=( const Double& t )
+ {
+ v -= t.v;
+ return *this;
+ }
+
+ template <typename T>
+ Double& operator -=( T t )
+ {
+ v -= static_cast<double>(t);
+ return *this;
+ }
+
+ Double& operator *= ( const Double& factor )
+ {
+ v *= factor.v;
+ return *this;
+ }
+
+ template <typename T>
+ Double& operator *=( T t )
+ {
+ v *= static_cast<double>(t);
+ return *this;
+ }
+
+ Double& operator /= (const Double& divisor)
+ {
+ v /= divisor.v;
+ return *this;
+ }
+
+ template <typename T>
+ Double& operator /=( T t )
+ {
+ v /= static_cast<double>(t);
+ return (*this);
+ }
+
+ double v;
+ };
+
+ //! Define numeric_limits for the custom type.
+ namespace std
+ {
+ template<>
+ class numeric_limits<Double> : public numeric_limits<double>
+ {
+ public:
+
+ //! Limit our Double to a range of +/- 100.0
+ static Double (min)()
+ {
+ return Double(1.e-2);
+ }
+
+ static Double (max)()
+ {
+ return Double(1.e2);
+ }
+
+ static Double epsilon()
+ {
+ return Double( std::numeric_limits<double>::epsilon() );
+ }
+ };
+ }
+
+ //! Define range checking and overflow policies.
+ namespace custom
+ {
+ //! Define a custom range checker
+ template<typename Traits, typename OverFlowHandler>
+ struct range_checker
+ {
+ typedef typename Traits::argument_type argument_type ;
+ typedef typename Traits::source_type S;
+ typedef typename Traits::target_type T;
+
+ //! Check range of integral types.
+ static boost::numeric::range_check_result out_of_range( argument_type s )
+ {
+ using namespace boost::numeric;
+ if( s > bounds<T>::highest() )
+ return cPosOverflow;
+ else if( s < bounds<T>::lowest() )
+ return cNegOverflow;
+ else
+ return cInRange;
+ }
+
+ static void validate_range ( argument_type s )
+ {
+ BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_bounded );
+ OverFlowHandler()( out_of_range(s) );
+ }
+ };
+
+ //! Overflow handler
+ struct positive_overflow{};
+ struct negative_overflow{};
+
+ struct overflow_handler
+ {
+ void operator() ( boost::numeric::range_check_result r )
+ {
+ using namespace boost::numeric;
+ if( r == cNegOverflow )
+ throw negative_overflow() ;
+ else if( r == cPosOverflow )
+ throw positive_overflow() ;
+ }
+ };
+
+ //! Define a rounding policy and specialize on the custom type.
+ template<class S>
+ struct Ceil : boost::numeric::Ceil<S>{};
+
+ template<>
+ struct Ceil<Double>
+ {
+ typedef Double source_type;
+
+ typedef Double const& argument_type;
+
+ static source_type nearbyint ( argument_type s )
+ {
+ #if !defined(BOOST_NO_STDC_NAMESPACE)
+ using std::ceil ;
+ #endif
+ return Double( ceil(s.v) );
+ }
+
+ typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style;
+ };
+
+ //! Define a rounding policy and specialize on the custom type.
+ template<class S>
+ struct Trunc: boost::numeric::Trunc<S>{};
+
+ template<>
+ struct Trunc<Double>
+ {
+ typedef Double source_type;
+
+ typedef Double const& argument_type;
+
+ static source_type nearbyint ( argument_type s )
+ {
+ #if !defined(BOOST_NO_STDC_NAMESPACE)
+ using std::floor;
+ #endif
+ return Double( floor(s.v) );
+ }
+
+ typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style;
+ };
+ }//namespace custom;
+
+ namespace boost { namespace numeric {
+
+ //! Define the numeric_cast_traits specializations on the custom type.
+ template <typename S>
+ struct numeric_cast_traits<Double, S>
+ {
+ typedef custom::overflow_handler overflow_policy;
+ typedef custom::range_checker
+ <
+ boost::numeric::conversion_traits<Double, S>
+ , overflow_policy
+ > range_checking_policy;
+ typedef boost::numeric::Trunc<S> rounding_policy;
+ };
+
+ template <typename T>
+ struct numeric_cast_traits<T, Double>
+ {
+ typedef custom::overflow_handler overflow_policy;
+ typedef custom::range_checker
+ <
+ boost::numeric::conversion_traits<T, Double>
+ , overflow_policy
+ > range_checking_policy;
+ typedef custom::Trunc<Double> rounding_policy;
+ };
+
+ //! Define the conversion from the custom type to built-in types and vice-versa.
+ template<typename T>
+ struct raw_converter< conversion_traits< T, Double > >
+ {
+ static T low_level_convert ( const Double& n )
+ {
+ return static_cast<T>( n.v );
+ }
+ };
+
+ template<typename S>
+ struct raw_converter< conversion_traits< Double, S > >
+ {
+ static Double low_level_convert ( const S& n )
+ {
+ return Double(n);
+ }
+ };
+ }}//namespace boost::numeric;
+
+[endsect]
+
[endsect]
Modified: trunk/libs/numeric/conversion/test/Jamfile.v2
==============================================================================
--- trunk/libs/numeric/conversion/test/Jamfile.v2 (original)
+++ trunk/libs/numeric/conversion/test/Jamfile.v2 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -5,6 +5,16 @@
# 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)
+#
+# import testing ;
+
+project numeric_conversion_unit_tests
+ :
+ requirements
+ <include>.
+ <toolset>gcc:<cxxflags>"-ftemplate-depth-300 -g0"
+ <toolset>darwin:<cxxflags>"-ftemplate-depth-300 -g0"
+ ;
test-suite numeric/conversion :
[ run bounds_test.cpp ]
@@ -13,5 +23,10 @@
[ run udt_support_test.cpp ]
[ run numeric_cast_test.cpp ]
[ run udt_example_0.cpp ]
+ [ run numeric_cast_traits_test.cpp ]
+ ;
+
+ test-suite "compile_fail_test" :
+ [ compile-fail compile_fail/built_in_numeric_cast_traits.cpp ]
;
Added: trunk/libs/numeric/conversion/test/compile_fail/built_in_numeric_cast_traits.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/numeric/conversion/test/compile_fail/built_in_numeric_cast_traits.cpp 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -0,0 +1,122 @@
+//
+//! Copyright © 2011
+//! Brandon Kohn
+//
+// 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 <boost/operators.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/comparison/less.hpp>
+#include <boost/preprocessor/comparison/not_equal.hpp>
+#include <boost/preprocessor/repetition/for.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/test/minimal.hpp>
+
+//! Generate default traits for the specified source and target.
+#define BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS(r, state) \
+template <> \
+struct numeric_cast_traits< \
+ BOOST_PP_SEQ_ELEM( BOOST_PP_TUPLE_ELEM(4,0,state) \
+ , BOOST_PP_TUPLE_ELEM(4,3,state) ) \
+ , BOOST_PP_TUPLE_ELEM(4,2,state)> \
+{ \
+ typedef def_overflow_handler overflow_policy; \
+ typedef UseInternalRangeChecker range_checking_policy; \
+ typedef Trunc<BOOST_PP_TUPLE_ELEM(4,2,state)> rounding_policy; \
+}; \
+/***/
+
+#define BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL(r, state) \
+ BOOST_PP_LESS \
+ ( \
+ BOOST_PP_TUPLE_ELEM(4,0,state) \
+ , BOOST_PP_TUPLE_ELEM(4,1,state) \
+ ) \
+/***/
+
+#define BOOST_NUMERIC_CONVERSION_INC_OP(r, state) \
+ ( \
+ BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4,0,state)) \
+ , BOOST_PP_TUPLE_ELEM(4,1,state) \
+ , BOOST_PP_TUPLE_ELEM(4,2,state) \
+ , BOOST_PP_TUPLE_ELEM(4,3,state) \
+ ) \
+/***/
+
+#define BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP(r, state) \
+ BOOST_PP_FOR \
+ ( \
+ ( \
+ 0 \
+ , BOOST_PP_TUPLE_ELEM(4,1,state) \
+ , BOOST_PP_SEQ_ELEM(BOOST_PP_TUPLE_ELEM(4,0,state),BOOST_PP_TUPLE_ELEM(4,2,state)) \
+ , BOOST_PP_TUPLE_ELEM(4,2,state) \
+ ) \
+ , BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL \
+ , BOOST_NUMERIC_CONVERSION_INC_OP \
+ , BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS \
+ ) \
+/***/
+
+#define BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS(types) \
+ BOOST_PP_FOR \
+ ( \
+ (0,BOOST_PP_SEQ_SIZE(types),types,_) \
+ , BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL \
+ , BOOST_NUMERIC_CONVERSION_INC_OP \
+ , BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP \
+ ) \
+/***/
+
+namespace boost { namespace numeric {
+#if !defined( BOOST_NO_INT64_T )
+ //! Generate the specializations for the built-in types.
+ BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS
+ (
+ (char)
+ (boost::int8_t)
+ (boost::uint8_t)
+ (boost::int16_t)
+ (boost::uint16_t)
+ (boost::int32_t)
+ (boost::uint32_t)
+ (boost::int64_t)
+ (boost::uint64_t)
+ (float)
+ (double)
+ (long double)
+ )
+#else
+ BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS
+ (
+ (char)
+ (boost::int8_t)
+ (boost::uint8_t)
+ (boost::int16_t)
+ (boost::uint16_t)
+ (boost::int32_t)
+ (boost::uint32_t)
+ (float)
+ (double)
+ (long double)
+ )
+#endif
+}}//namespace boost::numeric;
+
+int test_main( int argc, char * argv[] )
+{
+ //! This test should not compile.
+ return 1;
+}
+
+#undef BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS
+#undef BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP
+#undef BOOST_NUMERIC_CONVERSION_INC_OP
+#undef BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL
+#undef BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS
Added: trunk/libs/numeric/conversion/test/numeric_cast_traits_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/numeric/conversion/test/numeric_cast_traits_test.cpp 2011-08-11 15:08:08 EDT (Thu, 11 Aug 2011)
@@ -0,0 +1,384 @@
+//
+//! Copyright © 2011
+//! Brandon Kohn
+//
+// 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 <boost/operators.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/mpl/for_each.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/test/minimal.hpp>
+
+//! Define a simple custom number
+struct Double
+ : boost::ordered_field_operators
+ <
+ Double
+ , boost::ordered_field_operators2< Double, long double
+ , boost::ordered_field_operators2< Double, double
+ , boost::ordered_field_operators2< Double, float
+ , boost::ordered_field_operators2< Double, boost::int8_t
+ , boost::ordered_field_operators2< Double, boost::uint8_t
+ , boost::ordered_field_operators2< Double, boost::int16_t
+ , boost::ordered_field_operators2< Double, boost::uint16_t
+ , boost::ordered_field_operators2< Double, boost::int32_t
+ , boost::ordered_field_operators2< Double, boost::uint32_t
+#if !defined( BOOST_NO_INT64_T )
+ , boost::ordered_field_operators2< Double, boost::int64_t
+ , boost::ordered_field_operators2< Double, boost::uint64_t
+#endif
+ > > > > > > > > > >
+#if !defined( BOOST_NO_INT64_T )
+ > >
+#endif
+{
+ Double()
+ : v(0)
+ {}
+
+ template <typename T>
+ explicit Double( T v )
+ : v(static_cast<double>(v))
+ {}
+
+ template <typename T>
+ Double& operator= ( T t )
+ {
+ v = static_cast<double>(t);
+ return *this;
+ }
+
+ bool operator < ( const Double& rhs ) const
+ {
+ return v < rhs.v;
+ }
+
+ template <typename T>
+ bool operator < ( T rhs ) const
+ {
+ return v < static_cast<double>(rhs);
+ }
+
+ bool operator > ( const Double& rhs ) const
+ {
+ return v > rhs.v;
+ }
+
+ template <typename T>
+ bool operator > ( T rhs ) const
+ {
+ return v > static_cast<double>(rhs);
+ }
+
+ bool operator ==( const Double& rhs ) const
+ {
+ return v == rhs.v;
+ }
+
+ template <typename T>
+ bool operator == ( T rhs ) const
+ {
+ return v == static_cast<double>(rhs);
+ }
+
+ bool operator !() const
+ {
+ return v == 0;
+ }
+
+ Double operator -() const
+ {
+ return Double(-v);
+ }
+
+ Double& operator +=( const Double& t )
+ {
+ v += t.v;
+ return *this;
+ }
+
+ template <typename T>
+ Double& operator +=( T t )
+ {
+ v += static_cast<double>(t);
+ return *this;
+ }
+
+ Double& operator -=( const Double& t )
+ {
+ v -= t.v;
+ return *this;
+ }
+
+ template <typename T>
+ Double& operator -=( T t )
+ {
+ v -= static_cast<double>(t);
+ return *this;
+ }
+
+ Double& operator *= ( const Double& factor )
+ {
+ v *= factor.v;
+ return *this;
+ }
+
+ template <typename T>
+ Double& operator *=( T t )
+ {
+ v *= static_cast<double>(t);
+ return *this;
+ }
+
+ Double& operator /= (const Double& divisor)
+ {
+ v /= divisor.v;
+ return *this;
+ }
+
+ template <typename T>
+ Double& operator /=( T t )
+ {
+ v /= static_cast<double>(t);
+ return (*this);
+ }
+
+ double v;
+};
+
+//! Define numeric_limits for the custom type.
+namespace std
+{
+ template<>
+ class numeric_limits< Double > : public numeric_limits<double>
+ {
+ public:
+
+ //! Limit our Double to a range of +/- 100.0
+ static Double (min)()
+ {
+ return Double(1.e-2);
+ }
+
+ static Double (max)()
+ {
+ return Double(1.e2);
+ }
+
+ static Double epsilon()
+ {
+ return Double( std::numeric_limits<double>::epsilon() );
+ }
+ };
+}
+
+//! Define range checking and overflow policies.
+namespace custom
+{
+ //! Define a custom range checker
+ template<typename Traits, typename OverFlowHandler>
+ struct range_checker
+ {
+ typedef typename Traits::argument_type argument_type ;
+ typedef typename Traits::source_type S;
+ typedef typename Traits::target_type T;
+
+ //! Check range of integral types.
+ static boost::numeric::range_check_result out_of_range( argument_type s )
+ {
+ using namespace boost::numeric;
+ if( s > bounds<T>::highest() )
+ return cPosOverflow;
+ else if( s < bounds<T>::lowest() )
+ return cNegOverflow;
+ else
+ return cInRange;
+ }
+
+ static void validate_range ( argument_type s )
+ {
+ BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_bounded );
+ OverFlowHandler()( out_of_range(s) );
+ }
+ };
+
+ //! Overflow handler
+ struct positive_overflow{};
+ struct negative_overflow{};
+
+ struct overflow_handler
+ {
+ void operator() ( boost::numeric::range_check_result r )
+ {
+ using namespace boost::numeric;
+ if( r == cNegOverflow )
+ throw negative_overflow() ;
+ else if( r == cPosOverflow )
+ throw positive_overflow() ;
+ }
+ };
+
+ //! Define a rounding policy and specialize on the custom type.
+ template<class S>
+ struct Ceil : boost::numeric::Ceil<S>{};
+
+ template<>
+ struct Ceil<Double>
+ {
+ typedef Double source_type;
+
+ typedef Double const& argument_type;
+
+ static source_type nearbyint ( argument_type s )
+ {
+#if !defined(BOOST_NO_STDC_NAMESPACE)
+ using std::ceil ;
+#endif
+ return Double( ceil(s.v) );
+ }
+
+ typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style;
+ };
+
+ //! Define a rounding policy and specialize on the custom type.
+ template<class S>
+ struct Trunc: boost::numeric::Trunc<S>{};
+
+ template<>
+ struct Trunc<Double>
+ {
+ typedef Double source_type;
+
+ typedef Double const& argument_type;
+
+ static source_type nearbyint ( argument_type s )
+ {
+#if !defined(BOOST_NO_STDC_NAMESPACE)
+ using std::floor;
+#endif
+ return Double( floor(s.v) );
+ }
+
+ typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style;
+ };
+}//namespace custom;
+
+namespace boost { namespace numeric {
+
+ //! Define the numeric_cast_traits specializations on the custom type.
+ template <typename S>
+ struct numeric_cast_traits<Double, S>
+ {
+ typedef custom::overflow_handler overflow_policy;
+ typedef custom::range_checker
+ <
+ boost::numeric::conversion_traits<Double, S>
+ , overflow_policy
+ > range_checking_policy;
+ typedef boost::numeric::Trunc<S> rounding_policy;
+ };
+
+ template <typename T>
+ struct numeric_cast_traits<T, Double>
+ {
+ typedef custom::overflow_handler overflow_policy;
+ typedef custom::range_checker
+ <
+ boost::numeric::conversion_traits<T, Double>
+ , overflow_policy
+ > range_checking_policy;
+ typedef custom::Trunc<Double> rounding_policy;
+ };
+
+ //! Define the conversion from the custom type to built-in types and vice-versa.
+ template<typename T>
+ struct raw_converter< conversion_traits< T, Double > >
+ {
+ static T low_level_convert ( const Double& n )
+ {
+ return static_cast<T>( n.v );
+ }
+ };
+
+ template<typename S>
+ struct raw_converter< conversion_traits< Double, S > >
+ {
+ static Double low_level_convert ( const S& n )
+ {
+ return Double(n);
+ }
+ };
+}}//namespace boost::numeric;
+
+#define BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW( CastCode ) \
+ try { CastCode; BOOST_CHECK( false ); } \
+ catch( custom::positive_overflow& ){} \
+ catch(...){ BOOST_CHECK( false ); } \
+/***/
+
+#define BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW( CastCode ) \
+ try { CastCode; BOOST_CHECK( false ); } \
+ catch( custom::negative_overflow& ){} \
+ catch(...){ BOOST_CHECK( false ); } \
+/***/
+
+struct test_cast_traits
+{
+ template <typename T>
+ void operator()(T) const
+ {
+ Double d = boost::numeric_cast<Double>( static_cast<T>(50) );
+ BOOST_CHECK( d.v == 50. );
+ T v = boost::numeric_cast<T>( d );
+ BOOST_CHECK( v == 50 );
+ }
+};
+
+void test_numeric_cast_traits()
+{
+ using namespace boost;
+ using namespace boost::numeric;
+ typedef mpl::vector
+ <
+ int8_t
+ , uint8_t
+ , int16_t
+ , uint16_t
+ , int32_t
+ , uint32_t
+#if !defined( BOOST_NO_INT64_T )
+ , int64_t
+ , uint64_t
+#endif
+ , float
+ , double
+ , long double
+ > types;
+ mpl::for_each<types>( test_cast_traits() );
+
+ //! Check overflow handler.
+ Double d( 56.0 );
+ BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW( d = numeric_cast<Double>( 101 ) );
+ BOOST_CHECK( d.v == 56. );
+ BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW( d = numeric_cast<Double>( -101 ) );
+ BOOST_CHECK( d.v == 56.);
+
+ //! Check custom round policy.
+ d = 5.9;
+ int five = boost::numeric_cast<int>( d );
+ BOOST_CHECK( five == 5 );
+}
+
+int test_main( int argc, char * argv[] )
+{
+ test_numeric_cast_traits();
+ return 0;
+}
+
+#undef BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW
+#undef BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk