Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/karma/numeric/real_policies.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Copyright (c) 2001-2011 Hartmut Kaiser | |
2 // | |
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | |
6 #if !defined(BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM) | |
7 #define BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM | |
8 | |
9 #if defined(_MSC_VER) | |
10 #pragma once | |
11 #endif | |
12 | |
13 #include <boost/config/no_tr1/cmath.hpp> | |
14 #include <boost/math/special_functions/fpclassify.hpp> | |
15 #include <boost/type_traits/remove_const.hpp> | |
16 | |
17 #include <boost/spirit/home/support/char_class.hpp> | |
18 #include <boost/spirit/home/karma/generator.hpp> | |
19 #include <boost/spirit/home/karma/char.hpp> | |
20 #include <boost/spirit/home/karma/numeric/int.hpp> | |
21 #include <boost/spirit/home/karma/numeric/detail/real_utils.hpp> | |
22 | |
23 #include <boost/mpl/bool.hpp> | |
24 | |
25 namespace boost { namespace spirit { namespace karma | |
26 { | |
27 /////////////////////////////////////////////////////////////////////////// | |
28 // | |
29 // real_policies, if you need special handling of your floating | |
30 // point numbers, just overload this policy class and use it as a template | |
31 // parameter to the karma::real_generator floating point specifier: | |
32 // | |
33 // template <typename T> | |
34 // struct scientific_policy : karma::real_policies<T> | |
35 // { | |
36 // // we want the numbers always to be in scientific format | |
37 // static int floatfield(T n) { return fmtflags::scientific; } | |
38 // }; | |
39 // | |
40 // typedef | |
41 // karma::real_generator<double, scientific_policy<double> > | |
42 // science_type; | |
43 // | |
44 // karma::generate(sink, science_type(), 1.0); // will output: 1.0e00 | |
45 // | |
46 /////////////////////////////////////////////////////////////////////////// | |
47 template <typename T> | |
48 struct real_policies | |
49 { | |
50 /////////////////////////////////////////////////////////////////////// | |
51 // Expose the data type the generator is targeted at | |
52 /////////////////////////////////////////////////////////////////////// | |
53 typedef T value_type; | |
54 | |
55 /////////////////////////////////////////////////////////////////////// | |
56 // By default the policy doesn't require any special iterator | |
57 // functionality. The floating point generator exposes its properties | |
58 // from here, so this needs to be updated in case other properties | |
59 // need to be implemented. | |
60 /////////////////////////////////////////////////////////////////////// | |
61 typedef mpl::int_<generator_properties::no_properties> properties; | |
62 | |
63 /////////////////////////////////////////////////////////////////////// | |
64 // Specifies, which representation type to use during output | |
65 // generation. | |
66 /////////////////////////////////////////////////////////////////////// | |
67 struct fmtflags | |
68 { | |
69 enum { | |
70 scientific = 0, // Generate floating-point values in scientific | |
71 // format (with an exponent field). | |
72 fixed = 1 // Generate floating-point values in fixed-point | |
73 // format (with no exponent field). | |
74 }; | |
75 }; | |
76 | |
77 /////////////////////////////////////////////////////////////////////// | |
78 // This is the main function used to generate the output for a | |
79 // floating point number. It is called by the real generator in order | |
80 // to perform the conversion. In theory all of the work can be | |
81 // implemented here, but it is the easiest to use existing | |
82 // functionality provided by the type specified by the template | |
83 // parameter `Inserter`. | |
84 // | |
85 // sink: the output iterator to use for generation | |
86 // n: the floating point number to convert | |
87 // p: the instance of the policy type used to instantiate this | |
88 // floating point generator. | |
89 /////////////////////////////////////////////////////////////////////// | |
90 template <typename Inserter, typename OutputIterator, typename Policies> | |
91 static bool | |
92 call (OutputIterator& sink, T n, Policies const& p) | |
93 { | |
94 return Inserter::call_n(sink, n, p); | |
95 } | |
96 | |
97 /////////////////////////////////////////////////////////////////////// | |
98 // The default behavior is to not to require generating a sign. If | |
99 // 'force_sign()' returns true, then all generated numbers will | |
100 // have a sign ('+' or '-', zeros will have a space instead of a sign) | |
101 // | |
102 // n The floating point number to output. This can be used to | |
103 // adjust the required behavior depending on the value of | |
104 // this number. | |
105 /////////////////////////////////////////////////////////////////////// | |
106 static bool force_sign(T) | |
107 { | |
108 return false; | |
109 } | |
110 | |
111 /////////////////////////////////////////////////////////////////////// | |
112 // Return whether trailing zero digits have to be emitted in the | |
113 // fractional part of the output. If set, this flag instructs the | |
114 // floating point generator to emit trailing zeros up to the required | |
115 // precision digits (as returned by the precision() function). | |
116 // | |
117 // n The floating point number to output. This can be used to | |
118 // adjust the required behavior depending on the value of | |
119 // this number. | |
120 /////////////////////////////////////////////////////////////////////// | |
121 static bool trailing_zeros(T) | |
122 { | |
123 // the default behavior is not to generate trailing zeros | |
124 return false; | |
125 } | |
126 | |
127 /////////////////////////////////////////////////////////////////////// | |
128 // Decide, which representation type to use in the generated output. | |
129 // | |
130 // By default all numbers having an absolute value of zero or in | |
131 // between 0.001 and 100000 will be generated using the fixed format, | |
132 // all others will be generated using the scientific representation. | |
133 // | |
134 // The function trailing_zeros() can be used to force the output of | |
135 // trailing zeros in the fractional part up to the number of digits | |
136 // returned by the precision() member function. The default is not to | |
137 // generate the trailing zeros. | |
138 // | |
139 // n The floating point number to output. This can be used to | |
140 // adjust the formatting flags depending on the value of | |
141 // this number. | |
142 /////////////////////////////////////////////////////////////////////// | |
143 static int floatfield(T n) | |
144 { | |
145 if (traits::test_zero(n)) | |
146 return fmtflags::fixed; | |
147 | |
148 T abs_n = traits::get_absolute_value(n); | |
149 return (abs_n >= 1e5 || abs_n < 1e-3) | |
150 ? fmtflags::scientific : fmtflags::fixed; | |
151 } | |
152 | |
153 /////////////////////////////////////////////////////////////////////// | |
154 // Return the maximum number of decimal digits to generate in the | |
155 // fractional part of the output. | |
156 // | |
157 // n The floating point number to output. This can be used to | |
158 // adjust the required precision depending on the value of | |
159 // this number. If the trailing zeros flag is specified the | |
160 // fractional part of the output will be 'filled' with | |
161 // zeros, if appropriate | |
162 // | |
163 // Note: If the trailing_zeros flag is not in effect additional | |
164 // comments apply. See the comment for the fraction_part() | |
165 // function below. Moreover, this precision will be limited | |
166 // to the value of std::numeric_limits<T>::digits10 + 1 | |
167 /////////////////////////////////////////////////////////////////////// | |
168 static unsigned precision(T) | |
169 { | |
170 // by default, generate max. 3 fractional digits | |
171 return 3; | |
172 } | |
173 | |
174 /////////////////////////////////////////////////////////////////////// | |
175 // Generate the integer part of the number. | |
176 // | |
177 // sink The output iterator to use for generation | |
178 // n The absolute value of the integer part of the floating | |
179 // point number to convert (always non-negative). | |
180 // sign The sign of the overall floating point number to | |
181 // convert. | |
182 // force_sign Whether a sign has to be generated even for | |
183 // non-negative numbers. Note, that force_sign will be | |
184 // set to false for zero floating point values. | |
185 /////////////////////////////////////////////////////////////////////// | |
186 template <typename OutputIterator> | |
187 static bool integer_part (OutputIterator& sink, T n, bool sign | |
188 , bool force_sign) | |
189 { | |
190 return sign_inserter::call( | |
191 sink, traits::test_zero(n), sign, force_sign, force_sign) && | |
192 int_inserter<10>::call(sink, n); | |
193 } | |
194 | |
195 /////////////////////////////////////////////////////////////////////// | |
196 // Generate the decimal point. | |
197 // | |
198 // sink The output iterator to use for generation | |
199 // n The fractional part of the floating point number to | |
200 // convert. Note that this number is scaled such, that | |
201 // it represents the number of units which correspond | |
202 // to the value returned from the precision() function | |
203 // earlier. I.e. a fractional part of 0.01234 is | |
204 // represented as 1234 when the 'Precision' is 5. | |
205 // precision The number of digits to emit as returned by the | |
206 // function 'precision()' above | |
207 // | |
208 // This is given to allow to decide, whether a decimal point | |
209 // has to be generated at all. | |
210 // | |
211 // Note: If the trailing_zeros flag is not in effect additional | |
212 // comments apply. See the comment for the fraction_part() | |
213 // function below. | |
214 /////////////////////////////////////////////////////////////////////// | |
215 template <typename OutputIterator> | |
216 static bool dot (OutputIterator& sink, T /*n*/, unsigned /*precision*/) | |
217 { | |
218 return char_inserter<>::call(sink, '.'); // generate the dot by default | |
219 } | |
220 | |
221 /////////////////////////////////////////////////////////////////////// | |
222 // Generate the fractional part of the number. | |
223 // | |
224 // sink The output iterator to use for generation | |
225 // n The fractional part of the floating point number to | |
226 // convert. This number is scaled such, that it represents | |
227 // the number of units which correspond to the 'Precision'. | |
228 // I.e. a fractional part of 0.01234 is represented as 1234 | |
229 // when the 'precision_' parameter is 5. | |
230 // precision_ The corrected number of digits to emit (see note | |
231 // below) | |
232 // precision The number of digits to emit as returned by the | |
233 // function 'precision()' above | |
234 // | |
235 // Note: If trailing_zeros() does not return true the 'precision_' | |
236 // parameter will have been corrected from the value the | |
237 // precision() function returned earlier (defining the maximal | |
238 // number of fractional digits) in the sense, that it takes into | |
239 // account trailing zeros. I.e. a floating point number 0.0123 | |
240 // and a value of 5 returned from precision() will result in: | |
241 // | |
242 // trailing_zeros is not specified: | |
243 // n 123 | |
244 // precision_ 4 | |
245 // | |
246 // trailing_zeros is specified: | |
247 // n 1230 | |
248 // precision_ 5 | |
249 // | |
250 /////////////////////////////////////////////////////////////////////// | |
251 template <typename OutputIterator> | |
252 static bool fraction_part (OutputIterator& sink, T n | |
253 , unsigned precision_, unsigned precision) | |
254 { | |
255 // allow for ADL to find the correct overload for floor and log10 | |
256 using namespace std; | |
257 | |
258 // The following is equivalent to: | |
259 // generate(sink, right_align(precision, '0')[ulong], n); | |
260 // but it's spelled out to avoid inter-modular dependencies. | |
261 | |
262 typename remove_const<T>::type digits = | |
263 (traits::test_zero(n) ? 0 : floor(log10(n))) + 1; | |
264 bool r = true; | |
265 for (/**/; r && digits < precision_; digits = digits + 1) | |
266 r = char_inserter<>::call(sink, '0'); | |
267 if (precision && r) | |
268 r = int_inserter<10>::call(sink, n); | |
269 return r; | |
270 } | |
271 | |
272 /////////////////////////////////////////////////////////////////////// | |
273 // Generate the exponential part of the number (this is called only | |
274 // if the floatfield() function returned the 'scientific' flag). | |
275 // | |
276 // sink The output iterator to use for generation | |
277 // n The (signed) exponential part of the floating point | |
278 // number to convert. | |
279 // | |
280 // The Tag template parameter is either of the type unused_type or | |
281 // describes the character class and conversion to be applied to any | |
282 // output possibly influenced by either the lower[...] or upper[...] | |
283 // directives. | |
284 /////////////////////////////////////////////////////////////////////// | |
285 template <typename CharEncoding, typename Tag, typename OutputIterator> | |
286 static bool exponent (OutputIterator& sink, long n) | |
287 { | |
288 long abs_n = traits::get_absolute_value(n); | |
289 bool r = char_inserter<CharEncoding, Tag>::call(sink, 'e') && | |
290 sign_inserter::call(sink, traits::test_zero(n) | |
291 , traits::test_negative(n), false); | |
292 | |
293 // the C99 Standard requires at least two digits in the exponent | |
294 if (r && abs_n < 10) | |
295 r = char_inserter<CharEncoding, Tag>::call(sink, '0'); | |
296 return r && int_inserter<10>::call(sink, abs_n); | |
297 } | |
298 | |
299 /////////////////////////////////////////////////////////////////////// | |
300 // Print the textual representations for non-normal floats (NaN and | |
301 // Inf) | |
302 // | |
303 // sink The output iterator to use for generation | |
304 // n The (signed) floating point number to convert. | |
305 // force_sign Whether a sign has to be generated even for | |
306 // non-negative numbers | |
307 // | |
308 // The Tag template parameter is either of the type unused_type or | |
309 // describes the character class and conversion to be applied to any | |
310 // output possibly influenced by either the lower[...] or upper[...] | |
311 // directives. | |
312 // | |
313 // Note: These functions get called only if fpclassify() returned | |
314 // FP_INFINITY or FP_NAN. | |
315 /////////////////////////////////////////////////////////////////////// | |
316 template <typename CharEncoding, typename Tag, typename OutputIterator> | |
317 static bool nan (OutputIterator& sink, T n, bool force_sign) | |
318 { | |
319 return sign_inserter::call( | |
320 sink, false, traits::test_negative(n), force_sign) && | |
321 string_inserter<CharEncoding, Tag>::call(sink, "nan"); | |
322 } | |
323 | |
324 template <typename CharEncoding, typename Tag, typename OutputIterator> | |
325 static bool inf (OutputIterator& sink, T n, bool force_sign) | |
326 { | |
327 return sign_inserter::call( | |
328 sink, false, traits::test_negative(n), force_sign) && | |
329 string_inserter<CharEncoding, Tag>::call(sink, "inf"); | |
330 } | |
331 }; | |
332 }}} | |
333 | |
334 #endif // defined(BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM) |