/*=============================================================================
    Copyright (c) 2001-2010 Joel de Guzman
    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(SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM)
#define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
#include <boost/spirit/home/qi/detail/string_parse.hpp>

namespace boost { namespace spirit { namespace qi
{
    ///////////////////////////////////////////////////////////////////////////
    //  Default (unsigned) real number policies
    ///////////////////////////////////////////////////////////////////////////
    template <typename T>
    struct ureal_policies
    {
        // trailing dot policy suggested by Gustavo Guerra
        static bool const allow_leading_dot = true;
        static bool const allow_trailing_dot = true;
        static bool const expect_dot = false;

        template <typename Iterator>
        static bool
        parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
        {
            return false;
        }

        template <typename Iterator, typename Attribute>
        static bool
        parse_n(Iterator& first, Iterator const& last, Attribute& attr)
        {
            return extract_uint<T, 10, 1, -1>::call(first, last, attr);
        }

        template <typename Iterator>
        static bool
        parse_dot(Iterator& first, Iterator const& last)
        {
            if (first == last || *first != '.')
                return false;
            ++first;
            return true;
        }

        template <typename Iterator, typename Attribute>
        static bool
        parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr)
        {
            return extract_uint<T, 10, 1, -1, true>::call(first, last, attr);
        }

        template <typename Iterator>
        static bool
        parse_exp(Iterator& first, Iterator const& last)
        {
            if (first == last || (*first != 'e' && *first != 'E'))
                return false;
            ++first;
            return true;
        }

        template <typename Iterator>
        static bool
        parse_exp_n(Iterator& first, Iterator const& last, int& attr)
        {
            return extract_int<int, 10, 1, -1>::call(first, last, attr);
        }

        ///////////////////////////////////////////////////////////////////////
        //  The parse_nan() and parse_inf() functions get called whenever:
        //
        //    - a number to parse does not start with a digit (after having
        //      successfully parsed an optional sign)
        //
        //  or
        //
        //    - after a floating point number of the value 1 (having no
        //      exponential part and a fractional part value of 0) has been
        //      parsed.
        //
        //  The first call allows to recognize representations of NaN or Inf
        //  starting with a non-digit character (such as NaN, Inf, QNaN etc.).
        //
        //  The second call allows to recognize representation formats starting
        //  with a 1.0 (such as 1.0#NAN or 1.0#INF etc.).
        //
        //  The functions should return true if a Nan or Inf has been found. In
        //  this case the attr should be set to the matched value (NaN or
        //  Inf). The optional sign will be automatically applied afterwards.
        //
        //  The default implementation below recognizes representations of NaN
        //  and Inf as mandated by the C99 Standard and as proposed for
        //  inclusion into the C++0x Standard: nan, nan(...), inf and infinity
        //  (the matching is performed case-insensitively).
        ///////////////////////////////////////////////////////////////////////
        template <typename Iterator, typename Attribute>
        static bool
        parse_nan(Iterator& first, Iterator const& last, Attribute& attr)
        {
            if (first == last)
                return false;   // end of input reached

            if (*first != 'n' && *first != 'N')
                return false;   // not "nan"

            // nan[(...)] ?
            if (detail::string_parse("nan", "NAN", first, last, unused))
            {
                if (*first == '(')
                {
                    // skip trailing (...) part
                    Iterator i = first;

                    while (++i != last && *i != ')')
                        ;
                    if (i == last)
                        return false;     // no trailing ')' found, give up

                    first = ++i;
                }
                attr = std::numeric_limits<T>::quiet_NaN();
                return true;
            }
            return false;
        }

        template <typename Iterator, typename Attribute>
        static bool
        parse_inf(Iterator& first, Iterator const& last, Attribute& attr)
        {
            if (first == last)
                return false;   // end of input reached

            if (*first != 'i' && *first != 'I')
                return false;   // not "inf"

            // inf or infinity ?
            if (detail::string_parse("inf", "INF", first, last, unused))
            {
                // skip allowed 'inity' part of infinity
                detail::string_parse("inity", "INITY", first, last, unused);
                attr = std::numeric_limits<T>::infinity();
                return true;
            }
            return false;
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //  Default (signed) real number policies
    ///////////////////////////////////////////////////////////////////////////
    template <typename T>
    struct real_policies : ureal_policies<T>
    {
        template <typename Iterator>
        static bool
        parse_sign(Iterator& first, Iterator const& last)
        {
            return extract_sign(first, last);
        }
    };

    template <typename T>
    struct strict_ureal_policies : ureal_policies<T>
    {
        static bool const expect_dot = true;
    };

    template <typename T>
    struct strict_real_policies : real_policies<T>
    {
        static bool const expect_dot = true;
    };
}}}

#endif
