]> git.lyx.org Git - lyx.git/blob - boost/boost/numeric/conversion/converter_policies.hpp
Don't allow newline characters in document settings.
[lyx.git] / boost / boost / numeric / conversion / converter_policies.hpp
1 //  (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
2 //  Use, modification, and distribution is subject to the Boost Software
3 //  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5
6 //  See library home page at http://www.boost.org/libs/numeric/conversion
7 //
8 // Contact the author at: fernando_cacciola@hotmail.com
9 //
10 #ifndef BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
11 #define BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
12
13 #include <typeinfo> // for std::bad_cast
14
15 #include <boost/config/no_tr1/cmath.hpp> // for std::floor and std::ceil
16
17 #include <functional>
18
19 #include "boost/type_traits/is_arithmetic.hpp"
20
21 #include "boost/mpl/if.hpp"
22 #include "boost/mpl/integral_c.hpp"
23
24 namespace boost { namespace numeric
25 {
26
27 template<class S>
28 struct Trunc
29 {
30   typedef S source_type ;
31
32   typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
33
34   static source_type nearbyint ( argument_type s )
35   {
36 #if !defined(BOOST_NO_STDC_NAMESPACE)
37     using std::floor ;
38     using std::ceil  ;
39 #endif
40
41     return s < static_cast<S>(0) ? ceil(s) : floor(s) ;
42   }
43
44   typedef mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style ;
45 } ;
46
47
48
49 template<class S>
50 struct Floor
51 {
52   typedef S source_type ;
53
54   typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
55
56   static source_type nearbyint ( argument_type s )
57   {
58 #if !defined(BOOST_NO_STDC_NAMESPACE)
59     using std::floor ;
60 #endif
61
62     return floor(s) ;
63   }
64
65   typedef mpl::integral_c< std::float_round_style, std::round_toward_neg_infinity> round_style ;
66 } ;
67
68 template<class S>
69 struct Ceil
70 {
71   typedef S source_type ;
72
73   typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
74
75   static source_type nearbyint ( argument_type s )
76   {
77 #if !defined(BOOST_NO_STDC_NAMESPACE)
78     using std::ceil ;
79 #endif
80
81     return ceil(s) ;
82   }
83
84   typedef mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style ;
85 } ;
86
87 template<class S>
88 struct RoundEven
89 {
90   typedef S source_type ;
91
92   typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
93
94   static source_type nearbyint ( argument_type s )
95   {
96     // Algorithm contributed by Guillaume Melquiond
97
98 #if !defined(BOOST_NO_STDC_NAMESPACE)
99     using std::floor ;
100     using std::ceil  ;
101 #endif
102
103     // only works inside the range not at the boundaries
104     S prev = floor(s);
105     S next = ceil(s);
106
107     S rt = (s - prev) - (next - s); // remainder type
108
109     S const zero(0.0);
110     S const two(2.0);
111
112     if ( rt < zero )
113       return prev;
114     else if ( rt > zero )
115       return next;
116     else
117     {
118       bool is_prev_even = two * floor(prev / two) == prev ;
119       return ( is_prev_even ? prev : next ) ;
120     }
121   }
122
123   typedef mpl::integral_c< std::float_round_style, std::round_to_nearest> round_style ;
124 } ;
125
126
127 enum range_check_result
128 {
129   cInRange     = 0 ,
130   cNegOverflow = 1 ,
131   cPosOverflow = 2
132 } ;
133
134 class bad_numeric_cast : public std::bad_cast
135 {
136   public:
137
138     virtual const char * what() const throw()
139       {  return "bad numeric conversion: overflow"; }
140 };
141
142 class negative_overflow : public bad_numeric_cast
143 {
144   public:
145
146     virtual const char * what() const throw()
147       {  return "bad numeric conversion: negative overflow"; }
148 };
149 class positive_overflow : public bad_numeric_cast
150 {
151   public:
152
153     virtual const char * what() const throw()
154       { return "bad numeric conversion: positive overflow"; }
155 };
156
157 struct def_overflow_handler
158 {
159   void operator() ( range_check_result r ) // throw(negative_overflow,positive_overflow)
160   {
161     if ( r == cNegOverflow )
162       throw negative_overflow() ;
163     else if ( r == cPosOverflow )
164            throw positive_overflow() ;
165   }
166 } ;
167
168 struct silent_overflow_handler
169 {
170   void operator() ( range_check_result ) {} // throw()
171 } ;
172
173 template<class Traits>
174 struct raw_converter
175 {
176   typedef typename Traits::result_type   result_type   ;
177   typedef typename Traits::argument_type argument_type ;
178
179   static result_type low_level_convert ( argument_type s ) { return static_cast<result_type>(s) ; }
180 } ;
181
182 struct UseInternalRangeChecker {} ;
183
184 } } // namespace boost::numeric
185
186 #endif