stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -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
@@ -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
@@ -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