]> git.donarmstrong.com Git - rsem.git/blobdiff - boost/numeric/conversion/converter_policies.hpp
Updated boost to v1.55.0
[rsem.git] / boost / numeric / conversion / converter_policies.hpp
diff --git a/boost/numeric/conversion/converter_policies.hpp b/boost/numeric/conversion/converter_policies.hpp
new file mode 100644 (file)
index 0000000..e7a5e67
--- /dev/null
@@ -0,0 +1,194 @@
+//  (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
+//  Use, modification, and distribution is subject to 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)
+
+//  See library home page at http://www.boost.org/libs/numeric/conversion
+//
+// Contact the author at: fernando_cacciola@hotmail.com
+//
+#ifndef BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
+#define BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
+
+#include <typeinfo> // for std::bad_cast
+
+#include <boost/config/no_tr1/cmath.hpp> // for std::floor and std::ceil
+#include <boost/throw_exception.hpp>
+
+#include <functional>
+
+#include "boost/type_traits/is_arithmetic.hpp"
+
+#include "boost/mpl/if.hpp"
+#include "boost/mpl/integral_c.hpp"
+
+namespace boost { namespace numeric
+{
+
+template<class S>
+struct Trunc
+{
+  typedef S source_type ;
+
+  typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
+
+  static source_type nearbyint ( argument_type s )
+  {
+#if !defined(BOOST_NO_STDC_NAMESPACE)
+    using std::floor ;
+    using std::ceil  ;
+#endif
+
+    return s < static_cast<S>(0) ? ceil(s) : floor(s) ;
+  }
+
+  typedef mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style ;
+} ;
+
+
+
+template<class S>
+struct Floor
+{
+  typedef S source_type ;
+
+  typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
+
+  static source_type nearbyint ( argument_type s )
+  {
+#if !defined(BOOST_NO_STDC_NAMESPACE)
+    using std::floor ;
+#endif
+
+    return floor(s) ;
+  }
+
+  typedef mpl::integral_c< std::float_round_style, std::round_toward_neg_infinity> round_style ;
+} ;
+
+template<class S>
+struct Ceil
+{
+  typedef S source_type ;
+
+  typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
+
+  static source_type nearbyint ( argument_type s )
+  {
+#if !defined(BOOST_NO_STDC_NAMESPACE)
+    using std::ceil ;
+#endif
+
+    return ceil(s) ;
+  }
+
+  typedef mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style ;
+} ;
+
+template<class S>
+struct RoundEven
+{
+  typedef S source_type ;
+
+  typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
+
+  static source_type nearbyint ( argument_type s )
+  {
+    // Algorithm contributed by Guillaume Melquiond
+
+#if !defined(BOOST_NO_STDC_NAMESPACE)
+    using std::floor ;
+    using std::ceil  ;
+#endif
+
+    // only works inside the range not at the boundaries
+    S prev = floor(s);
+    S next = ceil(s);
+
+    S rt = (s - prev) - (next - s); // remainder type
+
+    S const zero(0.0);
+    S const two(2.0);
+
+    if ( rt < zero )
+      return prev;
+    else if ( rt > zero )
+      return next;
+    else
+    {
+      bool is_prev_even = two * floor(prev / two) == prev ;
+      return ( is_prev_even ? prev : next ) ;
+    }
+  }
+
+  typedef mpl::integral_c< std::float_round_style, std::round_to_nearest> round_style ;
+} ;
+
+
+enum range_check_result
+{
+  cInRange     = 0 ,
+  cNegOverflow = 1 ,
+  cPosOverflow = 2
+} ;
+
+class bad_numeric_cast : public std::bad_cast
+{
+  public:
+
+    virtual const char * what() const throw()
+      {  return "bad numeric conversion: overflow"; }
+};
+
+class negative_overflow : public bad_numeric_cast
+{
+  public:
+
+    virtual const char * what() const throw()
+      {  return "bad numeric conversion: negative overflow"; }
+};
+class positive_overflow : public bad_numeric_cast
+{
+  public:
+
+    virtual const char * what() const throw()
+      { return "bad numeric conversion: positive overflow"; }
+};
+
+struct def_overflow_handler
+{
+  void operator() ( range_check_result r ) // throw(negative_overflow,positive_overflow)
+  {
+#ifndef BOOST_NO_EXCEPTIONS
+    if ( r == cNegOverflow )
+      throw negative_overflow() ;
+    else if ( r == cPosOverflow )
+           throw positive_overflow() ;
+#else
+    if ( r == cNegOverflow )
+      ::boost::throw_exception(negative_overflow()) ;
+    else if ( r == cPosOverflow )
+           ::boost::throw_exception(positive_overflow()) ;
+#endif
+  }
+} ;
+
+struct silent_overflow_handler
+{
+  void operator() ( range_check_result ) {} // throw()
+} ;
+
+template<class Traits>
+struct raw_converter
+{
+  typedef typename Traits::result_type   result_type   ;
+  typedef typename Traits::argument_type argument_type ;
+
+  static result_type low_level_convert ( argument_type s ) { return static_cast<result_type>(s) ; }
+} ;
+
+struct UseInternalRangeChecker {} ;
+
+} } // namespace boost::numeric
+
+#endif