Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:38

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 // 
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #if !defined(BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM)
0007 #define BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/config/no_tr1/cmath.hpp>
0014 #include <boost/type_traits/remove_const.hpp>
0015 
0016 #include <boost/spirit/home/support/char_class.hpp>
0017 #include <boost/spirit/home/karma/generator.hpp>
0018 #include <boost/spirit/home/karma/char.hpp>
0019 #include <boost/spirit/home/karma/numeric/int.hpp>
0020 #include <boost/spirit/home/karma/numeric/detail/real_utils.hpp>
0021 
0022 #include <boost/mpl/bool.hpp>
0023 
0024 namespace boost { namespace spirit { namespace karma 
0025 {
0026     ///////////////////////////////////////////////////////////////////////////
0027     //
0028     //  real_policies, if you need special handling of your floating
0029     //  point numbers, just overload this policy class and use it as a template
0030     //  parameter to the karma::real_generator floating point specifier:
0031     //
0032     //      template <typename T>
0033     //      struct scientific_policy : karma::real_policies<T>
0034     //      {
0035     //          //  we want the numbers always to be in scientific format
0036     //          static int floatfield(T n) { return fmtflags::scientific; }
0037     //      };
0038     //
0039     //      typedef 
0040     //          karma::real_generator<double, scientific_policy<double> > 
0041     //      science_type;
0042     //
0043     //      karma::generate(sink, science_type(), 1.0); // will output: 1.0e00
0044     //
0045     ///////////////////////////////////////////////////////////////////////////
0046     template <typename T>
0047     struct real_policies
0048     {
0049         ///////////////////////////////////////////////////////////////////////
0050         // Expose the data type the generator is targeted at
0051         ///////////////////////////////////////////////////////////////////////
0052         typedef T value_type;
0053 
0054         ///////////////////////////////////////////////////////////////////////
0055         //  By default the policy doesn't require any special iterator 
0056         //  functionality. The floating point generator exposes its properties
0057         //  from here, so this needs to be updated in case other properties
0058         //  need to be implemented.
0059         ///////////////////////////////////////////////////////////////////////
0060         typedef mpl::int_<generator_properties::no_properties> properties;
0061 
0062         ///////////////////////////////////////////////////////////////////////
0063         //  Specifies, which representation type to use during output 
0064         //  generation.
0065         ///////////////////////////////////////////////////////////////////////
0066         struct fmtflags
0067         {
0068             enum {
0069                 scientific = 0,   // Generate floating-point values in scientific 
0070                                   // format (with an exponent field).
0071                 fixed = 1         // Generate floating-point values in fixed-point 
0072                                   // format (with no exponent field). 
0073             };
0074         };
0075 
0076         ///////////////////////////////////////////////////////////////////////
0077         //  This is the main function used to generate the output for a 
0078         //  floating point number. It is called by the real generator in order 
0079         //  to perform the conversion. In theory all of the work can be 
0080         //  implemented here, but it is the easiest to use existing 
0081         //  functionality provided by the type specified by the template 
0082         //  parameter `Inserter`. 
0083         //
0084         //      sink: the output iterator to use for generation
0085         //      n:    the floating point number to convert 
0086         //      p:    the instance of the policy type used to instantiate this 
0087         //            floating point generator.
0088         ///////////////////////////////////////////////////////////////////////
0089         template <typename Inserter, typename OutputIterator, typename Policies>
0090         static bool
0091         call (OutputIterator& sink, T n, Policies const& p)
0092         {
0093             return Inserter::call_n(sink, n, p);
0094         }
0095 
0096         ///////////////////////////////////////////////////////////////////////
0097         //  The default behavior is to not to require generating a sign. If 
0098         //  'force_sign()' returns true, then all generated numbers will 
0099         //  have a sign ('+' or '-', zeros will have a space instead of a sign)
0100         // 
0101         //      n     The floating point number to output. This can be used to 
0102         //            adjust the required behavior depending on the value of 
0103         //            this number.
0104         ///////////////////////////////////////////////////////////////////////
0105         static bool force_sign(T)
0106         {
0107             return false;
0108         }
0109 
0110         ///////////////////////////////////////////////////////////////////////
0111         //  Return whether trailing zero digits have to be emitted in the 
0112         //  fractional part of the output. If set, this flag instructs the 
0113         //  floating point generator to emit trailing zeros up to the required 
0114         //  precision digits (as returned by the precision() function).
0115         // 
0116         //      n     The floating point number to output. This can be used to 
0117         //            adjust the required behavior depending on the value of 
0118         //            this number.
0119         ///////////////////////////////////////////////////////////////////////
0120         static bool trailing_zeros(T)
0121         {
0122             // the default behavior is not to generate trailing zeros
0123             return false;
0124         }
0125 
0126         ///////////////////////////////////////////////////////////////////////
0127         //  Decide, which representation type to use in the generated output.
0128         //
0129         //  By default all numbers having an absolute value of zero or in 
0130         //  between 0.001 and 100000 will be generated using the fixed format, 
0131         //  all others will be generated using the scientific representation.
0132         //
0133         //  The function trailing_zeros() can be used to force the output of 
0134         //  trailing zeros in the fractional part up to the number of digits 
0135         //  returned by the precision() member function. The default is not to 
0136         //  generate the trailing zeros.
0137         //  
0138         //      n     The floating point number to output. This can be used to 
0139         //            adjust the formatting flags depending on the value of 
0140         //            this number.
0141         ///////////////////////////////////////////////////////////////////////
0142         static int floatfield(T n)
0143         {
0144             if (traits::test_zero(n))
0145                 return fmtflags::fixed;
0146 
0147             T abs_n = traits::get_absolute_value(n);
0148             return (abs_n >= 1e5 || abs_n < 1e-3) 
0149               ? fmtflags::scientific : fmtflags::fixed;
0150         }
0151 
0152         ///////////////////////////////////////////////////////////////////////
0153         //  Return the maximum number of decimal digits to generate in the 
0154         //  fractional part of the output.
0155         //  
0156         //      n     The floating point number to output. This can be used to 
0157         //            adjust the required precision depending on the value of 
0158         //            this number. If the trailing zeros flag is specified the
0159         //            fractional part of the output will be 'filled' with 
0160         //            zeros, if appropriate
0161         //
0162         //  Note:     If the trailing_zeros flag is not in effect additional
0163         //            comments apply. See the comment for the fraction_part()
0164         //            function below.
0165         ///////////////////////////////////////////////////////////////////////
0166         static unsigned precision(T)
0167         {
0168             // by default, generate max. 3 fractional digits
0169             return 3;
0170         }
0171 
0172         ///////////////////////////////////////////////////////////////////////
0173         //  Generate the integer part of the number.
0174         //
0175         //      sink       The output iterator to use for generation
0176         //      n          The absolute value of the integer part of the floating
0177         //                 point number to convert (always non-negative).
0178         //      sign       The sign of the overall floating point number to
0179         //                 convert.
0180         //      force_sign Whether a sign has to be generated even for
0181         //                 non-negative numbers. Note, that force_sign will be
0182         //                 set to false for zero floating point values.
0183         ///////////////////////////////////////////////////////////////////////
0184         template <typename OutputIterator>
0185         static bool integer_part (OutputIterator& sink, T n, bool sign
0186           , bool force_sign)
0187         {
0188             return sign_inserter::call(
0189                       sink, traits::test_zero(n), sign, force_sign, force_sign) &&
0190                    int_inserter<10>::call(sink, n);
0191         }
0192 
0193         ///////////////////////////////////////////////////////////////////////
0194         //  Generate the decimal point.
0195         //
0196         //      sink  The output iterator to use for generation
0197         //      n     The fractional part of the floating point number to 
0198         //            convert. Note that this number is scaled such, that 
0199         //            it represents the number of units which correspond
0200         //            to the value returned from the precision() function 
0201         //            earlier. I.e. a fractional part of 0.01234 is
0202         //            represented as 1234 when the 'Precision' is 5.
0203         //      precision   The number of digits to emit as returned by the 
0204         //                  function 'precision()' above
0205         //
0206         //            This is given to allow to decide, whether a decimal point
0207         //            has to be generated at all.
0208         //
0209         //  Note:     If the trailing_zeros flag is not in effect additional
0210         //            comments apply. See the comment for the fraction_part()
0211         //            function below.
0212         ///////////////////////////////////////////////////////////////////////
0213         template <typename OutputIterator>
0214         static bool dot (OutputIterator& sink, T /*n*/, unsigned /*precision*/)
0215         {
0216             return char_inserter<>::call(sink, '.');  // generate the dot by default 
0217         }
0218 
0219         ///////////////////////////////////////////////////////////////////////
0220         //  Generate the fractional part of the number.
0221         //
0222         //      sink  The output iterator to use for generation
0223         //      n     The fractional part of the floating point number to 
0224         //            convert. This number is scaled such, that it represents 
0225         //            the number of units which correspond to the 'Precision'. 
0226         //            I.e. a fractional part of 0.01234 is represented as 1234 
0227         //            when the 'precision_' parameter is 5.
0228         //      precision_  The corrected number of digits to emit (see note 
0229         //                  below)
0230         //      precision   The number of digits to emit as returned by the 
0231         //                  function 'precision()' above
0232         //
0233         //  Note: If trailing_zeros() does not return true the 'precision_' 
0234         //        parameter will have been corrected from the value the 
0235         //        precision() function returned earlier (defining the maximal 
0236         //        number of fractional digits) in the sense, that it takes into 
0237         //        account trailing zeros. I.e. a floating point number 0.0123 
0238         //        and a value of 5 returned from precision() will result in:
0239         //
0240         //        trailing_zeros is not specified:
0241         //            n           123
0242         //            precision_  4
0243         //
0244         //        trailing_zeros is specified:
0245         //            n           1230
0246         //            precision_  5
0247         //
0248         ///////////////////////////////////////////////////////////////////////
0249         template <typename OutputIterator>
0250         static bool fraction_part (OutputIterator& sink, T n
0251           , unsigned precision_, unsigned precision)
0252         {
0253             // allow for ADL to find the correct overload for floor and log10
0254             using namespace std;
0255 
0256             // The following is equivalent to:
0257             //    generate(sink, right_align(precision, '0')[ulong], n);
0258             // but it's spelled out to avoid inter-modular dependencies.
0259 
0260             typename remove_const<T>::type digits = 
0261                 (traits::test_zero(n) ? 1 : ceil(log10(n + T(1.))));
0262             bool r = true;
0263             for (/**/; r && digits < precision_; digits = digits + 1)
0264                 r = char_inserter<>::call(sink, '0');
0265             if (precision && r)
0266                 r = int_inserter<10>::call(sink, n);
0267             return r;
0268         }
0269 
0270         ///////////////////////////////////////////////////////////////////////
0271         //  Generate the exponential part of the number (this is called only 
0272         //  if the floatfield() function returned the 'scientific' flag).
0273         //
0274         //      sink  The output iterator to use for generation
0275         //      n     The (signed) exponential part of the floating point 
0276         //            number to convert. 
0277         //
0278         //  The Tag template parameter is either of the type unused_type or
0279         //  describes the character class and conversion to be applied to any 
0280         //  output possibly influenced by either the lower[...] or upper[...] 
0281         //  directives.
0282         ///////////////////////////////////////////////////////////////////////
0283         template <typename CharEncoding, typename Tag, typename OutputIterator>
0284         static bool exponent (OutputIterator& sink, long n)
0285         {
0286             long abs_n = traits::get_absolute_value(n);
0287             bool r = char_inserter<CharEncoding, Tag>::call(sink, 'e') &&
0288                      sign_inserter::call(sink, traits::test_zero(n)
0289                         , traits::test_negative(n), false);
0290 
0291             // the C99 Standard requires at least two digits in the exponent
0292             if (r && abs_n < 10)
0293                 r = char_inserter<CharEncoding, Tag>::call(sink, '0');
0294             return r && int_inserter<10>::call(sink, abs_n);
0295         }
0296 
0297         ///////////////////////////////////////////////////////////////////////
0298         //  Print the textual representations for non-normal floats (NaN and 
0299         //  Inf)
0300         //
0301         //      sink       The output iterator to use for generation
0302         //      n          The (signed) floating point number to convert. 
0303         //      force_sign Whether a sign has to be generated even for 
0304         //                 non-negative numbers
0305         //
0306         //  The Tag template parameter is either of the type unused_type or
0307         //  describes the character class and conversion to be applied to any 
0308         //  output possibly influenced by either the lower[...] or upper[...] 
0309         //  directives.
0310         //
0311         //  Note: These functions get called only if fpclassify() returned 
0312         //        FP_INFINITY or FP_NAN.
0313         ///////////////////////////////////////////////////////////////////////
0314         template <typename CharEncoding, typename Tag, typename OutputIterator>
0315         static bool nan (OutputIterator& sink, T n, bool force_sign)
0316         {
0317             return sign_inserter::call(
0318                         sink, false, traits::test_negative(n), force_sign) &&
0319                    string_inserter<CharEncoding, Tag>::call(sink, "nan");
0320         }
0321 
0322         template <typename CharEncoding, typename Tag, typename OutputIterator>
0323         static bool inf (OutputIterator& sink, T n, bool force_sign)
0324         {
0325             return sign_inserter::call(
0326                         sink, false, traits::test_negative(n), force_sign) &&
0327                    string_inserter<CharEncoding, Tag>::call(sink, "inf");
0328         }
0329     };
0330 }}}
0331 
0332 #endif // defined(BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM)