//  Copyright (c) 2001-2010 Hartmut Kaiser
// 
//  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_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM)
#define BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/config/no_tr1/cmath.hpp>
#include <boost/math/special_functions/fpclassify.hpp>

#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/char.hpp>
#include <boost/spirit/home/karma/numeric/int.hpp>
#include <boost/spirit/home/karma/numeric/detail/real_utils.hpp>

#include <boost/mpl/bool.hpp>

namespace boost { namespace spirit { namespace karma 
{
    ///////////////////////////////////////////////////////////////////////////
    //
    //  real_policies, if you need special handling of your floating
    //  point numbers, just overload this policy class and use it as a template
    //  parameter to the karma::real_generator floating point specifier:
    //
    //      template <typename T>
    //      struct scientific_policy : karma::real_policies<T>
    //      {
    //          //  we want the numbers always to be in scientific format
    //          static int floatfield(T n) { return fmtflags::scientific; }
    //      };
    //
    //      typedef 
    //          karma::real_generator<double, scientific_policy<double> > 
    //      science_type;
    //
    //      karma::generate(sink, science_type(), 1.0); // will output: 1.0e00
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename T>
    struct real_policies
    {
        ///////////////////////////////////////////////////////////////////////
        // Expose the data type the generator is targeted at
        ///////////////////////////////////////////////////////////////////////
        typedef T value_type;

        ///////////////////////////////////////////////////////////////////////
        //  By default the policy doesn't require any special iterator 
        //  functionality. The floating point generator exposes its properties
        //  from here, so this needs to be updated in case other properties
        //  need to be implemented.
        ///////////////////////////////////////////////////////////////////////
        typedef mpl::int_<generator_properties::no_properties> properties;

        ///////////////////////////////////////////////////////////////////////
        //  Specifies, which representation type to use during output 
        //  generation.
        ///////////////////////////////////////////////////////////////////////
        struct fmtflags
        {
            enum {
                scientific = 0,   // Generate floating-point values in scientific 
                                  // format (with an exponent field).
                fixed = 1         // Generate floating-point values in fixed-point 
                                  // format (with no exponent field). 
            };
        };

        ///////////////////////////////////////////////////////////////////////
        //  This is the main function used to generate the output for a 
        //  floating point number. It is called by the real generator in order 
        //  to perform the conversion. In theory all of the work can be 
        //  implemented here, but it is the easiest to use existing 
        //  functionality provided by the type specified by the template 
        //  parameter `Inserter`. 
        //
        //      sink: the output iterator to use for generation
        //      n:    the floating point number to convert 
        //      p:    the instance of the policy type used to instantiate this 
        //            floating point generator.
        ///////////////////////////////////////////////////////////////////////
        template <typename Inserter, typename OutputIterator, typename Policies>
        static bool
        call (OutputIterator& sink, T n, Policies const& p)
        {
            return Inserter::call_n(sink, n, p);
        }

        ///////////////////////////////////////////////////////////////////////
        //  The default behavior is to not to require generating a sign. If 
        //  'force_sign()' returns true, then all generated numbers will 
        //  have a sign ('+' or '-', zeros will have a space instead of a sign)
        // 
        //      n     The floating point number to output. This can be used to 
        //            adjust the required behavior depending on the value of 
        //            this number.
        ///////////////////////////////////////////////////////////////////////
        static bool force_sign(T)
        {
            return false;
        }

        ///////////////////////////////////////////////////////////////////////
        //  Return whether trailing zero digits have to be emitted in the 
        //  fractional part of the output. If set, this flag instructs the 
        //  floating point generator to emit trailing zeros up to the required 
        //  precision digits (as returned by the precision() function).
        // 
        //      n     The floating point number to output. This can be used to 
        //            adjust the required behavior depending on the value of 
        //            this number.
        ///////////////////////////////////////////////////////////////////////
        static bool trailing_zeros(T)
        {
            // the default behavior is not to generate trailing zeros
            return false;
        }

        ///////////////////////////////////////////////////////////////////////
        //  Decide, which representation type to use in the generated output.
        //
        //  By default all numbers having an absolute value of zero or in 
        //  between 0.001 and 100000 will be generated using the fixed format, 
        //  all others will be generated using the scientific representation.
        //
        //  The function trailing_zeros() can be used to force the output of 
        //  trailing zeros in the fractional part up to the number of digits 
        //  returned by the precision() member function. The default is not to 
        //  generate the trailing zeros.
        //  
        //      n     The floating point number to output. This can be used to 
        //            adjust the formatting flags depending on the value of 
        //            this number.
        ///////////////////////////////////////////////////////////////////////
        static int floatfield(T n)
        {
            if (detail::is_zero(n))
                return fmtflags::fixed;

            T abs_n = detail::absolute_value(n);
            return (abs_n >= 1e5 || abs_n < 1e-3) 
              ? fmtflags::scientific : fmtflags::fixed;
        }

        ///////////////////////////////////////////////////////////////////////
        //  Return the maximum number of decimal digits to generate in the 
        //  fractional part of the output.
        //  
        //      n     The floating point number to output. This can be used to 
        //            adjust the required precision depending on the value of 
        //            this number. If the trailing zeros flag is specified the
        //            fractional part of the output will be 'filled' with 
        //            zeros, if appropriate
        //
        //  Note:     If the trailing_zeros flag is not in effect additional
        //            comments apply. See the comment for the fraction_part()
        //            function below. Moreover, this precision will be limited
        //            to the value of std::numeric_limits<T>::digits10 + 1
        ///////////////////////////////////////////////////////////////////////
        static unsigned precision(T)
        {
            // by default, generate max. 3 fractional digits
            return 3;
        }

        ///////////////////////////////////////////////////////////////////////
        //  Generate the integer part of the number.
        //
        //      sink       The output iterator to use for generation
        //      n          The absolute value of the integer part of the floating 
        //                 point number to convert (always non-negative). 
        //      sign       The sign of the overall floating point number to 
        //                 convert.
        //      force_sign Whether a sign has to be generated even for 
        //                 non-negative numbers
        ///////////////////////////////////////////////////////////////////////
        template <typename OutputIterator>
        static bool integer_part (OutputIterator& sink, T n, bool sign
          , bool force_sign)
        {
            return sign_inserter::call(
                      sink, detail::is_zero(n), sign, force_sign) &&
                   int_inserter<10>::call(sink, n);
        }

        ///////////////////////////////////////////////////////////////////////
        //  Generate the decimal point.
        //
        //      sink  The output iterator to use for generation
        //      n     The fractional part of the floating point number to 
        //            convert. Note that this number is scaled such, that 
        //            it represents the number of units which correspond
        //            to the value returned from the precision() function 
        //            earlier. I.e. a fractional part of 0.01234 is
        //            represented as 1234 when the 'Precision' is 5.
        //      precision   The number of digits to emit as returned by the 
        //                  function 'precision()' above
        //
        //            This is given to allow to decide, whether a decimal point
        //            has to be generated at all.
        //
        //  Note:     If the trailing_zeros flag is not in effect additional
        //            comments apply. See the comment for the fraction_part()
        //            function below.
        ///////////////////////////////////////////////////////////////////////
        template <typename OutputIterator>
        static bool dot (OutputIterator& sink, T /*n*/, unsigned /*precision*/)
        {
            return char_inserter<>::call(sink, '.');  // generate the dot by default 
        }

        ///////////////////////////////////////////////////////////////////////
        //  Generate the fractional part of the number.
        //
        //      sink  The output iterator to use for generation
        //      n     The fractional part of the floating point number to 
        //            convert. This number is scaled such, that it represents 
        //            the number of units which correspond to the 'Precision'. 
        //            I.e. a fractional part of 0.01234 is represented as 1234 
        //            when the 'precision_' parameter is 5.
        //      precision_  The corrected number of digits to emit (see note 
        //                  below)
        //      precision   The number of digits to emit as returned by the 
        //                  function 'precision()' above
        //
        //  Note: If trailing_zeros() does not return true the 'precision_' 
        //        parameter will have been corrected from the value the 
        //        precision() function returned earlier (defining the maximal 
        //        number of fractional digits) in the sense, that it takes into 
        //        account trailing zeros. I.e. a floating point number 0.0123 
        //        and a value of 5 returned from precision() will result in:
        //
        //        trailing_zeros is not specified:
        //            n           123
        //            precision_  4
        //
        //        trailing_zeros is specified:
        //            n           1230
        //            precision_  5
        //
        ///////////////////////////////////////////////////////////////////////
        template <typename OutputIterator>
        static bool fraction_part (OutputIterator& sink, T n
          , unsigned precision_, unsigned precision)
        {
            // allow for ADL to find the correct overload for floor and log10
            using namespace std;

            // The following is equivalent to:
            //    generate(sink, right_align(precision, '0')[ulong], n);
            // but it's spelled out to avoid inter-modular dependencies.

            T digits = (detail::is_zero(n) ? 0 : floor(log10(n))) + 1;
            bool r = true;
            for (/**/; r && digits < precision_; digits = digits + 1)
                r = char_inserter<>::call(sink, '0');
            if (precision && r)
                r = int_inserter<10>::call(sink, n);
            return r;
        }

        ///////////////////////////////////////////////////////////////////////
        //  Generate the exponential part of the number (this is called only 
        //  if the floatfield() function returned the 'scientific' flag).
        //
        //      sink  The output iterator to use for generation
        //      n     The (signed) exponential part of the floating point 
        //            number to convert. 
        //
        //  The Tag template parameter is either of the type unused_type or
        //  describes the character class and conversion to be applied to any 
        //  output possibly influenced by either the lower[...] or upper[...] 
        //  directives.
        ///////////////////////////////////////////////////////////////////////
        template <typename CharEncoding, typename Tag, typename OutputIterator>
        static bool exponent (OutputIterator& sink, long n)
        {
            long abs_n = detail::absolute_value(n);
            bool r = char_inserter<CharEncoding, Tag>::call(sink, 'e') &&
                     sign_inserter::call(sink, detail::is_zero(n)
                        , detail::is_negative(n), false);

            // the C99 Standard requires at least two digits in the exponent
            if (r && abs_n < 10)
                r = char_inserter<CharEncoding, Tag>::call(sink, '0');
            return r && int_inserter<10>::call(sink, abs_n);
        }

        ///////////////////////////////////////////////////////////////////////
        //  Print the textual representations for non-normal floats (NaN and 
        //  Inf)
        //
        //      sink       The output iterator to use for generation
        //      n          The (signed) floating point number to convert. 
        //      force_sign Whether a sign has to be generated even for 
        //                 non-negative numbers
        //
        //  The Tag template parameter is either of the type unused_type or
        //  describes the character class and conversion to be applied to any 
        //  output possibly influenced by either the lower[...] or upper[...] 
        //  directives.
        //
        //  Note: These functions get called only if fpclassify() returned 
        //        FP_INFINITY or FP_NAN.
        ///////////////////////////////////////////////////////////////////////
        template <typename CharEncoding, typename Tag, typename OutputIterator>
        static bool nan (OutputIterator& sink, T n, bool force_sign)
        {
            return sign_inserter::call(
                        sink, false, detail::is_negative(n), force_sign) &&
                   string_inserter<CharEncoding, Tag>::call(sink, "nan");
        }

        template <typename CharEncoding, typename Tag, typename OutputIterator>
        static bool inf (OutputIterator& sink, T n, bool force_sign)
        {
            return sign_inserter::call(
                        sink, false, detail::is_negative(n), force_sign) &&
                   string_inserter<CharEncoding, Tag>::call(sink, "inf");
        }
    };

}}}

#endif // defined(BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM)
