stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,338 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
Copyright (c) 2011 Bryce Lelbach
|
||||
|
||||
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_QI_BOOL_SEP_29_2009_0709AM)
|
||||
#define SPIRIT_QI_BOOL_SEP_29_2009_0709AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/bool_policies.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// forward declaration only
|
||||
template <typename T>
|
||||
struct bool_policies;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This is the class that the user can instantiate directly in
|
||||
// order to create a customized bool parser
|
||||
template <typename T, typename BoolPolicies = bool_policies<T> >
|
||||
struct bool_parser
|
||||
: spirit::terminal<tag::stateful_tag<BoolPolicies, tag::bool_, T> >
|
||||
{
|
||||
typedef tag::stateful_tag<BoolPolicies, tag::bool_, T> tag_type;
|
||||
|
||||
bool_parser() {}
|
||||
bool_parser(BoolPolicies const& data)
|
||||
: spirit::terminal<tag_type>(data) {}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables bool_
|
||||
struct use_terminal<qi::domain, tag::bool_>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables true_
|
||||
struct use_terminal<qi::domain, tag::true_>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables false_
|
||||
struct use_terminal<qi::domain, tag::false_>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables lit(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, bool> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables bool_(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::bool_, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* bool_(...)
|
||||
struct use_lazy_terminal<qi::domain, tag::bool_, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables any custom bool_parser
|
||||
template <typename T, typename BoolPolicies>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::stateful_tag<BoolPolicies, tag::bool_, T> >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables any custom bool_parser(...)
|
||||
template <typename T, typename BoolPolicies, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::stateful_tag<BoolPolicies, tag::bool_, T>
|
||||
, fusion::vector1<A0> > >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables *lazy* custom bool_parser(...)
|
||||
template <typename T, typename BoolPolicies>
|
||||
struct use_lazy_terminal<
|
||||
qi::domain
|
||||
, tag::stateful_tag<BoolPolicies, tag::bool_, T>
|
||||
, 1 // arity
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::bool_;
|
||||
using spirit::true_;
|
||||
using spirit::false_;
|
||||
using spirit::lit; // lit(true) is equivalent to true
|
||||
#endif
|
||||
using spirit::bool_type;
|
||||
using spirit::true_type;
|
||||
using spirit::false_type;
|
||||
using spirit::lit_type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename T, typename BoolPolicies>
|
||||
struct bool_impl
|
||||
{
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool parse(Iterator& first, Iterator const& last
|
||||
, Attribute& attr, BoolPolicies const& p, bool allow_true = true
|
||||
, bool disallow_false = false)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
p; // suppresses warning: C4100: 'p' : unreferenced formal parameter
|
||||
#endif
|
||||
return (allow_true && p.parse_true(first, last, attr)) ||
|
||||
(!disallow_false && p.parse_false(first, last, attr));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This actual boolean parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename BoolPolicies = bool_policies<T> >
|
||||
struct any_bool_parser
|
||||
: primitive_parser<any_bool_parser<T, BoolPolicies> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef detail::bool_impl<T, BoolPolicies> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::parse(first, last, attr_, BoolPolicies());
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("boolean");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename BoolPolicies = bool_policies<T>
|
||||
, bool no_attribute = true>
|
||||
struct literal_bool_parser
|
||||
: primitive_parser<literal_bool_parser<T, BoolPolicies, no_attribute> >
|
||||
{
|
||||
template <typename Value>
|
||||
literal_bool_parser(Value const& n) : n_(n) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_c<no_attribute, unused_type, T>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef detail::bool_impl<T, BoolPolicies> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::parse(first, last, attr_, BoolPolicies(), n_, n_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("boolean");
|
||||
}
|
||||
|
||||
T n_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Modifiers
|
||||
, typename Policies = bool_policies<T> >
|
||||
struct make_bool
|
||||
{
|
||||
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
|
||||
no_case;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
no_case
|
||||
, is_same<bool_policies<T>, Policies>
|
||||
>
|
||||
, any_bool_parser<T, no_case_bool_policies<T> >
|
||||
, any_bool_parser<T, Policies> >::type
|
||||
result_type;
|
||||
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Modifiers
|
||||
, typename Policies = bool_policies<T> >
|
||||
struct make_direct_bool
|
||||
{
|
||||
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
|
||||
no_case;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
no_case
|
||||
, is_same<bool_policies<T>, Policies>
|
||||
>
|
||||
, literal_bool_parser<T, no_case_bool_policies<T>, false>
|
||||
, literal_bool_parser<T, Policies, false> >::type
|
||||
result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Modifiers, bool b
|
||||
, typename Policies = bool_policies<T> >
|
||||
struct make_predefined_direct_bool
|
||||
{
|
||||
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
|
||||
no_case;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
no_case
|
||||
, is_same<bool_policies<T>, Policies>
|
||||
>
|
||||
, literal_bool_parser<T, no_case_bool_policies<T>, false>
|
||||
, literal_bool_parser<T, Policies, false> >::type
|
||||
result_type;
|
||||
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type(b);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Modifiers
|
||||
, typename Policies = bool_policies<T> >
|
||||
struct make_literal_bool
|
||||
{
|
||||
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
|
||||
no_case;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
no_case
|
||||
, is_same<bool_policies<T>, Policies>
|
||||
>
|
||||
, literal_bool_parser<T, no_case_bool_policies<T> >
|
||||
, literal_bool_parser<T, Policies> >::type
|
||||
result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, bool> >::type>
|
||||
: make_literal_bool<bool, Modifiers> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::false_, Modifiers>
|
||||
: make_predefined_direct_bool<bool, Modifiers, false>
|
||||
{};
|
||||
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::true_, Modifiers>
|
||||
: make_predefined_direct_bool<bool, Modifiers, true>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Policies, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
|
||||
: make_bool<T, Modifiers, Policies> {};
|
||||
|
||||
template <typename T, typename Policies, typename A0, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::stateful_tag<Policies, tag::bool_, T>
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_bool<T, Modifiers, Policies> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::bool_, Modifiers>
|
||||
: make_bool<bool, Modifiers> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::bool_
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_bool<bool, Modifiers> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 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_QI_BOOL_POLICIES_SEP_29_2009_0710AM)
|
||||
#define SPIRIT_QI_BOOL_POLICIES_SEP_29_2009_0710AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/detail/string_parse.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Default boolean policies
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T = bool>
|
||||
struct bool_policies
|
||||
{
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_true(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (detail::string_parse("true", first, last, unused))
|
||||
{
|
||||
spirit::traits::assign_to(T(true), attr_); // result is true
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_false(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (detail::string_parse("false", first, last, unused))
|
||||
{
|
||||
spirit::traits::assign_to(T(false), attr_); // result is false
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T = bool>
|
||||
struct no_case_bool_policies
|
||||
{
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_true(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (detail::string_parse("true", "TRUE", first, last, unused))
|
||||
{
|
||||
spirit::traits::assign_to(T(true), attr_); // result is true
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_false(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (detail::string_parse("false", "FALSE", first, last, unused))
|
||||
{
|
||||
spirit::traits::assign_to(T(false), attr_); // result is false
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+534
@@ -0,0 +1,534 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
Copyright (c) 2011 Jan Frederick Eick
|
||||
Copyright (c) 2011 Christopher Jefferson
|
||||
Copyright (c) 2006 Stephen Nutt
|
||||
|
||||
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_NUMERIC_UTILS_APRIL_17_2006_0816AM)
|
||||
#define SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0816AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
|
||||
#include <boost/spirit/home/support/numeric_traits.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/comparison/less.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/seq/elem.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
|
||||
# define SPIRIT_NUMERICS_LOOP_UNROLL 3
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The maximum radix digits that can be represented without
|
||||
// overflow:
|
||||
//
|
||||
// template<typename T, unsigned Radix>
|
||||
// struct digits_traits::value;
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix>
|
||||
struct digits_traits;
|
||||
|
||||
// lookup table for log2(x) : 2 <= x <= 36
|
||||
#define BOOST_SPIRIT_LOG2 (#error)(#error) \
|
||||
(1000000)(1584960)(2000000)(2321920)(2584960)(2807350) \
|
||||
(3000000)(3169920)(3321920)(3459430)(3584960)(3700430) \
|
||||
(3807350)(3906890)(4000000)(4087460)(4169920)(4247920) \
|
||||
(4321920)(4392310)(4459430)(4523560)(4584960)(4643850) \
|
||||
(4700430)(4754880)(4807350)(4857980)(4906890)(4954190) \
|
||||
(5000000)(5044390)(5087460)(5129280)(5169925) \
|
||||
/***/
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(Radix) \
|
||||
template <typename T> struct digits_traits<T, Radix> \
|
||||
{ \
|
||||
typedef std::numeric_limits<T> numeric_limits_type; \
|
||||
BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \
|
||||
(numeric_limits_type::digits * 1000000) / \
|
||||
BOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_LOG2))); \
|
||||
}; \
|
||||
/***/
|
||||
|
||||
#define BOOST_PP_LOCAL_LIMITS (2, 36)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#undef BOOST_SPIRIT_LOG2
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Traits class for radix specific number conversion
|
||||
//
|
||||
// Test the validity of a single character:
|
||||
//
|
||||
// template<typename Char> static bool is_valid(Char ch);
|
||||
//
|
||||
// Convert a digit from character representation to binary
|
||||
// representation:
|
||||
//
|
||||
// template<typename Char> static int digit(Char ch);
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <unsigned Radix>
|
||||
struct radix_traits
|
||||
{
|
||||
template <typename Char>
|
||||
inline static bool is_valid(Char ch)
|
||||
{
|
||||
if (Radix <= 10)
|
||||
return (ch >= '0' && ch <= static_cast<Char>('0' + Radix -1));
|
||||
return (ch >= '0' && ch <= '9')
|
||||
|| (ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
|
||||
|| (ch >= 'A' && ch <= static_cast<Char>('A' + Radix -10 -1));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline static unsigned digit(Char ch)
|
||||
{
|
||||
if (Radix <= 10 || (ch >= '0' && ch <= '9'))
|
||||
return ch - '0';
|
||||
return spirit::char_encoding::ascii::tolower(ch) - 'a' + 10;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, T Val>
|
||||
struct constexpr_int
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR T value = Val;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// positive_accumulator/negative_accumulator: Accumulator policies for
|
||||
// extracting integers. Use positive_accumulator if number is positive.
|
||||
// Use negative_accumulator if number is negative.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <unsigned Radix>
|
||||
struct positive_accumulator
|
||||
{
|
||||
template <typename T, typename Char>
|
||||
inline static void add(T& n, Char ch, mpl::false_) // unchecked add
|
||||
{
|
||||
const int digit = radix_traits<Radix>::digit(ch);
|
||||
n = n * T(Radix) + T(digit);
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline static bool add(T& n, Char ch, mpl::true_) // checked add
|
||||
{
|
||||
// Ensure n *= Radix will not overflow
|
||||
typedef constexpr_int<T, boost::integer_traits<T>::const_max> max;
|
||||
typedef constexpr_int<T, max::value / Radix> val;
|
||||
|
||||
if (n > val::value)
|
||||
return false;
|
||||
|
||||
n *= Radix;
|
||||
|
||||
// Ensure n += digit will not overflow
|
||||
const int digit = radix_traits<Radix>::digit(ch);
|
||||
if (n > max::value - digit)
|
||||
return false;
|
||||
|
||||
n += static_cast<T>(digit);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned Radix>
|
||||
struct negative_accumulator
|
||||
{
|
||||
template <typename T, typename Char>
|
||||
inline static void add(T& n, Char ch, mpl::false_) // unchecked subtract
|
||||
{
|
||||
const int digit = radix_traits<Radix>::digit(ch);
|
||||
n = n * T(Radix) - T(digit);
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline static bool add(T& n, Char ch, mpl::true_) // checked subtract
|
||||
{
|
||||
// Ensure n *= Radix will not underflow
|
||||
typedef constexpr_int<T, boost::integer_traits<T>::const_min> min;
|
||||
typedef constexpr_int<T, (min::value + 1) / T(Radix)> val;
|
||||
|
||||
if (n < val::value)
|
||||
return false;
|
||||
|
||||
n *= Radix;
|
||||
|
||||
// Ensure n -= digit will not underflow
|
||||
int const digit = radix_traits<Radix>::digit(ch);
|
||||
if (n < min::value + digit)
|
||||
return false;
|
||||
|
||||
n -= static_cast<T>(digit);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Common code for extract_int::parse specializations
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <unsigned Radix, typename Accumulator, int MaxDigits, bool AlwaysCheckOverflow>
|
||||
struct int_extractor
|
||||
{
|
||||
template <typename Char, typename T>
|
||||
inline static bool
|
||||
call(Char ch, std::size_t count, T& n, mpl::true_)
|
||||
{
|
||||
typedef constexpr_int<std::size_t, digits_traits<T, Radix>::value - 1> overflow_free;
|
||||
|
||||
if (!AlwaysCheckOverflow && (count < overflow_free::value))
|
||||
{
|
||||
Accumulator::add(n, ch, mpl::false_());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Accumulator::add(n, ch, mpl::true_()))
|
||||
return false; // over/underflow!
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
inline static bool
|
||||
call(Char ch, std::size_t /*count*/, T& n, mpl::false_)
|
||||
{
|
||||
// no need to check for overflow
|
||||
Accumulator::add(n, ch, mpl::false_());
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline static bool
|
||||
call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
inline static bool
|
||||
call(Char ch, std::size_t count, T& n)
|
||||
{
|
||||
return call(ch, count, n
|
||||
, mpl::bool_<
|
||||
( (MaxDigits < 0)
|
||||
|| (MaxDigits > digits_traits<T, Radix>::value)
|
||||
)
|
||||
&& traits::check_overflow<T>::value
|
||||
>()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// End of loop checking: check if the number of digits
|
||||
// being parsed exceeds MaxDigits. Note: if MaxDigits == -1
|
||||
// we don't do any checking.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <int MaxDigits>
|
||||
struct check_max_digits
|
||||
{
|
||||
inline static bool
|
||||
call(std::size_t count)
|
||||
{
|
||||
return count < MaxDigits; // bounded
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct check_max_digits<-1>
|
||||
{
|
||||
inline static bool
|
||||
call(std::size_t /*count*/)
|
||||
{
|
||||
return true; // unbounded
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// extract_int: main code for extracting integers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
|
||||
if (!check_max_digits<MaxDigits>::call(count + leading_zeros) \
|
||||
|| it == last) \
|
||||
break; \
|
||||
ch = *it; \
|
||||
if (!radix_check::is_valid(ch)) \
|
||||
break; \
|
||||
if (!extractor::call(ch, count, val)) \
|
||||
{ \
|
||||
if (IgnoreOverflowDigits) \
|
||||
first = it; \
|
||||
traits::assign_to(val, attr); \
|
||||
return IgnoreOverflowDigits; \
|
||||
} \
|
||||
++it; \
|
||||
++count; \
|
||||
/**/
|
||||
|
||||
template <
|
||||
typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename Accumulator = positive_accumulator<Radix>
|
||||
, bool Accumulate = false
|
||||
, bool IgnoreOverflowDigits = false
|
||||
>
|
||||
struct extract_int
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool
|
||||
parse_main(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
typedef radix_traits<Radix> radix_check;
|
||||
typedef int_extractor<Radix, Accumulator, MaxDigits, Accumulate> extractor;
|
||||
typedef typename
|
||||
boost::detail::iterator_traits<Iterator>::value_type
|
||||
char_type;
|
||||
|
||||
Iterator it = first;
|
||||
std::size_t leading_zeros = 0;
|
||||
if (!Accumulate)
|
||||
{
|
||||
// skip leading zeros
|
||||
while (it != last && *it == '0' && (MaxDigits < 0 || leading_zeros < static_cast< std::size_t >(MaxDigits)))
|
||||
{
|
||||
++it;
|
||||
++leading_zeros;
|
||||
}
|
||||
}
|
||||
|
||||
typedef typename
|
||||
traits::attribute_type<Attribute>::type
|
||||
attribute_type;
|
||||
|
||||
attribute_type val = Accumulate ? attr : attribute_type(0);
|
||||
std::size_t count = 0;
|
||||
char_type ch;
|
||||
|
||||
while (true)
|
||||
{
|
||||
BOOST_PP_REPEAT(
|
||||
SPIRIT_NUMERICS_LOOP_UNROLL
|
||||
, SPIRIT_NUMERIC_INNER_LOOP, _)
|
||||
}
|
||||
|
||||
if (count + leading_zeros >= MinDigits)
|
||||
{
|
||||
traits::assign_to(val, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
inline static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, unused_type)
|
||||
{
|
||||
T n = 0; // must calculate value to detect over/underflow
|
||||
return parse_main(first, last, n);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
return parse_main(first, last, attr);
|
||||
}
|
||||
};
|
||||
#undef SPIRIT_NUMERIC_INNER_LOOP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// extract_int: main code for extracting integers
|
||||
// common case where MinDigits == 1 and MaxDigits = -1
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
|
||||
if (it == last) \
|
||||
break; \
|
||||
ch = *it; \
|
||||
if (!radix_check::is_valid(ch)) \
|
||||
break; \
|
||||
if (!extractor::call(ch, count, val)) \
|
||||
{ \
|
||||
traits::assign_to(val, attr); \
|
||||
return false; \
|
||||
} \
|
||||
++it; \
|
||||
++count; \
|
||||
/**/
|
||||
|
||||
template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
|
||||
struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool
|
||||
parse_main(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
typedef radix_traits<Radix> radix_check;
|
||||
typedef int_extractor<Radix, Accumulator, -1, Accumulate> extractor;
|
||||
typedef typename
|
||||
boost::detail::iterator_traits<Iterator>::value_type
|
||||
char_type;
|
||||
|
||||
Iterator it = first;
|
||||
std::size_t count = 0;
|
||||
if (!Accumulate)
|
||||
{
|
||||
// skip leading zeros
|
||||
while (it != last && *it == '0')
|
||||
{
|
||||
++it;
|
||||
++count;
|
||||
}
|
||||
|
||||
if (it == last)
|
||||
{
|
||||
if (count == 0) // must have at least one digit
|
||||
return false;
|
||||
traits::assign_to(0, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
typedef typename
|
||||
traits::attribute_type<Attribute>::type
|
||||
attribute_type;
|
||||
|
||||
attribute_type val = Accumulate ? attr : attribute_type(0);
|
||||
char_type ch = *it;
|
||||
|
||||
if (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))
|
||||
{
|
||||
if (count == 0) // must have at least one digit
|
||||
return false;
|
||||
traits::assign_to(val, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
|
||||
// count = 0; $$$ verify: I think this is wrong $$$
|
||||
++it;
|
||||
while (true)
|
||||
{
|
||||
BOOST_PP_REPEAT(
|
||||
SPIRIT_NUMERICS_LOOP_UNROLL
|
||||
, SPIRIT_NUMERIC_INNER_LOOP, _)
|
||||
}
|
||||
|
||||
traits::assign_to(val, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
inline static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, unused_type)
|
||||
{
|
||||
T n = 0; // must calculate value to detect over/underflow
|
||||
return parse_main(first, last, n);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
return parse_main(first, last, attr);
|
||||
}
|
||||
};
|
||||
|
||||
#undef SPIRIT_NUMERIC_INNER_LOOP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Cast an signed integer to an unsigned integer
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T,
|
||||
bool force_unsigned
|
||||
= mpl::and_<is_integral<T>, is_signed<T> >::value>
|
||||
struct cast_unsigned;
|
||||
|
||||
template <typename T>
|
||||
struct cast_unsigned<T, true>
|
||||
{
|
||||
typedef typename make_unsigned<T>::type unsigned_type;
|
||||
typedef typename make_unsigned<T>::type& unsigned_type_ref;
|
||||
|
||||
inline static unsigned_type_ref call(T& n)
|
||||
{
|
||||
return unsigned_type_ref(n);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct cast_unsigned<T, false>
|
||||
{
|
||||
inline static T& call(T& n)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
};
|
||||
}}}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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_IMPL_APRIL_18_2006_0901AM)
|
||||
#define SPIRIT_REAL_IMPL_APRIL_18_2006_0901AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/detail/pow10.hpp>
|
||||
#include <boost/spirit/home/support/detail/sign.hpp>
|
||||
#include <boost/integer.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
using spirit::traits::pow10;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename T, typename AccT>
|
||||
void compensate_roundoff(T& n, AccT acc_n, mpl::true_)
|
||||
{
|
||||
// at the lowest extremes, we compensate for floating point
|
||||
// roundoff errors by doing imprecise computation using T
|
||||
int const comp = 10;
|
||||
n = T((acc_n / comp) * comp);
|
||||
n += T(acc_n % comp);
|
||||
}
|
||||
|
||||
template <typename T, typename AccT>
|
||||
void compensate_roundoff(T& n, AccT acc_n, mpl::false_)
|
||||
{
|
||||
// no need to compensate
|
||||
n = acc_n;
|
||||
}
|
||||
|
||||
template <typename T, typename AccT>
|
||||
void compensate_roundoff(T& n, AccT acc_n)
|
||||
{
|
||||
compensate_roundoff(n, acc_n, is_integral<AccT>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename AccT>
|
||||
inline bool
|
||||
scale(int exp, T& n, AccT acc_n)
|
||||
{
|
||||
if (exp >= 0)
|
||||
{
|
||||
int max_exp = std::numeric_limits<T>::max_exponent10;
|
||||
|
||||
// return false if exp exceeds the max_exp
|
||||
// do this check only for primitive types!
|
||||
if (is_floating_point<T>() && exp > max_exp)
|
||||
return false;
|
||||
n = acc_n * pow10<T>(exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (exp < std::numeric_limits<T>::min_exponent10)
|
||||
{
|
||||
int min_exp = std::numeric_limits<T>::min_exponent10;
|
||||
detail::compensate_roundoff(n, acc_n);
|
||||
n /= pow10<T>(-min_exp);
|
||||
|
||||
// return false if (-exp + min_exp) exceeds the -min_exp
|
||||
// do this check only for primitive types!
|
||||
if (is_floating_point<T>() && (-exp + min_exp) > -min_exp)
|
||||
return false;
|
||||
|
||||
n /= pow10<T>(-exp + min_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = T(acc_n) / pow10<T>(-exp);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
scale(int /*exp*/, unused_type /*n*/, unused_type /*acc_n*/)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename AccT>
|
||||
inline bool
|
||||
scale(int exp, int frac, T& n, AccT acc_n)
|
||||
{
|
||||
return scale(exp - frac, n, acc_n);
|
||||
}
|
||||
|
||||
inline bool
|
||||
scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return true;
|
||||
}
|
||||
|
||||
inline float
|
||||
negate(bool neg, float n)
|
||||
{
|
||||
return neg ? spirit::detail::changesign(n) : n;
|
||||
}
|
||||
|
||||
inline double
|
||||
negate(bool neg, double n)
|
||||
{
|
||||
return neg ? spirit::detail::changesign(n) : n;
|
||||
}
|
||||
|
||||
inline long double
|
||||
negate(bool neg, long double n)
|
||||
{
|
||||
return neg ? spirit::detail::changesign(n) : n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T
|
||||
negate(bool neg, T const& n)
|
||||
{
|
||||
return neg ? -n : n;
|
||||
}
|
||||
|
||||
inline unused_type
|
||||
negate(bool /*neg*/, unused_type n)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
is_equal_to_one(T const& value)
|
||||
{
|
||||
return value == 1.0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
is_equal_to_one(unused_type)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct real_accumulator : mpl::identity<T> {};
|
||||
|
||||
template <>
|
||||
struct real_accumulator<float>
|
||||
: mpl::identity<uint_t<(sizeof(float)*CHAR_BIT)>::least> {};
|
||||
|
||||
template <>
|
||||
struct real_accumulator<double>
|
||||
: mpl::identity<uint_t<(sizeof(double)*CHAR_BIT)>::least> {};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename T, typename RealPolicies>
|
||||
struct real_impl
|
||||
{
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse(Iterator& first, Iterator const& last, Attribute& attr,
|
||||
RealPolicies const& p)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
Iterator save = first;
|
||||
|
||||
// Start by parsing the sign. neg will be true if
|
||||
// we got a "-" sign, false otherwise.
|
||||
bool neg = p.parse_sign(first, last);
|
||||
|
||||
// Now attempt to parse an integer
|
||||
T n;
|
||||
|
||||
typename traits::real_accumulator<T>::type acc_n = 0;
|
||||
bool got_a_number = p.parse_n(first, last, acc_n);
|
||||
|
||||
// If we did not get a number it might be a NaN, Inf or a leading
|
||||
// dot.
|
||||
if (!got_a_number)
|
||||
{
|
||||
// Check whether the number to parse is a NaN or Inf
|
||||
if (p.parse_nan(first, last, n) ||
|
||||
p.parse_inf(first, last, n))
|
||||
{
|
||||
// If we got a negative sign, negate the number
|
||||
traits::assign_to(traits::negate(neg, n), attr);
|
||||
return true; // got a NaN or Inf, return early
|
||||
}
|
||||
|
||||
// If we did not get a number and our policies do not
|
||||
// allow a leading dot, fail and return early (no-match)
|
||||
if (!p.allow_leading_dot)
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool e_hit = false;
|
||||
Iterator e_pos;
|
||||
int frac_digits = 0;
|
||||
|
||||
// Try to parse the dot ('.' decimal point)
|
||||
if (p.parse_dot(first, last))
|
||||
{
|
||||
// We got the decimal point. Now we will try to parse
|
||||
// the fraction if it is there. If not, it defaults
|
||||
// to zero (0) only if we already got a number.
|
||||
if (p.parse_frac_n(first, last, acc_n, frac_digits))
|
||||
{
|
||||
}
|
||||
else if (!got_a_number || !p.allow_trailing_dot)
|
||||
{
|
||||
// We did not get a fraction. If we still haven't got a
|
||||
// number and our policies do not allow a trailing dot,
|
||||
// return no-match.
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now, let's see if we can parse the exponent prefix
|
||||
e_pos = first;
|
||||
e_hit = p.parse_exp(first, last);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No dot and no number! Return no-match.
|
||||
if (!got_a_number)
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we must expect a dot and we didn't see an exponent
|
||||
// prefix, return no-match.
|
||||
e_pos = first;
|
||||
e_hit = p.parse_exp(first, last);
|
||||
if (p.expect_dot && !e_hit)
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (e_hit)
|
||||
{
|
||||
// We got the exponent prefix. Now we will try to parse the
|
||||
// actual exponent.
|
||||
int exp = 0;
|
||||
if (p.parse_exp_n(first, last, exp))
|
||||
{
|
||||
// Got the exponent value. Scale the number by
|
||||
// exp-frac_digits.
|
||||
if (!traits::scale(exp, frac_digits, n, acc_n))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there is no number, disregard the exponent altogether.
|
||||
// by resetting 'first' prior to the exponent prefix (e|E)
|
||||
first = e_pos;
|
||||
n = static_cast<T>(acc_n);
|
||||
}
|
||||
}
|
||||
else if (frac_digits)
|
||||
{
|
||||
// No exponent found. Scale the number by -frac_digits.
|
||||
traits::scale(-frac_digits, n, acc_n);
|
||||
}
|
||||
else if (traits::is_equal_to_one(acc_n))
|
||||
{
|
||||
// There is a chance of having to parse one of the 1.0#...
|
||||
// styles some implementations use for representing NaN or Inf.
|
||||
|
||||
// Check whether the number to parse is a NaN or Inf
|
||||
if (p.parse_nan(first, last, n) ||
|
||||
p.parse_inf(first, last, n))
|
||||
{
|
||||
// If we got a negative sign, negate the number
|
||||
traits::assign_to(traits::negate(neg, n), attr);
|
||||
return true; // got a NaN or Inf, return immediately
|
||||
}
|
||||
|
||||
n = static_cast<T>(acc_n);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = static_cast<T>(acc_n);
|
||||
}
|
||||
|
||||
// If we got a negative sign, negate the number
|
||||
traits::assign_to(traits::negate(neg, n), attr);
|
||||
|
||||
// Success!!!
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,411 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2011 Bryce Lelbach
|
||||
|
||||
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_INT_APR_17_2006_0830AM)
|
||||
#define BOOST_SPIRIT_INT_APR_17_2006_0830AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace tag
|
||||
{
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct int_parser
|
||||
{
|
||||
BOOST_SPIRIT_IS_TAG()
|
||||
};
|
||||
}
|
||||
|
||||
namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This one is the class that the user can instantiate directly in
|
||||
// order to create a customized int parser
|
||||
template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct int_parser
|
||||
: spirit::terminal<tag::int_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_enable_short
|
||||
template <> // enables short_
|
||||
struct use_terminal<qi::domain, tag::short_> : mpl::true_ {};
|
||||
//]
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, signed short> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables short_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::short_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* short_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::short_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_enable_int
|
||||
template <> // enables int_
|
||||
struct use_terminal<qi::domain, tag::int_> : mpl::true_ {};
|
||||
//]
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, signed> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables int_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::int_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* int_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::int_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_enable_long
|
||||
template <> // enables long_
|
||||
struct use_terminal<qi::domain, tag::long_> : mpl::true_ {};
|
||||
//]
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, signed long> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables long_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::long_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* long_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::long_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
//[primitive_parsers_enable_long_long
|
||||
template <> // enables long_long
|
||||
struct use_terminal<qi::domain, tag::long_long> : mpl::true_ {};
|
||||
//]
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, boost::long_long_type> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables long_long(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::long_long, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* long_long(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::long_long, 1> : mpl::true_ {};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables any custom int_parser
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::int_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables any custom int_parser(n)
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
// enables *lazy* custom int_parser(n)
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct use_lazy_terminal<qi::domain
|
||||
, tag::int_parser<T, Radix, MinDigits, MaxDigits>, 1
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::short_;
|
||||
using spirit::int_;
|
||||
using spirit::long_;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using spirit::long_long;
|
||||
#endif
|
||||
using spirit::lit; // lit(1) is equivalent to 1
|
||||
#endif
|
||||
using spirit::short_type;
|
||||
using spirit::int_type;
|
||||
using spirit::long_type;
|
||||
using spirit::lit_type;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using spirit::long_long_type;
|
||||
#endif
|
||||
using spirit::lit_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is the actual int parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_int_parser
|
||||
template <
|
||||
typename T
|
||||
, unsigned Radix = 10
|
||||
, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct any_int_parser
|
||||
: primitive_parser<any_int_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::call(first, last, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("integer");
|
||||
}
|
||||
};
|
||||
//]
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1, bool no_attribute = true>
|
||||
struct literal_int_parser
|
||||
: primitive_parser<literal_int_parser<T, Radix, MinDigits, MaxDigits
|
||||
, no_attribute> >
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Value>
|
||||
literal_int_parser(Value const& n) : n_(n) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_c<no_attribute, unused_type, T>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
Iterator save = first;
|
||||
T attr_;
|
||||
|
||||
if (extract::call(first, last, attr_) && (attr_ == n_))
|
||||
{
|
||||
traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("integer");
|
||||
}
|
||||
|
||||
T n_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_make_int
|
||||
template <
|
||||
typename T
|
||||
, unsigned Radix = 10
|
||||
, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_int
|
||||
{
|
||||
typedef any_int_parser<T, Radix, MinDigits, MaxDigits> result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
//]
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_direct_int
|
||||
{
|
||||
typedef literal_int_parser<T, Radix, MinDigits, MaxDigits, false>
|
||||
result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_literal_int
|
||||
{
|
||||
typedef literal_int_parser<T, Radix, MinDigits, MaxDigits> result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, signed short> >::type>
|
||||
: make_literal_int<signed short> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, signed> >::type>
|
||||
: make_literal_int<signed> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, signed long> >::type>
|
||||
: make_literal_int<signed long> {};
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, boost::long_long_type> >::type>
|
||||
: make_literal_int<boost::long_long_type> {};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::int_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, Modifiers>
|
||||
: make_int<T, Radix, MinDigits, MaxDigits> {};
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename A0, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_int<T, Radix, MinDigits, MaxDigits> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_short_primitive
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::short_, Modifiers>
|
||||
: make_int<short> {};
|
||||
//]
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::short_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_int<short> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_int_primitive
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::int_, Modifiers>
|
||||
: make_int<int> {};
|
||||
//]
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::int_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_int<int> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_long_primitive
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::long_, Modifiers>
|
||||
: make_int<long> {};
|
||||
//]
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::long_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_int<long> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
//[primitive_parsers_long_long_primitive
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::long_long, Modifiers>
|
||||
: make_int<boost::long_long_type> {};
|
||||
//]
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::long_long
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_int<boost::long_long_type> {};
|
||||
#endif
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2011 Jan Frederick Eick
|
||||
|
||||
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_NUMERIC_UTILS_APRIL_17_2006_0830AM)
|
||||
#define BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/assert_msg.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/detail/numeric_utils.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Extract the prefix sign (- or +), return true if a '-' was found
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator>
|
||||
inline bool
|
||||
extract_sign(Iterator& first, Iterator const& last)
|
||||
{
|
||||
(void)last; // silence unused warnings
|
||||
BOOST_ASSERT(first != last); // precondition
|
||||
|
||||
// Extract the sign
|
||||
bool neg = *first == '-';
|
||||
if (neg || (*first == '+'))
|
||||
{
|
||||
++first;
|
||||
return neg;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Low level unsigned integer parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, bool Accumulate = false, bool IgnoreOverflowDigits = false>
|
||||
struct extract_uint
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix >= 2 && Radix <= 36,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Iterator>
|
||||
inline static bool call(Iterator& first, Iterator const& last, T& attr_)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
typedef detail::extract_int<
|
||||
T
|
||||
, Radix
|
||||
, MinDigits
|
||||
, MaxDigits
|
||||
, detail::positive_accumulator<Radix>
|
||||
, Accumulate
|
||||
, IgnoreOverflowDigits>
|
||||
extract_type;
|
||||
|
||||
Iterator save = first;
|
||||
if (!extract_type::parse(first, last,
|
||||
detail::cast_unsigned<T>::call(attr_)))
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
// this case is called when Attribute is not T
|
||||
T attr_local;
|
||||
if (call(first, last, attr_local))
|
||||
{
|
||||
traits::assign_to(attr_local, attr_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Low level signed integer parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct extract_int
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Iterator>
|
||||
inline static bool call(Iterator& first, Iterator const& last, T& attr_)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
typedef detail::extract_int<
|
||||
T, Radix, MinDigits, MaxDigits>
|
||||
extract_pos_type;
|
||||
|
||||
typedef detail::extract_int<
|
||||
T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
|
||||
extract_neg_type;
|
||||
|
||||
Iterator save = first;
|
||||
bool hit = extract_sign(first, last);
|
||||
if (hit)
|
||||
hit = extract_neg_type::parse(first, last, attr_);
|
||||
else
|
||||
hit = extract_pos_type::parse(first, last, attr_);
|
||||
|
||||
if (!hit)
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
// this case is called when Attribute is not T
|
||||
T attr_local;
|
||||
if (call(first, last, attr_local))
|
||||
{
|
||||
traits::assign_to(attr_local, attr_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,342 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2011 Bryce Lelbach
|
||||
|
||||
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_REAL_APRIL_18_2006_0850AM)
|
||||
#define BOOST_SPIRIT_REAL_APRIL_18_2006_0850AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/real_policies.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/detail/real_impl.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// forward declaration only
|
||||
template <typename T>
|
||||
struct real_policies;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This is the class that the user can instantiate directly in
|
||||
// order to create a customized real parser
|
||||
template <typename T = double, typename Policies = real_policies<T> >
|
||||
struct real_parser
|
||||
: spirit::terminal<tag::stateful_tag<Policies, tag::double_, T> >
|
||||
{
|
||||
typedef tag::stateful_tag<Policies, tag::double_, T> tag_type;
|
||||
|
||||
real_parser() {}
|
||||
real_parser(Policies const& p)
|
||||
: spirit::terminal<tag_type>(p) {}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables float_
|
||||
struct use_terminal<qi::domain, tag::float_>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables double_
|
||||
struct use_terminal<qi::domain, tag::double_>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables long_double
|
||||
struct use_terminal<qi::domain, tag::long_double>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, float> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, double> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, long double> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables float_(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::float_, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables double_(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::double_, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables long_double(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::long_double, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* float_(...)
|
||||
struct use_lazy_terminal<qi::domain, tag::float_, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* double_(...)
|
||||
struct use_lazy_terminal<qi::domain, tag::double_, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* long_double_(...)
|
||||
struct use_lazy_terminal<qi::domain, tag::long_double, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables custom real_parser
|
||||
template <typename T, typename Policies>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::stateful_tag<Policies, tag::double_, T> >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables custom real_parser(...)
|
||||
template <typename T, typename Policies, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
|
||||
, fusion::vector1<A0> > >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables *lazy* custom real_parser(...)
|
||||
template <typename T, typename Policies>
|
||||
struct use_lazy_terminal<
|
||||
qi::domain
|
||||
, tag::stateful_tag<Policies, tag::double_, T>
|
||||
, 1 // arity
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::float_;
|
||||
using spirit::double_;
|
||||
using spirit::long_double;
|
||||
using spirit::lit; // lit(1.0) is equivalent to 1.0
|
||||
#endif
|
||||
|
||||
using spirit::float_type;
|
||||
using spirit::double_type;
|
||||
using spirit::long_double_type;
|
||||
using spirit::lit_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is the actual real number parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename RealPolicies = real_policies<T> >
|
||||
struct any_real_parser
|
||||
: primitive_parser<any_real_parser<T, RealPolicies> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, T& attr_) const
|
||||
{
|
||||
typedef detail::real_impl<T, RealPolicies> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::parse(first, last, attr_, RealPolicies());
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
// this case is called when Attribute is not T
|
||||
T attr_;
|
||||
if (parse(first, last, context, skipper, attr_))
|
||||
{
|
||||
traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("real");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename RealPolicies = real_policies<T>
|
||||
, bool no_attribute = true>
|
||||
struct literal_real_parser
|
||||
: primitive_parser<literal_real_parser<T, RealPolicies, no_attribute> >
|
||||
{
|
||||
template <typename Value>
|
||||
literal_real_parser(Value const& n) : n_(n) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_c<no_attribute, unused_type, T>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context&, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
typedef detail::real_impl<T, RealPolicies> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
Iterator save = first;
|
||||
T attr_;
|
||||
|
||||
if (extract::parse(first, last, attr_, RealPolicies()) &&
|
||||
(attr_ == n_))
|
||||
{
|
||||
traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("real");
|
||||
}
|
||||
|
||||
T n_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Policies = real_policies<T> >
|
||||
struct make_real
|
||||
{
|
||||
typedef any_real_parser<T, Policies> result_type;
|
||||
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Policies = real_policies<T> >
|
||||
struct make_direct_real
|
||||
{
|
||||
typedef literal_real_parser<T, Policies, false> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(T(fusion::at_c<0>(term.args)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Policies = real_policies<T> >
|
||||
struct make_literal_real
|
||||
{
|
||||
typedef literal_real_parser<T, Policies> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, float> >::type>
|
||||
: make_literal_real<float> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, double> >::type>
|
||||
: make_literal_real<double> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, long double> >::type>
|
||||
: make_literal_real<long double> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Policies, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::stateful_tag<Policies, tag::double_, T>, Modifiers>
|
||||
: make_real<T, Policies> {};
|
||||
|
||||
template <typename T, typename Policies, typename A0, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_real<T, Policies> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::float_, Modifiers>
|
||||
: make_real<float> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::float_
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_real<float> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::double_, Modifiers>
|
||||
: make_real<double> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::double_
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_real<double> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::long_double, Modifiers>
|
||||
: make_real<long double> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::long_double
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_real<long double> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,198 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 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<Attribute, 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_, int& frac_digits)
|
||||
{
|
||||
Iterator savef = first;
|
||||
bool r = extract_uint<Attribute, 10, 1, -1, true, true>::call(first, last, attr_);
|
||||
if (r)
|
||||
{
|
||||
// Optimization note: don't compute frac_digits if T is
|
||||
// an unused_type. This should be optimized away by the compiler.
|
||||
if (!is_same<T, unused_type>::value)
|
||||
frac_digits =
|
||||
static_cast<int>(std::distance(savef, first));
|
||||
// ignore extra (non-significant digits)
|
||||
extract_uint<unused_type, 10, 1, -1>::call(first, last, unused);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
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 != last && *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
|
||||
@@ -0,0 +1,464 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2011 Bryce Lelbach
|
||||
Copyright (c) 2011 Jan Frederick Eick
|
||||
|
||||
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_UINT_APR_17_2006_0901AM)
|
||||
#define SPIRIT_UINT_APR_17_2006_0901AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace tag
|
||||
{
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct uint_parser
|
||||
{
|
||||
BOOST_SPIRIT_IS_TAG()
|
||||
};
|
||||
}
|
||||
|
||||
namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This one is the class that the user can instantiate directly in
|
||||
// order to create a customized int parser
|
||||
template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct uint_parser
|
||||
: spirit::terminal<tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables ushort_
|
||||
struct use_terminal<qi::domain, tag::ushort_> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, unsigned short> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables ushort_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::ushort_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* ushort_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::ushort_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables uint_
|
||||
struct use_terminal<qi::domain, tag::uint_> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, unsigned> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables uint_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::uint_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* uint_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::uint_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables ulong_
|
||||
struct use_terminal<qi::domain, tag::ulong_> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, unsigned long> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables ulong_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::ulong_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* ulong_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::ulong_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <> // enables ulong_long
|
||||
struct use_terminal<qi::domain, tag::ulong_long> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables ulong_long(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::ulong_long, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* ulong_long(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::ulong_long, 1> : mpl::true_ {};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables bin
|
||||
struct use_terminal<qi::domain, tag::bin> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables bin(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::bin, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* bin(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::bin, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables oct
|
||||
struct use_terminal<qi::domain, tag::oct> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables oct(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::oct, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* oct(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::oct, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables hex
|
||||
struct use_terminal<qi::domain, tag::hex> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables hex(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::hex, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* hex(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::hex, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables any custom uint_parser
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables any custom uint_parser(n)
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
// enables *lazy* custom uint_parser(n)
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct use_lazy_terminal<qi::domain
|
||||
, tag::uint_parser<T, Radix, MinDigits, MaxDigits>, 1
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::bin;
|
||||
using spirit::oct;
|
||||
using spirit::hex;
|
||||
|
||||
using spirit::ushort_;
|
||||
using spirit::uint_;
|
||||
using spirit::ulong_;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using spirit::ulong_long;
|
||||
#endif
|
||||
using spirit::lit; // lit(1) is equivalent to 1
|
||||
#endif
|
||||
|
||||
using spirit::bin_type;
|
||||
using spirit::oct_type;
|
||||
using spirit::hex_type;
|
||||
|
||||
using spirit::ushort_type;
|
||||
using spirit::uint_type;
|
||||
using spirit::ulong_type;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using spirit::ulong_long_type;
|
||||
#endif
|
||||
using spirit::lit_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is the actual uint parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct any_uint_parser
|
||||
: primitive_parser<any_uint_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix >= 2 && Radix <= 36,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::call(first, last, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("unsigned-integer");
|
||||
}
|
||||
};
|
||||
//]
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1, bool no_attribute = true>
|
||||
struct literal_uint_parser
|
||||
: primitive_parser<literal_uint_parser<T, Radix, MinDigits, MaxDigits
|
||||
, no_attribute> >
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Value>
|
||||
literal_uint_parser(Value const& n) : n_(n) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_c<no_attribute, unused_type, T>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
Iterator save = first;
|
||||
T attr_;
|
||||
|
||||
if (extract::call(first, last, attr_) && (attr_ == n_))
|
||||
{
|
||||
traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("unsigned-integer");
|
||||
}
|
||||
|
||||
T n_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_uint
|
||||
{
|
||||
typedef any_uint_parser<T, Radix, MinDigits, MaxDigits> result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_direct_uint
|
||||
{
|
||||
typedef literal_uint_parser<T, Radix, MinDigits, MaxDigits, false>
|
||||
result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_literal_uint
|
||||
{
|
||||
typedef literal_uint_parser<T, Radix, MinDigits, MaxDigits> result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, unsigned short> >::type>
|
||||
: make_literal_uint<unsigned short> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, unsigned> >::type>
|
||||
: make_literal_uint<unsigned> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, unsigned long> >::type>
|
||||
: make_literal_uint<unsigned long> {};
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
|
||||
: make_literal_uint<boost::ulong_long_type> {};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::uint_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, Modifiers>
|
||||
: make_uint<T, Radix, MinDigits, MaxDigits> {};
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename A0, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_uint<T, Radix, MinDigits, MaxDigits> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::bin, Modifiers>
|
||||
: make_uint<unsigned, 2> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::bin
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned, 2> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::oct, Modifiers>
|
||||
: make_uint<unsigned, 8> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::oct
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned, 8> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::hex, Modifiers>
|
||||
: make_uint<unsigned, 16> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::hex
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned, 16> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::ushort_, Modifiers>
|
||||
: make_uint<unsigned short> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::ushort_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned short> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::uint_, Modifiers>
|
||||
: make_uint<unsigned> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::uint_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::ulong_, Modifiers>
|
||||
: make_uint<unsigned long> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::ulong_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned long> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::ulong_long, Modifiers>
|
||||
: make_uint<boost::ulong_long_type> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::ulong_long
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<boost::ulong_long_type> {};
|
||||
#endif
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user