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,16 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_ACTION_JANUARY_07_2007_1233PM)
#define SPIRIT_ACTION_JANUARY_07_2007_1233PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/action/action.hpp>
#endif
@@ -0,0 +1,202 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_ACTION_JANUARY_07_2007_1128AM)
#define SPIRIT_ACTION_JANUARY_07_2007_1128AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/spirit/home/support/context.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/action_dispatch.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace qi
{
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
template <typename Subject, typename Action>
struct action : unary_parser<action<Subject, Action> >
{
typedef Subject subject_type;
typedef Action action_type;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<Subject, Context, Iterator>
{};
action(Subject const& subject_, Action f_)
: subject(subject_), f(f_) {}
#ifndef BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
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 typename attribute<Context, Iterator>::type attr_type;
typedef traits::make_attribute<attr_type, Attribute> make_attribute;
// create an attribute if one is not supplied
typedef traits::transform_attribute<
typename make_attribute::type, attr_type, domain> transform;
typename make_attribute::type made_attr = make_attribute::call(attr_);
typename transform::type attr = transform::pre(made_attr);
Iterator save = first;
if (subject.parse(first, last, context, skipper, attr))
{
// call the function, passing the attribute, the context.
// The client can return false to fail parsing.
if (traits::action_dispatch<Subject>()(f, attr, context))
{
// Do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate.
traits::post_transform(attr_, attr);
return true;
}
// reset iterators if semantic action failed the match
// retrospectively
first = save;
}
return false;
}
#else
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
Iterator save = first;
if (subject.parse(first, last, context, skipper, attr)) // Use the attribute as-is
{
// call the function, passing the attribute, the context.
// The client can return false to fail parsing.
if (traits::action_dispatch<Subject>()(f, attr, context))
return true;
// reset iterators if semantic action failed the match
// retrospectively
first = save;
}
return false;
}
template <typename Iterator, typename Context
, typename Skipper>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, unused_type) const
{
typedef typename attribute<Context, Iterator>::type attr_type;
typedef traits::make_attribute<attr_type, unused_type> make_attribute;
// synthesize the attribute since one is not supplied
typedef traits::transform_attribute<
typename make_attribute::type, attr_type, domain> transform;
typename make_attribute::type made_attr = make_attribute::call(unused_type());
typename transform::type attr = transform::pre(made_attr);
Iterator save = first;
if (subject.parse(first, last, context, skipper, attr))
{
// call the function, passing the attribute, the context.
// The client can return false to fail parsing.
if (traits::action_dispatch<Subject>()(f, attr, context))
return true;
// reset iterators if semantic action failed the match
// retrospectively
first = save;
}
return false;
}
#endif
template <typename Context>
info what(Context& context) const
{
// the action is transparent (does not add any info)
return subject.what(context);
}
Subject subject;
Action f;
private:
// silence MSVC warning C4512: assignment operator could not be generated
action& operator= (action const&);
};
}}}
namespace boost { namespace spirit
{
// Qi action meta-compiler
template <>
struct make_component<qi::domain, tag::action>
{
template <typename Sig>
struct result;
template <typename This, typename Elements, typename Modifiers>
struct result<This(Elements, Modifiers)>
{
typedef typename
remove_const<typename Elements::car_type>::type
subject_type;
typedef typename
remove_const<typename Elements::cdr_type::car_type>::type
action_type;
typedef qi::action<subject_type, action_type> type;
};
template <typename Elements>
typename result<make_component(Elements, unused_type)>::type
operator()(Elements const& elements, unused_type) const
{
typename result<make_component(Elements, unused_type)>::type
result(elements.car, elements.cdr.car);
return result;
}
};
}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Action>
struct has_semantic_action<qi::action<Subject, Action> >
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Action, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::action<Subject, Action>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,18 @@
/*=============================================================================
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(BOOST_SPIRIT_AUTO_NOV_29_2009_0335PM)
#define BOOST_SPIRIT_AUTO_NOV_29_2009_0335PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/auto/auto.hpp>
#include <boost/spirit/home/qi/detail/parse_auto.hpp>
#endif
@@ -0,0 +1,90 @@
// 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(BOOST_SPIRIT_QI_AUTO_NOV_29_2009_0336PM)
#define BOOST_SPIRIT_QI_AUTO_NOV_29_2009_0336PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/detail/hold_any.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/auto/create_parser.hpp>
#include <boost/mpl/bool.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_terminal<qi::domain, tag::auto_> // enables auto_
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::auto_;
#endif
using spirit::auto_type;
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
struct auto_parser
: parser<auto_parser<Modifiers> >
{
template <typename Context, typename Iterator>
struct attribute
{
typedef spirit::hold_any type;
};
auto_parser(Modifiers const& modifiers)
: modifiers_(modifiers) {}
template <typename Iterator, typename Context, typename Skipper
, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, Attribute& attr) const
{
return compile<qi::domain>(create_parser<Attribute>(), modifiers_)
.parse(first, last, context, skipper, attr);
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("auto_");
}
Modifiers modifiers_;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
struct make_primitive<tag::auto_, Modifiers>
{
typedef auto_parser<Modifiers> result_type;
result_type operator()(unused_type, Modifiers const& modifiers) const
{
return result_type(modifiers);
}
};
}}}
#endif
@@ -0,0 +1,45 @@
// 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(BOOST_SPIRIT_QI_CREATE_NOV_21_2009_0444PM)
#define BOOST_SPIRIT_QI_CREATE_NOV_21_2009_0444PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/auto/meta_create.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace result_of
{
template <typename T>
struct create_parser
: spirit::traits::meta_create<qi::domain, T> {};
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
// Main API function for parser creation from data type
template <typename T>
typename result_of::create_parser<T>::type
create_parser()
{
return spirit::traits::meta_create<qi::domain, T>::call();
}
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
// Meta function returning true if create_parser does return a valid
// parser for the given type T.
template <typename T>
struct create_parser_exists
: meta_create_exists<qi::domain, T> {};
}}}
#endif
@@ -0,0 +1,274 @@
// 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(BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM)
#define BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/auto/meta_create.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include <boost/config.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/fusion/include/as_vector.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// compatible STL containers
template <typename Container>
struct meta_create_container
{
typedef make_unary_proto_expr<
typename Container::value_type
, proto::tag::dereference, qi::domain
> make_proto_expr;
typedef typename make_proto_expr::type type;
static type call()
{
return make_proto_expr::call();
}
};
///////////////////////////////////////////////////////////////////////////
// Fusion sequences
template <typename Sequence>
struct meta_create_sequence
{
// create a mpl sequence from the given fusion sequence
typedef typename mpl::fold<
typename fusion::result_of::as_vector<Sequence>::type
, mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
>::type sequence_type;
typedef make_nary_proto_expr<
sequence_type, proto::tag::shift_right, qi::domain
> make_proto_expr;
typedef typename make_proto_expr::type type;
static type call()
{
return make_proto_expr::call();
}
};
///////////////////////////////////////////////////////////////////////////
// the default is to use the standard streaming operator unless it's a
// STL container or a fusion sequence
// The default implementation will be chosen if no predefined mapping of
// the data type T to a Qi component is defined.
struct no_auto_mapping_exists {};
template <typename T, typename Enable = void>
struct meta_create_impl : mpl::identity<no_auto_mapping_exists> {};
template <typename T>
struct meta_create_impl<T
, typename enable_if<mpl::and_<
traits::is_container<T>, mpl::not_<traits::is_string<T> > >
>::type>
: meta_create_container<T> {};
template <typename T>
struct meta_create_impl<T, typename enable_if<
spirit::detail::is_fusion_sequence_but_not_proto_expr<T>
>::type>
: meta_create_sequence<T> {};
template <typename T, typename Enable = void>
struct meta_create : meta_create_impl<T> {};
///////////////////////////////////////////////////////////////////////////
// optional
template <typename T>
struct meta_create<boost::optional<T> >
{
typedef make_unary_proto_expr<
T, proto::tag::negate, qi::domain
> make_proto_expr;
typedef typename make_proto_expr::type type;
static type call()
{
return make_proto_expr::call();
}
};
///////////////////////////////////////////////////////////////////////////
// alternatives
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
typedef make_nary_proto_expr<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
, proto::tag::bitwise_or, qi::domain
> make_proto_expr;
typedef typename make_proto_expr::type type;
static type call()
{
return make_proto_expr::call();
}
};
///////////////////////////////////////////////////////////////////////////
// predefined specializations for primitive components
// character generator
template <>
struct meta_create<char>
{
typedef spirit::standard::char_type type;
static type call() { return type(); }
};
template <>
struct meta_create<signed char>
{
typedef spirit::standard::char_type type;
static type call() { return type(); }
};
template <>
struct meta_create<wchar_t>
{
typedef spirit::standard_wide::char_type type;
static type call() { return type(); }
};
template <>
struct meta_create<unsigned char>
{
typedef spirit::standard::char_type type;
static type call() { return type(); }
};
// boolean generator
template <>
struct meta_create<bool>
{
typedef spirit::bool_type type;
static type call() { return type(); }
};
// integral generators
template <>
struct meta_create<int>
{
typedef spirit::int_type type;
static type call() { return type(); }
};
template <>
struct meta_create<short>
{
typedef spirit::short_type type;
static type call() { return type(); }
};
template <>
struct meta_create<long>
{
typedef spirit::long_type type;
static type call() { return type(); }
};
template <>
struct meta_create<unsigned int>
{
typedef spirit::uint_type type;
static type call() { return type(); }
};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <>
struct meta_create<unsigned short>
{
typedef spirit::ushort_type type;
static type call() { return type(); }
};
#endif
template <>
struct meta_create<unsigned long>
{
typedef spirit::ulong_type type;
static type call() { return type(); }
};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct meta_create<boost::long_long_type>
{
typedef spirit::long_long_type type;
static type call() { return type(); }
};
template <>
struct meta_create<boost::ulong_long_type>
{
typedef spirit::ulong_long_type type;
static type call() { return type(); }
};
#endif
// floating point generators
template <>
struct meta_create<float>
{
typedef spirit::float_type type;
static type call() { return type(); }
};
template <>
struct meta_create<double>
{
typedef spirit::double_type type;
static type call() { return type(); }
};
template <>
struct meta_create<long double>
{
typedef spirit::long_double_type type;
static type call() { return type(); }
};
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// main customization point for create_parser
template <typename T, typename Enable = void>
struct create_parser : qi::meta_create<T> {};
///////////////////////////////////////////////////////////////////////////
// dispatch this to the Qi related specializations
template <typename T>
struct meta_create<qi::domain, T>
: create_parser<typename spirit::detail::remove_const_ref<T>::type> {};
///////////////////////////////////////////////////////////////////////////
// Check whether a valid mapping exits for the given data type to a Qi
// component
template <typename T>
struct meta_create_exists<qi::domain, T>
: mpl::not_<is_same<
qi::no_auto_mapping_exists
, typename meta_create<qi::domain, T>::type
> > {};
}}}
#endif
@@ -0,0 +1,22 @@
/*=============================================================================
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(BOOST_SPIRIT_AUXILIARY_FEBRUARY_03_2007_0355PM)
#define BOOST_SPIRIT_AUXILIARY_FEBRUARY_03_2007_0355PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/auxiliary/eps.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/qi/auxiliary/eol.hpp>
#include <boost/spirit/home/qi/auxiliary/eoi.hpp>
#include <boost/spirit/home/qi/auxiliary/attr.hpp>
#include <boost/spirit/home/qi/auxiliary/attr_cast.hpp>
#endif
@@ -0,0 +1,110 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
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_ATTR_JUL_23_2008_0956AM)
#define BOOST_SPIRIT_ATTR_JUL_23_2008_0956AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_const.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <typename A0> // enables attr()
struct use_terminal<
qi::domain, terminal_ex<tag::attr, fusion::vector1<A0> > >
: mpl::true_ {};
template <> // enables *lazy* attr()
struct use_lazy_terminal<qi::domain, tag::attr, 1>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::attr;
#endif
using spirit::attr_type;
template <typename Value>
struct attr_parser : primitive_parser<attr_parser<Value> >
{
template <typename Context, typename Iterator>
struct attribute : remove_const<Value> {};
attr_parser(typename add_reference<Value>::type value)
: value_(value) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& /*first*/, Iterator const& /*last*/
, Context& /*context*/, Skipper const& /*skipper*/
, Attribute& attr_) const
{
spirit::traits::assign_to(value_, attr_);
return true; // never consume any input, succeed always
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("attr");
}
Value value_;
private:
// silence MSVC warning C4512: assignment operator could not be generated
attr_parser& operator= (attr_parser const&);
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<tag::attr, fusion::vector1<A0> >
, Modifiers>
{
typedef typename add_const<A0>::type const_value;
typedef attr_parser<const_value> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(fusion::at_c<0>(term.args));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Attr, typename Context, typename Iterator>
struct handles_container<qi::attr_parser<T>, Attr, Context, Iterator>
: traits::is_container<Attr> {};
}}}
#endif
@@ -0,0 +1,145 @@
// 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_ATTR_CAST_SEP_26_2009_0735PM)
#define SPIRIT_QI_ATTR_CAST_SEP_26_2009_0735PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/auxiliary/attr_cast.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables attr_cast<>() pseudo parser
template <typename Expr, typename Exposed, typename Transformed>
struct use_terminal<qi::domain
, tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed> >
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
using spirit::attr_cast;
///////////////////////////////////////////////////////////////////////////
// attr_cast_parser consumes the attribute of subject generator without
// generating anything
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed, typename Subject>
struct attr_cast_parser
: unary_parser<attr_cast_parser<Exposed, Transformed, Subject> >
{
typedef typename result_of::compile<qi::domain, Subject>::type
subject_type;
typedef typename mpl::eval_if<
traits::not_is_unused<Transformed>
, mpl::identity<Transformed>
, traits::attribute_of<subject_type> >::type
transformed_attribute_type;
attr_cast_parser(Subject const& subject_)
: subject(subject_)
{
// If you got an error_invalid_expression error message here,
// then the expression (Subject) is not a valid spirit qi
// expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Subject);
}
// If Exposed is given, we use the given type, otherwise all we can do
// is to guess, so we expose our inner type as an attribute and
// deal with the passed attribute inside the parse function.
template <typename Context, typename Iterator>
struct attribute
: mpl::if_<traits::not_is_unused<Exposed>, Exposed
, transformed_attribute_type>
{};
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
{
// Find the real exposed attribute. If exposed is given, we use it
// otherwise we assume the exposed attribute type to be the actual
// attribute type as passed by the user.
typedef typename mpl::if_<
traits::not_is_unused<Exposed>, Exposed, Attribute>::type
exposed_attribute_type;
// do down-stream transformation, provides attribute for embedded
// parser
typedef traits::transform_attribute<
exposed_attribute_type, transformed_attribute_type, domain>
transform;
typename transform::type attr_ = transform::pre(attr_param);
if (!compile<qi::domain>(subject).
parse(first, last, context, skipper, attr_))
{
transform::fail(attr_param);
return false;
}
// do up-stream transformation, this mainly integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr_param, attr_);
return true;
}
template <typename Context>
info what(Context& context) const
{
return info("attr_cast"
, compile<qi::domain>(subject).what(context));
}
Subject subject;
private:
// silence MSVC warning C4512: assignment operator could not be generated
attr_cast_parser& operator= (attr_cast_parser const&);
};
///////////////////////////////////////////////////////////////////////////
// Parser generator: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Exposed, typename Transformed
, typename Modifiers>
struct make_primitive<
tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed>, Modifiers>
{
typedef attr_cast_parser<Exposed, Transformed, Expr> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
typedef tag::stateful_tag<
Expr, tag::attr_cast, Exposed, Transformed> tag_type;
using spirit::detail::get_stateful_data;
return result_type(get_stateful_data<tag_type>::call(term));
}
};
}}}
#endif
@@ -0,0 +1,80 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
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_EOI_APRIL_18_2008_0751PM)
#define BOOST_SPIRIT_EOI_APRIL_18_2008_0751PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_terminal<qi::domain, tag::eoi> // enables eoi
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::eoi;
#endif
using spirit::eoi_type;
struct eoi_parser : primitive_parser<eoi_parser>
{
template <typename Context, typename Iterator>
struct attribute
{
typedef unused_type 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
{
qi::skip_over(first, last, skipper);
return first == last;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("eoi");
}
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
struct make_primitive<tag::eoi, Modifiers>
{
typedef eoi_parser result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
}}}
#endif
@@ -0,0 +1,98 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
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_EOL_APRIL_18_2008_0751PM)
#define BOOST_SPIRIT_EOL_APRIL_18_2008_0751PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_terminal<qi::domain, tag::eol> // enables eol
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::eol;
#endif
using spirit::eol_type;
struct eol_parser : primitive_parser<eol_parser>
{
template <typename Context, typename Iterator>
struct attribute
{
typedef unused_type 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
{
qi::skip_over(first, last, skipper);
Iterator it = first;
bool matched = false;
if (it != last && *it == '\r') // CR
{
matched = true;
++it;
}
if (it != last && *it == '\n') // LF
{
matched = true;
++it;
}
if (!matched)
return false;
first = it;
return true;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("eol");
}
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
struct make_primitive<tag::eol, Modifiers>
{
typedef eol_parser result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
}}}
#endif
@@ -0,0 +1,132 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_EPS_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_EPS_MARCH_23_2007_0454PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/type_traits/is_convertible.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_terminal<qi::domain, tag::eps> // enables eps
: mpl::true_ {};
template <typename A0>
struct use_terminal<qi::domain
, terminal_ex<tag::eps, fusion::vector1<A0> > // enables eps(bool-condition)
> : is_convertible<A0, bool> {};
template <> // enables eps(f)
struct use_lazy_terminal<
qi::domain, tag::eps, 1 /*arity*/
> : mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::eps;
#endif
using spirit::eps_type;
struct eps_parser : primitive_parser<eps_parser>
{
template <typename Context, typename Iterator>
struct attribute
{
typedef unused_type 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
{
qi::skip_over(first, last, skipper);
return true;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("eps");
}
};
struct semantic_predicate : primitive_parser<semantic_predicate>
{
template <typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
semantic_predicate(bool predicate_)
: predicate(predicate_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& /*attr*/) const
{
qi::skip_over(first, last, skipper);
return predicate;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("semantic-predicate");
}
bool predicate;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
struct make_primitive<tag::eps, Modifiers>
{
typedef eps_parser result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
template <typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<tag::eps, fusion::vector1<A0> >
, Modifiers>
{
typedef semantic_predicate result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(fusion::at_c<0>(term.args) ? true : false);
}
};
}}}
#endif
@@ -0,0 +1,287 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_LAZY_MARCH_27_2007_1002AM)
#define BOOST_SPIRIT_LAZY_MARCH_27_2007_1002AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/lazy.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/not.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <typename Eval>
struct use_terminal<qi::domain, phoenix::actor<Eval> > // enables phoenix actors
: mpl::true_ {};
// forward declaration
template <typename Terminal, typename Actor, int Arity>
struct lazy_terminal;
}}
namespace boost { namespace spirit { namespace qi
{
using spirit::lazy;
typedef modify<qi::domain> qi_modify;
namespace detail
{
template <typename Parser, typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool lazy_parse_impl(Parser const& p
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr, mpl::false_)
{
return p.parse(first, last, context, skipper, attr);
}
template <typename Parser, typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool lazy_parse_impl(Parser const& p
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& /*attr*/, mpl::true_)
{
// If DeducedAuto is false (semantic actions is present), the
// component's attribute is unused.
return p.parse(first, last, context, skipper, unused);
}
template <typename Parser, typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool lazy_parse_impl_main(Parser const& p
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
// If DeducedAuto is true (no semantic action), we pass the parser's
// attribute on to the component.
typedef typename traits::has_semantic_action<Parser>::type auto_rule;
return lazy_parse_impl(p, first, last, context, skipper, attr, auto_rule());
}
}
template <typename Function, typename Modifiers>
struct lazy_parser : parser<lazy_parser<Function, Modifiers> >
{
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
boost::result_of<qi_modify(tag::lazy_eval, Modifiers)>::type
modifier;
typedef typename
remove_reference<
typename boost::result_of<Function(unused_type, Context)>::type
>::type
expr_type;
// If you got an error_invalid_expression error message here,
// then the expression (expr_type) is not a valid spirit qi
// expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, expr_type);
typedef typename
result_of::compile<qi::domain, expr_type, modifier>::type
parser_type;
typedef typename
traits::attribute_of<parser_type, Context, Iterator>::type
type;
};
lazy_parser(Function const& function_, Modifiers const& modifiers_)
: function(function_), modifiers(modifiers_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
return detail::lazy_parse_impl_main(
compile<qi::domain>(function(unused, context)
, qi_modify()(tag::lazy_eval(), modifiers))
, first, last, context, skipper, attr);
}
template <typename Context>
info what(Context& context) const
{
return info("lazy"
, compile<qi::domain>(function(unused, context)
, qi_modify()(tag::lazy_eval(), modifiers))
.what(context)
);
}
Function function;
Modifiers modifiers;
};
template <typename Function, typename Subject, typename Modifiers>
struct lazy_directive
: unary_parser<lazy_directive<Function, Subject, Modifiers> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
boost::result_of<qi_modify(tag::lazy_eval, Modifiers)>::type
modifier;
typedef typename
remove_reference<
typename boost::result_of<Function(unused_type, Context)>::type
>::type
directive_expr_type;
typedef typename
proto::result_of::make_expr<
proto::tag::subscript
, directive_expr_type
, Subject
>::type
expr_type;
// If you got an error_invalid_expression error message here,
// then the expression (expr_type) is not a valid spirit qi
// expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, expr_type);
typedef typename
result_of::compile<qi::domain, expr_type, modifier>::type
parser_type;
typedef typename
traits::attribute_of<parser_type, Context, Iterator>::type
type;
};
lazy_directive(
Function const& function_
, Subject const& subject_
, Modifiers const& modifiers_)
: function(function_), subject(subject_), modifiers(modifiers_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
return detail::lazy_parse_impl_main(compile<qi::domain>(
proto::make_expr<proto::tag::subscript>(
function(unused, context)
, subject)
, qi_modify()(tag::lazy_eval(), modifiers))
, first, last, context, skipper, attr);
}
template <typename Context>
info what(Context& context) const
{
return info("lazy-directive"
, compile<qi::domain>(
proto::make_expr<proto::tag::subscript>(
function(unused, context)
, subject
), qi_modify()(tag::lazy_eval(), modifiers))
.what(context)
);
}
Function function;
Subject subject;
Modifiers modifiers;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Eval, typename Modifiers>
struct make_primitive<phoenix::actor<Eval>, Modifiers>
{
typedef lazy_parser<phoenix::actor<Eval>, Modifiers> result_type;
result_type operator()(phoenix::actor<Eval> const& f
, Modifiers const& modifiers) const
{
return result_type(f, modifiers);
}
};
template <typename Terminal, typename Actor, int Arity, typename Modifiers>
struct make_primitive<lazy_terminal<Terminal, Actor, Arity>, Modifiers>
{
typedef lazy_parser<Actor, Modifiers> result_type;
result_type operator()(
lazy_terminal<Terminal, Actor, Arity> const& lt
, Modifiers const& modifiers) const
{
return result_type(lt.actor, modifiers);
}
};
template <typename Terminal, typename Actor, int Arity, typename Subject, typename Modifiers>
struct make_directive<lazy_terminal<Terminal, Actor, Arity>, Subject, Modifiers>
{
typedef lazy_directive<Actor, Subject, Modifiers> result_type;
result_type operator()(
lazy_terminal<Terminal, Actor, Arity> const& lt
, Subject const& subject, Modifiers const& modifiers) const
{
return result_type(lt.actor, subject, modifiers);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Actor, typename Modifiers, typename Attribute
, typename Context, typename Iterator>
struct handles_container<
qi::lazy_parser<Actor, Modifiers>, Attribute, Context, Iterator>
: handles_container<
typename qi::lazy_parser<Actor, Modifiers>::template
attribute<Context, Iterator>::parser_type
, Attribute, Context, Iterator>
{};
template <typename Subject, typename Actor, typename Modifiers
, typename Attribute, typename Context, typename Iterator>
struct handles_container<
qi::lazy_directive<Actor, Subject, Modifiers>, Attribute
, Context, Iterator>
: handles_container<
typename qi::lazy_directive<Actor, Subject, Modifiers>::template
attribute<Context, Iterator>::parser_type
, Attribute, Context, Iterator>
{};
}}}
#endif
@@ -0,0 +1,16 @@
/*=============================================================================
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(BOOST_SPIRIT_BINARY_MAY_08_2007_0906AM)
#define BOOST_SPIRIT_BINARY_MAY_08_2007_0906AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/binary/binary.hpp>
#endif
@@ -0,0 +1,413 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
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_BINARY_MAY_08_2007_0808AM)
#define BOOST_SPIRIT_BINARY_MAY_08_2007_0808AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/detail/endian.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/config.hpp>
#define BOOST_SPIRIT_ENABLE_BINARY(name) \
template <> \
struct use_terminal<qi::domain, tag::name> \
: mpl::true_ {}; \
\
template <typename A0> \
struct use_terminal<qi::domain \
, terminal_ex<tag::name, fusion::vector1<A0> > > \
: mpl::or_<is_integral<A0>, is_enum<A0> > {}; \
\
template <> \
struct use_lazy_terminal<qi::domain, tag::name, 1> : mpl::true_ {}; \
\
/***/
#define BOOST_SPIRIT_ENABLE_BINARY_IEEE754(name) \
template<> \
struct use_terminal<qi::domain, tag::name>: mpl::true_ {}; \
\
template<typename A0> \
struct use_terminal<qi::domain, terminal_ex<tag::name, \
fusion::vector1<A0> > >: is_floating_point<A0> {}; \
\
template<> \
struct use_lazy_terminal<qi::domain, tag::name, 1>: mpl::true_ {}; \
\
/***/
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_ENABLE_BINARY(byte_) // enables byte_
BOOST_SPIRIT_ENABLE_BINARY(word) // enables word
BOOST_SPIRIT_ENABLE_BINARY(big_word) // enables big_word
BOOST_SPIRIT_ENABLE_BINARY(little_word) // enables little_word
BOOST_SPIRIT_ENABLE_BINARY(dword) // enables dword
BOOST_SPIRIT_ENABLE_BINARY(big_dword) // enables big_dword
BOOST_SPIRIT_ENABLE_BINARY(little_dword) // enables little_dword
#ifdef BOOST_HAS_LONG_LONG
BOOST_SPIRIT_ENABLE_BINARY(qword) // enables qword
BOOST_SPIRIT_ENABLE_BINARY(big_qword) // enables big_qword
BOOST_SPIRIT_ENABLE_BINARY(little_qword) // enables little_qword
#endif
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_float)
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_float)
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_float)
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_double)
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_double)
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_double)
}}
#undef BOOST_SPIRIT_ENABLE_BINARY
#undef BOOST_SPIRIT_ENABLE_BINARY_IEEE754
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using boost::spirit::byte_;
using boost::spirit::word;
using boost::spirit::big_word;
using boost::spirit::little_word;
using boost::spirit::dword;
using boost::spirit::big_dword;
using boost::spirit::little_dword;
#ifdef BOOST_HAS_LONG_LONG
using boost::spirit::qword;
using boost::spirit::big_qword;
using boost::spirit::little_qword;
#endif
using boost::spirit::bin_float;
using boost::spirit::big_bin_float;
using boost::spirit::little_bin_float;
using boost::spirit::bin_double;
using boost::spirit::big_bin_double;
using boost::spirit::little_bin_double;
#endif
using boost::spirit::byte_type;
using boost::spirit::word_type;
using boost::spirit::big_word_type;
using boost::spirit::little_word_type;
using boost::spirit::dword_type;
using boost::spirit::big_dword_type;
using boost::spirit::little_dword_type;
#ifdef BOOST_HAS_LONG_LONG
using boost::spirit::qword_type;
using boost::spirit::big_qword_type;
using boost::spirit::little_qword_type;
#endif
using boost::spirit::bin_float_type;
using boost::spirit::big_bin_float_type;
using boost::spirit::little_bin_float_type;
using boost::spirit::bin_double_type;
using boost::spirit::big_bin_double_type;
using boost::spirit::little_bin_double_type;
namespace detail
{
template <int bits>
struct integer
{
#ifdef BOOST_HAS_LONG_LONG
BOOST_SPIRIT_ASSERT_MSG(
bits == 8 || bits == 16 || bits == 32 || bits == 64,
not_supported_binary_size, ());
#else
BOOST_SPIRIT_ASSERT_MSG(
bits == 8 || bits == 16 || bits == 32,
not_supported_binary_size, ());
#endif
};
template <>
struct integer<8>
{
enum { size = 1 };
typedef uint_least8_t type;
};
template <>
struct integer<16>
{
enum { size = 2 };
typedef uint_least16_t type;
};
template <>
struct integer<32>
{
enum { size = 4 };
typedef uint_least32_t type;
};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct integer<64>
{
enum { size = 8 };
typedef uint_least64_t type;
};
#endif
template <int bits>
struct floating_point
{
BOOST_SPIRIT_ASSERT_MSG(
bits == 32 || bits == 64,
not_supported_binary_size, ());
};
template <>
struct floating_point<32>
{
enum { size = 4 };
typedef float type;
};
template <>
struct floating_point<64>
{
enum { size = 8 };
typedef double type;
};
///////////////////////////////////////////////////////////////////////
template <BOOST_SCOPED_ENUM(boost::endian::endianness) bits>
struct what;
template <>
struct what<boost::endian::endianness::native>
{
static std::string is()
{
return "native-endian binary";
}
};
template <>
struct what<boost::endian::endianness::little>
{
static char const* is()
{
return "little-endian binary";
}
};
template <>
struct what<boost::endian::endianness::big>
{
static char const* is()
{
return "big-endian binary";
}
};
}
///////////////////////////////////////////////////////////////////////////
template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
struct any_binary_parser : primitive_parser<any_binary_parser<T, endian, bits> >
{
template <typename Context, typename Iterator>
struct attribute
{
typedef boost::endian::endian<endian, typename T::type,
bits> type;
};
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
{
qi::skip_over(first, last, skipper);
typename attribute<Context, Iterator>::type attr_;
unsigned char* bytes = reinterpret_cast<unsigned char*>(&attr_);
Iterator it = first;
for (unsigned int i = 0; i < sizeof(attr_); ++i)
{
if (it == last)
return false;
*bytes++ = *it++;
}
first = it;
spirit::traits::assign_to(attr_, attr_param);
return true;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info(qi::detail::what<endian>::is());
}
};
///////////////////////////////////////////////////////////////////////////
template <typename V, typename T
, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
struct binary_lit_parser
: primitive_parser<binary_lit_parser<V, T, endian, bits> >
{
template <typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
binary_lit_parser(V n_)
: n(n_) {}
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
{
qi::skip_over(first, last, skipper);
// Even if the endian types are not pod's (at least not in the
// definition of C++03) it seems to be safe to assume they are
// (but in C++0x the endian types _are_ PODs).
// This allows us to treat them as a sequence of consecutive bytes.
boost::endian::endian<endian, typename T::type, bits> attr_;
#if defined(BOOST_MSVC)
// warning C4244: 'argument' : conversion from 'const int' to 'foo', possible loss of data
#pragma warning(push)
#pragma warning(disable: 4244)
#endif
attr_ = n;
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
unsigned char* bytes = reinterpret_cast<unsigned char*>(&attr_);
Iterator it = first;
for (unsigned int i = 0; i < sizeof(attr_); ++i)
{
if (it == last || *bytes++ != static_cast<unsigned char>(*it++))
return false;
}
first = it;
spirit::traits::assign_to(attr_, attr_param);
return true;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info(qi::detail::what<endian>::is());
}
V n;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
struct make_binary_parser
{
typedef any_binary_parser<T, endian, bits> result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
template <typename V, typename T
, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
struct make_binary_lit_parser
{
typedef binary_lit_parser<V, T, endian, bits> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(fusion::at_c<0>(term.args));
}
};
#define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, bits) \
template <typename Modifiers> \
struct make_primitive<tag::name, Modifiers> \
: make_binary_parser<detail::integer<bits>, \
boost::endian::endianness::endiantype, bits> {}; \
\
template <typename Modifiers, typename A0> \
struct make_primitive< \
terminal_ex<tag::name, fusion::vector1<A0> > , Modifiers> \
: make_binary_lit_parser<A0, detail::integer<bits>, \
boost::endian::endianness::endiantype, bits> {}; \
\
/***/
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, 8)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, 16)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, 16)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, 16)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, 32)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, 32)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, 32)
#ifdef BOOST_HAS_LONG_LONG
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, 64)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, 64)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, 64)
#endif
#undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
#define BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(name, endiantype, bits) \
template<typename Modifiers> \
struct make_primitive<tag::name, Modifiers> \
: make_binary_parser<detail::floating_point<bits>, \
boost::endian::endianness::endiantype, bits> {}; \
\
template<typename Modifiers, typename A0> \
struct make_primitive< \
terminal_ex<tag::name, fusion::vector1<A0> >, Modifiers> \
: make_binary_lit_parser<A0, detail::floating_point<bits>, \
boost::endian::endianness::endiantype, \
bits> {}; \
\
/***/
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_float, native, 32)
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_float, big, 32)
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_float, little, 32)
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_double, native, 64)
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_double, big, 64)
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_double, little, 64)
#undef BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE
}}}
#endif
@@ -0,0 +1,18 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_CHAR_FEBRUARY_02_2007_0921AM)
#define BOOST_SPIRIT_CHAR_FEBRUARY_02_2007_0921AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/char/char_parser.hpp>
#include <boost/spirit/home/qi/char/char.hpp>
#include <boost/spirit/home/qi/char/char_class.hpp>
#endif
@@ -0,0 +1,615 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2010 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_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_CHAR_APRIL_16_2006_1051AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/string_traits.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/detail/get_encoding.hpp>
#include <boost/spirit/home/support/char_set/basic_chset.hpp>
#include <boost/spirit/home/qi/char/char_parser.hpp>
#include <boost/spirit/home/qi/char/char_class.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <string>
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding>
struct use_terminal<qi::domain
, terminal<
tag::char_code<tag::char_, CharEncoding> // enables char_
>
> : mpl::true_ {};
template <typename CharEncoding, typename A0>
struct use_terminal<qi::domain
, terminal_ex<
tag::char_code<tag::char_, CharEncoding> // enables char_('x'), char_("x")
, fusion::vector1<A0> // and char_("a-z0-9")
>
> : mpl::true_ {};
template <typename CharEncoding, typename A0, typename A1>
struct use_terminal<qi::domain
, terminal_ex<
tag::char_code<tag::char_, CharEncoding> // enables char_('a','z')
, fusion::vector2<A0, A1>
>
> : mpl::true_ {};
template <typename CharEncoding> // enables *lazy* char_('x'), char_("x")
struct use_lazy_terminal< // and char_("a-z0-9")
qi::domain
, tag::char_code<tag::char_, CharEncoding>
, 1 // arity
> : mpl::true_ {};
template <typename CharEncoding> // enables *lazy* char_('a','z')
struct use_lazy_terminal<
qi::domain
, tag::char_code<tag::char_, CharEncoding>
, 2 // arity
> : mpl::true_ {};
template <>
struct use_terminal<qi::domain, char> // enables 'x'
: mpl::true_ {};
template <>
struct use_terminal<qi::domain, char[2]> // enables "x"
: mpl::true_ {};
template <>
struct use_terminal<qi::domain, wchar_t> // enables wchar_t
: mpl::true_ {};
template <>
struct use_terminal<qi::domain, wchar_t[2]> // enables L"x"
: mpl::true_ {};
// enables lit(...)
template <typename A0>
struct use_terminal<qi::domain
, terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<traits::is_char<A0> >::type>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lit; // lit('x') is equivalent to 'x'
#endif
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
// Parser for a single character
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding, bool no_attribute, bool no_case = false>
struct literal_char
: char_parser<
literal_char<CharEncoding, no_attribute, false>
, typename CharEncoding::char_type
, typename mpl::if_c<no_attribute, unused_type
, typename CharEncoding::char_type>::type>
{
typedef typename CharEncoding::char_type char_type;
typedef CharEncoding char_encoding;
template <typename Char>
literal_char(Char ch_)
: ch(static_cast<char_type>(ch_)) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef typename mpl::if_c<
no_attribute, unused_type, char_type>::type
type;
};
template <typename CharParam, typename Context>
bool test(CharParam ch_, Context&) const
{
return traits::ischar<CharParam, char_encoding>::call(ch_) &&
ch == char_type(ch_);
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("literal-char", char_encoding::toucs4(ch));
}
char_type ch;
};
template <typename CharEncoding, bool no_attribute>
struct literal_char<CharEncoding, no_attribute, true> // case insensitive
: char_parser<
literal_char<CharEncoding, no_attribute, true>
, typename mpl::if_c<no_attribute, unused_type
, typename CharEncoding::char_type>::type>
{
typedef typename CharEncoding::char_type char_type;
typedef CharEncoding char_encoding;
literal_char(char_type ch)
: lo(static_cast<char_type>(char_encoding::tolower(ch)))
, hi(static_cast<char_type>(char_encoding::toupper(ch))) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef typename mpl::if_c<
no_attribute, unused_type, char_type>::type
type;
};
template <typename CharParam, typename Context>
bool test(CharParam ch_, Context&) const
{
if (!traits::ischar<CharParam, char_encoding>::call(ch_))
return false;
char_type ch = char_type(ch_); // optimize for token based parsing
return this->lo == ch || this->hi == ch;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("no-case-literal-char", char_encoding::toucs4(lo));
}
char_type lo, hi;
};
///////////////////////////////////////////////////////////////////////////
// Parser for a character range
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding, bool no_case = false>
struct char_range
: char_parser<char_range<CharEncoding, false>, typename CharEncoding::char_type>
{
typedef typename CharEncoding::char_type char_type;
typedef CharEncoding char_encoding;
char_range(char_type from_, char_type to_)
: from(from_), to(to_) {}
template <typename CharParam, typename Context>
bool test(CharParam ch_, Context&) const
{
if (!traits::ischar<CharParam, char_encoding>::call(ch_))
return false;
char_type ch = char_type(ch_); // optimize for token based parsing
return !(ch < from) && !(to < ch);
}
template <typename Context>
info what(Context& /*context*/) const
{
info result("char-range", char_encoding::toucs4(from));
boost::get<std::string>(result.value) += '-';
boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to));
return result;
}
char_type from, to;
};
template <typename CharEncoding>
struct char_range<CharEncoding, true> // case insensitive
: char_parser<char_range<CharEncoding, true>, typename CharEncoding::char_type>
{
typedef typename CharEncoding::char_type char_type;
typedef CharEncoding char_encoding;
char_range(char_type from, char_type to)
: from_lo(static_cast<char_type>(char_encoding::tolower(from)))
, to_lo(static_cast<char_type>(char_encoding::tolower(to)))
, from_hi(static_cast<char_type>(char_encoding::toupper(from)))
, to_hi(static_cast<char_type>(char_encoding::toupper(to)))
{}
template <typename CharParam, typename Context>
bool test(CharParam ch_, Context&) const
{
if (!traits::ischar<CharParam, char_encoding>::call(ch_))
return false;
char_type ch = char_type(ch_); // optimize for token based parsing
return (!(ch < from_lo) && !(to_lo < ch))
|| (!(ch < from_hi) && !(to_hi < ch))
;
}
template <typename Context>
info what(Context& /*context*/) const
{
info result("no-case-char-range", char_encoding::toucs4(from_lo));
boost::get<std::string>(result.value) += '-';
boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to_lo));
return result;
}
char_type from_lo, to_lo, from_hi, to_hi;
};
///////////////////////////////////////////////////////////////////////////
// Parser for a character set
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding, bool no_attribute, bool no_case = false>
struct char_set
: char_parser<char_set<CharEncoding, no_attribute, false>
, typename mpl::if_c<no_attribute, unused_type
, typename CharEncoding::char_type>::type>
{
typedef typename CharEncoding::char_type char_type;
typedef CharEncoding char_encoding;
template <typename String>
char_set(String const& str)
{
using spirit::detail::cast_char;
typedef typename
remove_const<
typename traits::char_type_of<String>::type
>::type
in_type;
BOOST_SPIRIT_ASSERT_MSG((
(sizeof(char_type) >= sizeof(in_type))
), cannot_convert_string, (String));
in_type const* definition =
(in_type const*)traits::get_c_string(str);
in_type ch = *definition++;
while (ch)
{
in_type next = *definition++;
if (next == '-')
{
next = *definition++;
if (next == 0)
{
chset.set(cast_char<char_type>(ch));
chset.set('-');
break;
}
chset.set(
cast_char<char_type>(ch),
cast_char<char_type>(next)
);
}
else
{
chset.set(cast_char<char_type>(ch));
}
ch = next;
}
}
template <typename CharParam, typename Context>
bool test(CharParam ch, Context&) const
{
return traits::ischar<CharParam, char_encoding>::call(ch) &&
chset.test(char_type(ch));
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("char-set");
}
support::detail::basic_chset<char_type> chset;
};
template <typename CharEncoding, bool no_attribute>
struct char_set<CharEncoding, no_attribute, true> // case insensitive
: char_parser<char_set<CharEncoding, no_attribute, true>
, typename mpl::if_c<no_attribute, unused_type
, typename CharEncoding::char_type>::type>
{
typedef typename CharEncoding::char_type char_type;
typedef CharEncoding char_encoding;
template <typename String>
char_set(String const& str)
{
typedef typename traits::char_type_of<String>::type in_type;
BOOST_SPIRIT_ASSERT_MSG((
(sizeof(char_type) == sizeof(in_type))
), cannot_convert_string, (String));
char_type const* definition =
(char_type const*)traits::get_c_string(str);
char_type ch = *definition++;
while (ch)
{
char_type next = *definition++;
if (next == '-')
{
next = *definition++;
if (next == 0)
{
chset.set(static_cast<char_type>(CharEncoding::tolower(ch)));
chset.set(static_cast<char_type>(CharEncoding::toupper(ch)));
chset.set('-');
break;
}
chset.set(static_cast<char_type>(CharEncoding::tolower(ch))
, static_cast<char_type>(CharEncoding::tolower(next)));
chset.set(static_cast<char_type>(CharEncoding::toupper(ch))
, static_cast<char_type>(CharEncoding::toupper(next)));
}
else
{
chset.set(static_cast<char_type>(CharEncoding::tolower(ch)));
chset.set(static_cast<char_type>(CharEncoding::toupper(ch)));
}
ch = next;
}
}
template <typename CharParam, typename Context>
bool test(CharParam ch, Context&) const
{
return traits::ischar<CharParam, char_encoding>::call(ch) &&
chset.test(char_type(ch));
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("no-case-char-set");
}
support::detail::basic_chset<char_type> chset;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename Modifiers, typename Encoding>
struct basic_literal
{
static bool const no_case =
has_modifier<
Modifiers
, tag::char_code_base<tag::no_case>
>::value;
static bool const no_attr =
!has_modifier<
Modifiers
, tag::lazy_eval
>::value;
typedef literal_char<
typename spirit::detail::get_encoding_with_case<
Modifiers, Encoding, no_case>::type
, no_attr
, no_case>
result_type;
template <typename Char>
result_type operator()(Char ch, unused_type) const
{
return result_type(ch);
}
template <typename Char>
result_type operator()(Char const* str, unused_type) const
{
return result_type(str[0]);
}
};
}
template <typename Modifiers>
struct make_primitive<char, Modifiers>
: detail::basic_literal<Modifiers, char_encoding::standard> {};
template <typename Modifiers>
struct make_primitive<char const(&)[2], Modifiers>
: detail::basic_literal<Modifiers, char_encoding::standard> {};
template <typename Modifiers>
struct make_primitive<wchar_t, Modifiers>
: detail::basic_literal<Modifiers, char_encoding::standard_wide> {};
template <typename Modifiers>
struct make_primitive<wchar_t const(&)[2], Modifiers>
: detail::basic_literal<Modifiers, char_encoding::standard_wide> {};
template <typename CharEncoding, typename Modifiers>
struct make_primitive<
terminal<tag::char_code<tag::char_, CharEncoding> >, Modifiers>
{
typedef typename
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
char_encoding;
typedef tag::char_code<tag::char_, char_encoding> tag;
typedef char_class<tag> result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
///////////////////////////////////////////////////////////////////////////
// char_('x')
template <typename CharEncoding, typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<
tag::char_code<tag::char_, CharEncoding>
, fusion::vector1<A0> >
, Modifiers>
{
static bool const no_case =
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
typedef typename
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
char_encoding;
typedef typename
mpl::if_<
traits::is_string<A0>
, char_set<char_encoding, false, no_case>
, literal_char<char_encoding, false, no_case>
>::type
result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(fusion::at_c<0>(term.args));
}
};
// lit('x')
template <typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<tag::lit, fusion::vector1<A0> >
, Modifiers
, typename enable_if<traits::is_char<A0> >::type>
{
static bool const no_case =
has_modifier<
Modifiers
, tag::char_code_base<tag::no_case>
>::value;
typedef typename traits::char_encoding_from_char<
typename traits::char_type_of<A0>::type>::type encoding;
typedef literal_char<
typename spirit::detail::get_encoding_with_case<
Modifiers, encoding, no_case>::type
, true, no_case>
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 CharEncoding, typename Modifiers, typename Char>
struct make_primitive<
terminal_ex<
tag::char_code<tag::char_, CharEncoding>
, fusion::vector1<Char(&)[2]> // For single char strings
>
, Modifiers>
{
static bool const no_case =
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
typedef typename
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
char_encoding;
typedef literal_char<char_encoding, false, no_case> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(fusion::at_c<0>(term.args)[0]);
}
};
template <typename CharEncoding, typename Modifiers, typename A0, typename A1>
struct make_primitive<
terminal_ex<
tag::char_code<tag::char_, CharEncoding>
, fusion::vector2<A0, A1>
>
, Modifiers>
{
static bool const no_case =
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
typedef typename
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
char_encoding;
typedef char_range<char_encoding, no_case> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(
fusion::at_c<0>(term.args)
, fusion::at_c<1>(term.args)
);
}
};
template <typename CharEncoding, typename Modifiers, typename Char>
struct make_primitive<
terminal_ex<
tag::char_code<tag::char_, CharEncoding>
, fusion::vector2<Char(&)[2], Char(&)[2]> // For single char strings
>
, Modifiers>
{
static bool const no_case =
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
typedef typename
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
char_encoding;
typedef char_range<char_encoding, no_case> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(
fusion::at_c<0>(term.args)[0]
, fusion::at_c<1>(term.args)[0]
);
}
};
}}}
#endif
@@ -0,0 +1,118 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_CHAR_CLASS_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_CHAR_CLASS_APRIL_16_2006_1051AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/char/char_parser.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/modify.hpp>
#include <boost/spirit/home/support/detail/get_encoding.hpp>
#include <boost/mpl/eval_if.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables alnum, alpha, graph, etc.
template <typename CharClass, typename CharEncoding>
struct use_terminal<qi::domain, tag::char_code<CharClass, CharEncoding> >
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
// hoist the char classification namespaces into qi sub-namespaces of the
// same name
namespace ascii { using namespace boost::spirit::ascii; }
namespace iso8859_1 { using namespace boost::spirit::iso8859_1; }
namespace standard { using namespace boost::spirit::standard; }
namespace standard_wide { using namespace boost::spirit::standard_wide; }
#if defined(BOOST_SPIRIT_UNICODE)
namespace unicode { using namespace boost::spirit::unicode; }
#endif
// Import the standard namespace into the qi namespace. This allows
// for default handling of all character/string related operations if not
// prefixed with a character set namespace.
using namespace boost::spirit::standard;
// Import encoding
using spirit::encoding;
///////////////////////////////////////////////////////////////////////////
// Generic char classification parser (for alnum, alpha, graph, etc.)
///////////////////////////////////////////////////////////////////////////
template <typename Tag>
struct char_class
: char_parser<char_class<Tag>, typename Tag::char_encoding::char_type>
{
typedef typename Tag::char_encoding char_encoding;
typedef typename Tag::char_class classification;
template <typename CharParam, typename Context>
bool test(CharParam ch, Context&) const
{
using spirit::char_class::classify;
return traits::ischar<CharParam, char_encoding>::call(ch) &&
classify<char_encoding>::is(classification(), ch);
}
template <typename Context>
info what(Context& /*context*/) const
{
typedef spirit::char_class::what<char_encoding> what_;
return info(what_::is(classification()));
}
};
namespace detail
{
template <typename Tag, bool no_case = false>
struct make_char_class : mpl::identity<Tag> {};
template <>
struct make_char_class<tag::lower, true> : mpl::identity<tag::alpha> {};
template <>
struct make_char_class<tag::upper, true> : mpl::identity<tag::alpha> {};
}
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename CharClass, typename CharEncoding, typename Modifiers>
struct make_primitive<tag::char_code<CharClass, CharEncoding>, Modifiers>
{
static bool const no_case =
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
typedef typename
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
char_encoding;
typedef tag::char_code<
typename detail::make_char_class<CharClass, no_case>::type
, char_encoding>
tag;
typedef char_class<tag> result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
}}}
#endif
@@ -0,0 +1,157 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_CHAR_PARSER_APR_16_2006_0906AM)
#define BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::complement> // enables ~
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace traits // classification
{
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(char_parser_id)
}
template <typename T>
struct is_char_parser : detail::has_char_parser_id<T> {};
}}}
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// The base char_parser
///////////////////////////////////////////////////////////////////////////
template <typename Derived, typename Char, typename Attr = Char>
struct char_parser : primitive_parser<Derived>
{
typedef Char char_type;
struct char_parser_id;
// if Attr is unused_type, Derived must supply its own attribute
// metafunction
template <typename Context, typename Iterator>
struct attribute
{
typedef Attr 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
{
qi::skip_over(first, last, skipper);
if (first != last && this->derived().test(*first, context))
{
spirit::traits::assign_to(*first, attr_);
++first;
return true;
}
return false;
}
// Requirement: p.test(ch, context) -> bool
//
// ch: character being parsed
// context: enclosing rule context
};
///////////////////////////////////////////////////////////////////////////
// negated_char_parser handles ~cp expressions (cp is a char_parser)
///////////////////////////////////////////////////////////////////////////
template <typename Positive>
struct negated_char_parser :
char_parser<negated_char_parser<Positive>, typename Positive::char_type>
{
negated_char_parser(Positive const& positive_)
: positive(positive_) {}
template <typename CharParam, typename Context>
bool test(CharParam ch, Context& context) const
{
return !positive.test(ch, context);
}
template <typename Context>
info what(Context& context) const
{
return info("not", positive.what(context));
}
Positive positive;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename Positive>
struct make_negated_char_parser
{
typedef negated_char_parser<Positive> result_type;
result_type operator()(Positive const& positive) const
{
return result_type(positive);
}
};
template <typename Positive>
struct make_negated_char_parser<negated_char_parser<Positive> >
{
typedef Positive result_type;
result_type operator()(negated_char_parser<Positive> const& ncp) const
{
return ncp.positive;
}
};
}
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::complement, Elements, Modifiers>
{
typedef typename
fusion::result_of::value_at_c<Elements, 0>::type
subject;
BOOST_SPIRIT_ASSERT_MSG((
traits::is_char_parser<subject>::value
), subject_is_not_negatable, (subject));
typedef typename
detail::make_negated_char_parser<subject>::result_type
result_type;
result_type operator()(Elements const& elements, unused_type) const
{
return detail::make_negated_char_parser<subject>()(
fusion::at_c<0>(elements));
}
};
}}}
#endif
@@ -0,0 +1,31 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
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_COPY_FEBRUARY_7_2012_0159PM)
#define BOOST_SPIRIT_COPY_FEBRUARY_7_2012_0159PM
#include <boost/config.hpp>
#include <boost/proto/proto.hpp>
#if defined(_MSC_VER)
#pragma once
#endif
#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
namespace boost { namespace spirit { namespace qi
{
template <typename Expr>
typename boost::proto::result_of::deep_copy<Expr>::type
copy(Expr const& expr)
{
BOOST_SPIRIT_ASSERT_MATCH(boost::spirit::qi::domain, Expr);
return boost::proto::deep_copy(expr);
}
}}}
#endif
#endif
@@ -0,0 +1,214 @@
/*=============================================================================
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_ALTERNATIVE_FUNCTION_APRIL_23_2007_1046AM)
#define SPIRIT_ALTERNATIVE_FUNCTION_APRIL_23_2007_1046AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/variant.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Variant, typename Expected>
struct find_substitute
{
// Get the typr from the variant that can be a substitute for Expected.
// If none is found, just return Expected
typedef Variant variant_type;
typedef typename variant_type::types types;
typedef typename mpl::end<types>::type end;
typedef typename
mpl::find_if<types, is_same<mpl::_1, Expected> >::type
iter_1;
typedef typename
mpl::eval_if<
is_same<iter_1, end>,
mpl::find_if<types, traits::is_substitute<mpl::_1, Expected> >,
mpl::identity<iter_1>
>::type
iter;
typedef typename
mpl::eval_if<
is_same<iter, end>,
mpl::identity<Expected>,
mpl::deref<iter>
>::type
type;
};
template <typename Iterator, typename Context, typename Skipper,
typename Attribute>
struct alternative_function
{
alternative_function(
Iterator& first_, Iterator const& last_, Context& context_,
Skipper const& skipper_, Attribute& attr_)
: first(first_), last(last_), context(context_), skipper(skipper_),
attr(attr_)
{
}
template <typename Component>
bool call(Component const& component, mpl::true_) const
{
// if Attribute is not a variant, then pass it as-is
return component.parse(first, last, context, skipper, attr);
}
template <typename Component>
bool call_optional_or_variant(Component const& component, mpl::true_) const
{
// If Attribute is an optional, then create an attribute for the Component
// with the type optional::value_type. If the expected attribute is unused type,
// use it instead.
typedef typename
traits::attribute_of<Component, Context, Iterator>::type
expected_type;
typename mpl::if_<
is_same<expected_type, unused_type>,
unused_type,
typename Attribute::value_type>::type
val;
if (component.parse(first, last, context, skipper, val))
{
traits::assign_to(val, attr);
return true;
}
return false;
}
template <typename Component>
bool call_variant(Component const& component, mpl::false_) const
{
// If Attribute is a variant, then search the variant types for a
// suitable substitute type.
typename
find_substitute<Attribute,
typename traits::attribute_of<Component, Context, Iterator>::type
>::type
val;
if (component.parse(first, last, context, skipper, val))
{
traits::assign_to(val, attr);
return true;
}
return false;
}
template <typename Component>
bool call_variant(Component const& component, mpl::true_) const
{
// If Attribute is a variant and the expected attribute is
// the same type (pass the variant as-is).
return component.parse(first, last, context, skipper, attr);
}
template <typename Component>
bool call_optional_or_variant(Component const& component, mpl::false_) const
{
// Attribute is a variant...
typedef typename
traits::attribute_of<Component, Context, Iterator>::type
expected;
return call_variant(component,
is_same<Attribute, expected>());
}
template <typename Component>
bool call(Component const& component, mpl::false_) const
{
return call_optional_or_variant(
component, spirit::traits::not_is_variant<Attribute, qi::domain>());
}
template <typename Component>
bool call_unused(Component const& component, mpl::true_) const
{
// return true if the parser succeeds
return call(component,
mpl::and_<
spirit::traits::not_is_variant<Attribute, qi::domain>,
spirit::traits::not_is_optional<Attribute, qi::domain>
>());
}
template <typename Component>
bool call_unused(Component const& component, mpl::false_) const
{
return component.parse(first, last, context, skipper, unused);
}
template <typename Component>
bool operator()(Component const& component) const
{
// return true if the parser succeeds
typedef typename traits::not_is_unused<
typename traits::attribute_of<Component, Context, Iterator>::type
>::type predicate;
return call_unused(component, predicate());
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
Attribute& attr;
private:
// silence MSVC warning C4512: assignment operator could not be generated
alternative_function& operator= (alternative_function const&);
};
template <typename Iterator, typename Context, typename Skipper>
struct alternative_function<Iterator, Context, Skipper, unused_type const>
{
alternative_function(
Iterator& first_, Iterator const& last_, Context& context_,
Skipper const& skipper_, unused_type)
: first(first_), last(last_), context(context_), skipper(skipper_)
{
}
template <typename Component>
bool operator()(Component const& component) const
{
// return true if the parser succeeds
return component.parse(first, last, context, skipper,
unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
private:
// silence MSVC warning C4512: assignment operator could not be generated
alternative_function& operator= (alternative_function const&);
};
}}}}
#endif
@@ -0,0 +1,403 @@
/*=============================================================================
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(BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM)
#define BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/detail/construct.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/fusion/include/copy.hpp>
#include <boost/fusion/adapted/struct/detail/extension.hpp>
#include <boost/ref.hpp>
#include <boost/range/iterator_range.hpp>
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// This file contains assignment utilities. The utilities provided also
// accept spirit's unused_type; all no-ops. Compiler optimization will
// easily strip these away.
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename T>
struct is_iter_range : mpl::false_ {};
template <typename I>
struct is_iter_range<boost::iterator_range<I> > : mpl::true_ {};
template <typename C>
struct is_container_of_ranges
: is_iter_range<typename C::value_type> {};
}
template <typename Attribute, typename Iterator, typename Enable>
struct assign_to_attribute_from_iterators
{
// Common case
static void
call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::false_)
{
if (traits::is_empty(attr))
attr = Attribute(first, last);
else {
for (Iterator i = first; i != last; ++i)
push_back(attr, *i);
}
}
// If Attribute is a container with value_type==iterator_range<T> just push the
// iterator_range into it
static void
call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::true_)
{
typename Attribute::value_type rng(first, last);
push_back(attr, rng);
}
static void
call(Iterator const& first, Iterator const& last, Attribute& attr)
{
call(first, last, attr, detail::is_container_of_ranges<Attribute>());
}
};
template <typename Attribute, typename Iterator>
struct assign_to_attribute_from_iterators<
reference_wrapper<Attribute>, Iterator>
{
static void
call(Iterator const& first, Iterator const& last
, reference_wrapper<Attribute> attr)
{
if (traits::is_empty(attr))
attr = Attribute(first, last);
else {
for (Iterator i = first; i != last; ++i)
push_back(attr, *i);
}
}
};
template <typename Attribute, typename Iterator>
struct assign_to_attribute_from_iterators<
boost::optional<Attribute>, Iterator>
{
static void
call(Iterator const& first, Iterator const& last
, boost::optional<Attribute>& attr)
{
Attribute val;
assign_to(first, last, val);
attr = val;
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<
iterator_range<Iterator>, Iterator>
{
static void
call(Iterator const& first, Iterator const& last
, iterator_range<Iterator>& attr)
{
attr = iterator_range<Iterator>(first, last);
}
};
template <typename Iterator, typename Attribute>
inline void
assign_to(Iterator const& first, Iterator const& last, Attribute& attr)
{
assign_to_attribute_from_iterators<Attribute, Iterator>::
call(first, last, attr);
}
template <typename Iterator>
inline void
assign_to(Iterator const&, Iterator const&, unused_type)
{
}
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Attribute>
void assign_to(T const& val, Attribute& attr);
template <typename Attribute, typename T, typename Enable>
struct assign_to_attribute_from_value
{
typedef typename traits::one_element_sequence<Attribute>::type
is_one_element_sequence;
typedef typename mpl::eval_if<
is_one_element_sequence
, fusion::result_of::at_c<Attribute, 0>
, mpl::identity<Attribute&>
>::type type;
template <typename T_>
static void
call(T_ const& val, Attribute& attr, mpl::false_)
{
attr = static_cast<Attribute>(val);
}
// This handles the case where the attribute is a single element fusion
// sequence. We silently assign to the only element and treat it as the
// attribute to parse the results into.
template <typename T_>
static void
call(T_ const& val, Attribute& attr, mpl::true_)
{
typedef typename fusion::result_of::value_at_c<Attribute, 0>::type
element_type;
fusion::at_c<0>(attr) = static_cast<element_type>(val);
}
static void
call(T const& val, Attribute& attr)
{
call(val, attr, is_one_element_sequence());
}
};
template <typename Attribute>
struct assign_to_attribute_from_value<Attribute, Attribute>
{
static void
call(Attribute const& val, Attribute& attr)
{
attr = val;
}
};
template <typename Attribute, typename T>
struct assign_to_attribute_from_value<Attribute, reference_wrapper<T>
, typename disable_if<is_same<Attribute, reference_wrapper<T> > >::type>
{
static void
call(reference_wrapper<T> const& val, Attribute& attr)
{
assign_to(val.get(), attr);
}
};
template <typename Attribute, typename T>
struct assign_to_attribute_from_value<Attribute, boost::optional<T>
, typename disable_if<is_same<Attribute, boost::optional<T> > >::type>
{
static void
call(boost::optional<T> const& val, Attribute& attr)
{
assign_to(val.get(), attr);
}
};
template <typename Attribute, int N, bool Const, typename T>
struct assign_to_attribute_from_value<fusion::extension::adt_attribute_proxy<Attribute, N, Const>, T>
{
static void
call(T const& val, typename fusion::extension::adt_attribute_proxy<Attribute, N, Const>& attr)
{
attr = val;
}
};
namespace detail
{
template <typename A, typename B>
struct is_same_size_sequence
: mpl::bool_<fusion::result_of::size<A>::value
== fusion::result_of::size<B>::value>
{};
}
template <typename Attribute, typename T>
struct assign_to_attribute_from_value<Attribute, T,
mpl::and_<
fusion::traits::is_sequence<Attribute>,
fusion::traits::is_sequence<T>,
detail::is_same_size_sequence<Attribute, T>
>
>
{
static void
call(T const& val, Attribute& attr)
{
fusion::copy(val, attr);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename T, typename Enable>
struct assign_to_container_from_value
{
// T is not a container and not a string
template <typename T_>
static void call(T_ const& val, Attribute& attr, mpl::false_, mpl::false_)
{
traits::push_back(attr, val);
}
// T is a container (but not a string), and T is convertible to the
// value_type of the Attribute container
template <typename T_>
static void
append_to_container_not_string(T_ const& val, Attribute& attr, mpl::true_)
{
traits::push_back(attr, val);
}
// T is a container (but not a string), generic overload
template <typename T_>
static void
append_to_container_not_string(T_ const& val, Attribute& attr, mpl::false_)
{
typedef typename traits::container_iterator<T_ const>::type
iterator_type;
iterator_type end = traits::end(val);
for (iterator_type i = traits::begin(val); i != end; traits::next(i))
traits::push_back(attr, traits::deref(i));
}
// T is a container (but not a string)
template <typename T_>
static void call(T_ const& val, Attribute& attr, mpl::true_, mpl::false_)
{
typedef typename container_value<Attribute>::type value_type;
typedef typename is_convertible<T, value_type>::type is_value_type;
append_to_container_not_string(val, attr, is_value_type());
}
///////////////////////////////////////////////////////////////////////
// T is a string
template <typename Iterator>
static void append_to_string(Attribute& attr, Iterator begin, Iterator end)
{
for (Iterator i = begin; i != end; ++i)
traits::push_back(attr, *i);
}
// T is string, but not convertible to value_type of container
template <typename T_>
static void append_to_container(T_ const& val, Attribute& attr, mpl::false_)
{
typedef typename char_type_of<T_>::type char_type;
append_to_string(attr, traits::get_begin<char_type>(val)
, traits::get_end<char_type>(val));
}
// T is string, and convertible to value_type of container
template <typename T_>
static void append_to_container(T_ const& val, Attribute& attr, mpl::true_)
{
traits::push_back(attr, val);
}
template <typename T_, typename Pred>
static void call(T_ const& val, Attribute& attr, Pred, mpl::true_)
{
typedef typename container_value<Attribute>::type value_type;
typedef typename is_convertible<T, value_type>::type is_value_type;
append_to_container(val, attr, is_value_type());
}
///////////////////////////////////////////////////////////////////////
static void call(T const& val, Attribute& attr)
{
typedef typename traits::is_container<T>::type is_container;
typedef typename traits::is_string<T>::type is_string;
call(val, attr, is_container(), is_string());
}
};
template <typename Attribute>
struct assign_to_container_from_value<Attribute, Attribute>
{
static void
call(Attribute const& val, Attribute& attr)
{
attr = val;
}
};
template <typename Attribute, typename T>
struct assign_to_container_from_value<Attribute, boost::optional<T>
, typename disable_if<is_same<Attribute, boost::optional<T> > >::type>
{
static void
call(boost::optional<T> const& val, Attribute& attr)
{
assign_to(val.get(), attr);
}
};
template <typename Attribute, typename T>
struct assign_to_container_from_value<Attribute, reference_wrapper<T>
, typename disable_if<is_same<Attribute, reference_wrapper<T> > >::type>
{
static void
call(reference_wrapper<T> const& val, Attribute& attr)
{
assign_to(val.get(), attr);
}
};
///////////////////////////////////////////////////////////////////////////
namespace detail
{
// overload for non-container attributes
template <typename T, typename Attribute>
inline void
assign_to(T const& val, Attribute& attr, mpl::false_)
{
assign_to_attribute_from_value<Attribute, T>::call(val, attr);
}
// overload for containers (but not for variants or optionals
// holding containers)
template <typename T, typename Attribute>
inline void
assign_to(T const& val, Attribute& attr, mpl::true_)
{
assign_to_container_from_value<Attribute, T>::call(val, attr);
}
}
template <typename T, typename Attribute>
inline void
assign_to(T const& val, Attribute& attr)
{
typedef typename mpl::and_<
traits::is_container<Attribute>
, traits::not_is_variant<Attribute>
, traits::not_is_optional<Attribute>
>::type is_not_wrapped_container;
detail::assign_to(val, attr, is_not_wrapped_container());
}
template <typename T>
inline void
assign_to(T const&, unused_type)
{
}
}}}
#endif
@@ -0,0 +1,176 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// Copyright (c) 2001-2011 Joel de Guzman
//
// 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_DETAIL_ATTRIBUTES_APR_18_2010_0458PM)
#define SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
#include <boost/spirit/home/support/attributes.hpp>
#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
template <typename Exposed, typename Transformed>
struct default_transform_attribute
{
typedef Transformed type;
static Transformed pre(Exposed&) { return Transformed(); }
static void post(Exposed& val, Transformed const& attr)
{
traits::assign_to(attr, val);
}
// fail() will be called by Qi rule's if the rhs failed parsing
static void fail(Exposed&) {}
};
// handle case where no transformation is required as the types are the same
template <typename Attribute>
struct default_transform_attribute<Attribute, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
static void fail(Attribute&) {}
};
template <typename Exposed, typename Transformed>
struct proxy_transform_attribute
{
typedef Transformed type;
static Transformed pre(Exposed& val) { return Transformed(val); }
static void post(Exposed&, Transformed const&) { /* no-op */ }
// fail() will be called by Qi rule's if the rhs failed parsing
static void fail(Exposed&) {}
};
// handle case where no transformation is required as the types are the same
template <typename Attribute>
struct proxy_transform_attribute<Attribute, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
static void fail(Attribute&) {}
};
// main specialization for Qi
template <typename Exposed, typename Transformed, typename Enable = void>
struct transform_attribute
: mpl::if_<
mpl::and_<
mpl::not_<is_const<Exposed> >
, mpl::not_<is_reference<Exposed> >
, traits::is_proxy<Transformed> >
, proxy_transform_attribute<Exposed, Transformed>
, default_transform_attribute<Exposed, Transformed>
>::type
{};
template <typename Exposed, typename Transformed>
struct transform_attribute<boost::optional<Exposed>, Transformed
, typename disable_if<is_same<boost::optional<Exposed>, Transformed> >::type>
{
typedef Transformed& type;
static Transformed& pre(boost::optional<Exposed>& val)
{
if (!val)
val = Transformed();
return boost::get<Transformed>(val);
}
static void post(boost::optional<Exposed>&, Transformed const&) {}
static void fail(boost::optional<Exposed>& val)
{
val = none; // leave optional uninitialized if rhs failed
}
};
// reference types need special handling
template <typename Attribute>
struct transform_attribute<Attribute&, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
static void fail(Attribute&) {}
};
// unused_type needs some special handling as well
template <>
struct transform_attribute<unused_type, unused_type>
{
typedef unused_type type;
static unused_type pre(unused_type) { return unused; }
static void post(unused_type, unused_type) {}
static void fail(unused_type) {}
};
template <>
struct transform_attribute<unused_type const, unused_type>
: transform_attribute<unused_type, unused_type>
{};
template <typename Attribute>
struct transform_attribute<unused_type, Attribute>
: transform_attribute<unused_type, unused_type>
{};
template <typename Attribute>
struct transform_attribute<unused_type const, Attribute>
: transform_attribute<unused_type, unused_type>
{};
template <typename Attribute>
struct transform_attribute<Attribute, unused_type>
: transform_attribute<unused_type, unused_type>
{};
template <typename Attribute>
struct transform_attribute<Attribute const, unused_type>
: transform_attribute<unused_type, unused_type>
{};
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed, Transformed, qi::domain>
: qi::transform_attribute<Exposed, Transformed>
{};
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed&, Transformed, qi::domain>
: transform_attribute<Exposed, Transformed, qi::domain>
{};
template <typename Attribute>
struct transform_attribute<Attribute&, Attribute, qi::domain>
: qi::transform_attribute<Attribute&, Attribute>
{};
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed>
void post_transform(Exposed& dest, Transformed const& attr)
{
return transform_attribute<Exposed, Transformed, qi::domain>::post(dest, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed>
void fail_transform(Exposed& dest, Transformed const&)
{
return transform_attribute<Exposed, Transformed, qi::domain>::fail(dest);
}
}}}
#endif
@@ -0,0 +1,202 @@
/*=============================================================================
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(BOOST_SPIRIT_CONSTRUCT_MAR_24_2007_0629PM)
#define BOOST_SPIRIT_CONSTRUCT_MAR_24_2007_0629PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// We provide overloads for the assign_to_attribute_from_iterators
// customization point for all built in types
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
struct assign_to_attribute_from_iterators<char, Iterator>
{
static void
call(Iterator const& first, Iterator const&, char& attr)
{
attr = *first;
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<signed char, Iterator>
{
static void
call(Iterator const& first, Iterator const&, signed char& attr)
{
attr = *first;
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned char, Iterator>
{
static void
call(Iterator const& first, Iterator const&, unsigned char& attr)
{
attr = *first;
}
};
// wchar_t is intrinsic
template <typename Iterator>
struct assign_to_attribute_from_iterators<wchar_t, Iterator>
{
static void
call(Iterator const& first, Iterator const&, wchar_t& attr)
{
attr = *first;
}
};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
// wchar_t is intrinsic, have separate overload for unsigned short
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned short, Iterator>
{
static void
call(Iterator const& first, Iterator const&, unsigned short& attr)
{
attr = *first;
}
};
#endif
template <typename Iterator>
struct assign_to_attribute_from_iterators<bool, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, bool& attr)
{
Iterator first_ = first;
qi::parse(first_, last, bool_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<short, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, short& attr)
{
Iterator first_ = first;
qi::parse(first_, last, short_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<int, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, int& attr)
{
Iterator first_ = first;
qi::parse(first_, last, int_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned int, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, unsigned int& attr)
{
Iterator first_ = first;
qi::parse(first_, last, uint_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<long, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, long& attr)
{
Iterator first_ = first;
qi::parse(first_, last, long_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned long, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, unsigned long& attr)
{
Iterator first_ = first;
qi::parse(first_, last, ulong_type(), attr);
}
};
#ifdef BOOST_HAS_LONG_LONG
template <typename Iterator>
struct assign_to_attribute_from_iterators<long_long_type, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, long_long_type& attr)
{
Iterator first_ = first;
qi::parse(first_, last, long_long_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<ulong_long_type, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, ulong_long_type& attr)
{
Iterator first_ = first;
qi::parse(first_, last, ulong_long_type(), attr);
}
};
#endif
template <typename Iterator>
struct assign_to_attribute_from_iterators<float, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, float& attr)
{
Iterator first_ = first;
qi::parse(first_, last, float_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<double, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, double& attr)
{
Iterator first_ = first;
qi::parse(first_, last, double_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<long double, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, long double& attr)
{
Iterator first_ = first;
qi::parse(first_, last, long_double_type(), attr);
}
};
}}}
#endif
@@ -0,0 +1,30 @@
// 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(BOOST_SPIRIT_QI_DETAIL_ENABLE_LIT_JAN_06_2011_0945PM)
#define BOOST_SPIRIT_QI_DETAIL_ENABLE_LIT_JAN_06_2011_0945PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/spirit/home/support/string_traits.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
namespace boost { namespace spirit
{
// enables lazy lit(...) for qi
template <>
struct use_lazy_terminal<qi::domain, tag::lit, 1>
: mpl::true_ {};
}}
#endif
@@ -0,0 +1,105 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_EXPECT_FUNCTION_APR_29_2007_0558PM)
#define SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/multi_pass_wrapper.hpp>
#include <boost/throw_exception.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <
typename Iterator, typename Context
, typename Skipper, typename Exception>
struct expect_function
{
typedef Iterator iterator_type;
typedef Context context_type;
expect_function(
Iterator& first_, Iterator const& last_
, Context& context_, Skipper const& skipper_)
: first(first_)
, last(last_)
, context(context_)
, skipper(skipper_)
, is_first(true)
{
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, Attribute& attr) const
{
// if this is not the first component in the expect chain we
// need to flush any multi_pass iterator we might be acting on
if (!is_first)
spirit::traits::clear_queue(first);
// if we are testing the first component in the sequence,
// return true if the parser fails, if this is not the first
// component, throw exception if the parser fails
if (!component.parse(first, last, context, skipper, attr))
{
if (is_first)
{
is_first = false;
return true; // true means the match failed
}
boost::throw_exception(Exception(first, last, component.what(context)));
#if defined(BOOST_NO_EXCEPTIONS)
return true; // for systems not supporting exceptions
#endif
}
is_first = false;
return false;
}
template <typename Component>
bool operator()(Component const& component) const
{
// if this is not the first component in the expect chain we
// need to flush any multi_pass iterator we might be acting on
if (!is_first)
spirit::traits::clear_queue(first);
// if we are testing the first component in the sequence,
// return true if the parser fails, if this not the first
// component, throw exception if the parser fails
if (!component.parse(first, last, context, skipper, unused))
{
if (is_first)
{
is_first = false;
return true;
}
boost::throw_exception(Exception(first, last, component.what(context)));
#if defined(BOOST_NO_EXCEPTIONS)
return false; // for systems not supporting exceptions
#endif
}
is_first = false;
return false;
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
mutable bool is_first;
private:
// silence MSVC warning C4512: assignment operator could not be generated
expect_function& operator= (expect_function const&);
};
}}}}
#endif
@@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_FAIL_FUNCTION_APRIL_22_2006_0159PM)
#define SPIRIT_FAIL_FUNCTION_APRIL_22_2006_0159PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Iterator, typename Context, typename Skipper>
struct fail_function
{
typedef Iterator iterator_type;
typedef Context context_type;
fail_function(
Iterator& first_, Iterator const& last_
, Context& context_, Skipper const& skipper_)
: first(first_)
, last(last_)
, context(context_)
, skipper(skipper_)
{
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, Attribute& attr) const
{
// return true if the parser fails
return !component.parse(first, last, context, skipper, attr);
}
template <typename Component>
bool operator()(Component const& component) const
{
// return true if the parser fails
return !component.parse(first, last, context, skipper, unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
private:
// silence MSVC warning C4512: assignment operator could not be generated
fail_function& operator= (fail_function const&);
};
}}}}
#endif
@@ -0,0 +1,97 @@
/*=============================================================================
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(BOOST_SPIRIT_DETAIL_PARSE_DEC_02_2009_0411PM)
#define BOOST_SPIRIT_DETAIL_PARSE_DEC_02_2009_0411PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_flag.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable = void>
struct parse_impl
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
// Did you intend to use the auto_ facilities while forgetting to
// #include <boost/spirit/include/qi_auto.hpp>?
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
};
template <typename Expr>
struct parse_impl<Expr
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
{
template <typename Iterator>
static bool call(
Iterator& first
, Iterator last
, Expr const& expr)
{
return compile<qi::domain>(expr).parse(
first, last, unused, unused, unused);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable = void>
struct phrase_parse_impl
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
// Did you intend to use the auto_ facilities while forgetting to
// #include <boost/spirit/include/qi_auto.hpp>?
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
};
template <typename Expr>
struct phrase_parse_impl<Expr
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
{
template <typename Iterator, typename Skipper>
static bool call(
Iterator& first
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the skipper is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
typedef
typename result_of::compile<qi::domain, Skipper>::type
skipper_type;
skipper_type const skipper_ = compile<qi::domain>(skipper);
if (!compile<qi::domain>(expr).parse(
first, last, unused, skipper_, unused))
return false;
if (post_skip == skip_flag::postskip)
qi::skip_over(first, last, skipper_);
return true;
}
};
}}}}
#endif
@@ -0,0 +1,191 @@
/*=============================================================================
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(BOOST_SPIRIT_DETAIL_PARSE_AUTO_DEC_02_2009_0426PM)
#define BOOST_SPIRIT_DETAIL_PARSE_AUTO_DEC_02_2009_0426PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/qi/auto/create_parser.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/and.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct parse_impl<Expr
, typename enable_if<
mpl::and_<
traits::meta_create_exists<qi::domain, Expr>
, mpl::not_<traits::matches<qi::domain, Expr> > >
>::type>
{
template <typename Iterator>
static bool call(Iterator& first, Iterator last, Expr& expr)
{
return qi::parse(first, last, create_parser<Expr>(), expr);
}
template <typename Iterator>
static bool call(Iterator& first, Iterator last, Expr const& expr)
{
return qi::parse(first, last, create_parser<Expr>()
, const_cast<Expr&>(expr));
}
};
// the following specializations are needed to explicitly disambiguate
// the two possible specializations for parse_impl<char> and
// parse_impl<wchar_t>
template <>
struct parse_impl<char>
{
template <typename Iterator>
static bool call(Iterator& first, Iterator last, char& expr)
{
return qi::parse(first, last, create_parser<char>(), expr);
}
template <typename Iterator>
static bool call(Iterator& first, Iterator last, char const&)
{
return qi::parse(first, last, create_parser<char>());
}
};
template <>
struct parse_impl<wchar_t>
{
template <typename Iterator>
static bool call(Iterator& first, Iterator last, wchar_t& expr)
{
return qi::parse(first, last, create_parser<wchar_t>(), expr);
}
template <typename Iterator>
static bool call(Iterator& first, Iterator last, wchar_t const&)
{
return qi::parse(first, last, create_parser<wchar_t>());
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct phrase_parse_impl<Expr
, typename enable_if<
mpl::and_<
traits::meta_create_exists<qi::domain, Expr>
, mpl::not_<traits::matches<qi::domain, Expr> > >
>::type>
{
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, Expr& expr
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<Expr>()
, skipper, post_skip, expr);
}
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, Expr const& expr
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<Expr>()
, skipper, post_skip, const_cast<Expr&>(expr));
}
};
// the following specializations are needed to explicitly disambiguate
// the two possible specializations for phrase_parse_impl<char> and
// phrase_parse_impl<wchar_t>
template <>
struct phrase_parse_impl<char>
{
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, char& expr
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<char>()
, skipper, post_skip, expr);
}
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, char const&
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<char>()
, skipper, post_skip);
}
};
template <>
struct phrase_parse_impl<wchar_t>
{
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, wchar_t& expr
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<wchar_t>()
, skipper, post_skip, expr);
}
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, wchar_t const&
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<wchar_t>()
, skipper, post_skip);
}
};
}}}}
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr>
inline bool
parse(
Iterator& first
, Iterator last
, Expr& expr)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
return detail::parse_impl<Expr>::call(first, last, expr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr, typename Skipper>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
return detail::phrase_parse_impl<Expr>::call(
first, last, expr, skipper, post_skip);
}
}}}
#endif
@@ -0,0 +1,382 @@
/*=============================================================================
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_PASS_CONTAINER_JANUARY_06_2009_0802PM)
#define SPIRIT_PASS_CONTAINER_JANUARY_06_2009_0802PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
// Helper meta-function allowing to evaluate weak substitutability and
// negate the result if the predicate (Sequence) is not true
template <typename Sequence, typename Attribute, typename ValueType>
struct negate_weak_substitute_if_not
: mpl::if_<
Sequence
, typename traits::is_weak_substitute<Attribute, ValueType>::type
, typename mpl::not_<
traits::is_weak_substitute<Attribute, ValueType>
>::type>
{};
// pass_through_container: utility to check decide whether a provided
// container attribute needs to be passed through to the current component
// or of we need to split the container by passing along instances of its
// value type
// if the expected attribute of the current component is neither a Fusion
// sequence nor a container, we will pass through the provided container
// only if its value type is not compatible with the component
template <typename Container, typename ValueType, typename Attribute
, typename Sequence, typename Enable = void>
struct pass_through_container_base
: negate_weak_substitute_if_not<Sequence, Attribute, ValueType>
{};
// Specialization for fusion sequences, in this case we check whether all
// the types in the sequence are convertible to the lhs attribute.
//
// We return false if the rhs attribute itself is a fusion sequence, which
// is compatible with the LHS sequence (we want to pass through this
// attribute without it being split apart).
template <typename Container, typename ValueType, typename Attribute
, typename Sequence = mpl::true_>
struct not_compatible_element
: mpl::and_<
negate_weak_substitute_if_not<Sequence, Attribute, Container>
, negate_weak_substitute_if_not<Sequence, Attribute, ValueType> >
{};
// If the value type of the container is not a Fusion sequence, we pass
// through the container if each of the elements of the Attribute
// sequence is compatible with either the container or its value type.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence
, bool IsSequence = fusion::traits::is_sequence<ValueType>::value>
struct pass_through_container_fusion_sequence
{
typedef typename mpl::find_if<
Attribute, not_compatible_element<Container, ValueType, mpl::_1>
>::type iter;
typedef typename mpl::end<Attribute>::type end;
typedef typename is_same<iter, end>::type type;
};
// If both, the Attribute and the value type of the provided container
// are Fusion sequences, we pass the container only if the two
// sequences are not compatible.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container_fusion_sequence<
Container, ValueType, Attribute, Sequence, true>
{
typedef typename mpl::find_if<
Attribute
, not_compatible_element<Container, ValueType, mpl::_1, Sequence>
>::type iter;
typedef typename mpl::end<Attribute>::type end;
typedef typename is_same<iter, end>::type type;
};
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container_base<Container, ValueType, Attribute
, Sequence
, typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
: pass_through_container_fusion_sequence<
Container, ValueType, Attribute, Sequence>
{};
// Specialization for containers
//
// If the value type of the attribute of the current component is not
// a Fusion sequence, we have to pass through the provided container if
// both are compatible.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence, typename AttributeValueType
, bool IsSequence = fusion::traits::is_sequence<AttributeValueType>::value>
struct pass_through_container_container
: mpl::or_<
traits::is_weak_substitute<Attribute, Container>
, traits::is_weak_substitute<AttributeValueType, Container> >
{};
// If the value type of the exposed container attribute is a Fusion
// sequence, we use the already existing logic for those.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence, typename AttributeValueType>
struct pass_through_container_container<
Container, ValueType, Attribute, Sequence, AttributeValueType, true>
: pass_through_container_fusion_sequence<
Container, ValueType, AttributeValueType, Sequence>
{};
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container_base<
Container, ValueType, Attribute, Sequence
, typename enable_if<traits::is_container<Attribute> >::type>
: detail::pass_through_container_container<
Container, ValueType, Attribute, Sequence
, typename traits::container_value<Attribute>::type>
{};
// Specialization for exposed optional attributes
//
// If the type embedded in the exposed optional is not a Fusion
// sequence we pass through the container attribute if it is compatible
// either to the optionals embedded type or to the containers value
// type.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence
, bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
struct pass_through_container_optional
: mpl::or_<
traits::is_weak_substitute<Attribute, Container>
, traits::is_weak_substitute<Attribute, ValueType> >
{};
// If the embedded type of the exposed optional attribute is a Fusion
// sequence, we use the already existing logic for those.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container_optional<
Container, ValueType, Attribute, Sequence, true>
: pass_through_container_fusion_sequence<
Container, ValueType, Attribute, Sequence>
{};
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container
: pass_through_container_base<Container, ValueType, Attribute, Sequence>
{};
// Handle optional attributes
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container<
Container, ValueType, boost::optional<Attribute>, Sequence>
: pass_through_container_optional<
Container, ValueType, Attribute, Sequence>
{};
// If both, the containers value type and the exposed attribute type are
// optionals we are allowed to pass through the container only if the
// embedded types of those optionals are not compatible.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container<
Container, boost::optional<ValueType>, boost::optional<Attribute>
, Sequence>
: mpl::not_<traits::is_weak_substitute<Attribute, ValueType> >
{};
// Specialization for exposed variant attributes
//
// We pass through the container attribute if at least one of the embedded
// types in the variant requires to pass through the attribute
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
template <typename Container, typename ValueType, typename Sequence
, typename T>
struct pass_through_container<Container, ValueType, boost::variant<T>
, Sequence>
: pass_through_container<Container, ValueType, T, Sequence>
{};
template <typename Container, typename ValueType, typename Sequence
, typename T0, typename ...TN>
struct pass_through_container<Container, ValueType
, boost::variant<T0, TN...>, Sequence>
: mpl::bool_<pass_through_container<
Container, ValueType, T0, Sequence
>::type::value || pass_through_container<
Container, ValueType, boost::variant<TN...>, Sequence
>::type::value>
{};
#else
#define BOOST_SPIRIT_PASS_THROUGH_CONTAINER(z, N, _) \
pass_through_container<Container, ValueType, \
BOOST_PP_CAT(T, N), Sequence>::type::value || \
/***/
// make sure unused variant parameters do not affect the outcome
template <typename Container, typename ValueType, typename Sequence>
struct pass_through_container<Container, ValueType
, boost::detail::variant::void_, Sequence>
: mpl::false_
{};
template <typename Container, typename ValueType, typename Sequence
, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct pass_through_container<Container, ValueType
, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Sequence>
: mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
, BOOST_SPIRIT_PASS_THROUGH_CONTAINER, _) false>
{};
#undef BOOST_SPIRIT_PASS_THROUGH_CONTAINER
#endif
}}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// forwarding customization point for domain qi::domain
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container<
Container, ValueType, Attribute, Sequence, qi::domain>
: qi::detail::pass_through_container<
Container, ValueType, Attribute, Sequence>
{};
}}}
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// This function handles the case where the attribute (Attr) given
// the sequence is an STL container. This is a wrapper around F.
// The function F does the actual parsing.
template <typename F, typename Attr, typename Sequence>
struct pass_container
{
typedef typename F::context_type context_type;
typedef typename F::iterator_type iterator_type;
pass_container(F const& f_, Attr& attr_)
: f(f_), attr(attr_) {}
// this is for the case when the current element exposes an attribute
// which is pushed back onto the container
template <typename Component>
bool dispatch_container(Component const& component, mpl::false_) const
{
// synthesized attribute needs to be default constructed
typename traits::container_value<Attr>::type val =
typename traits::container_value<Attr>::type();
iterator_type save = f.first;
bool r = f(component, val);
if (!r)
{
// push the parsed value into our attribute
r = !traits::push_back(attr, val);
if (r)
f.first = save;
}
return r;
}
// this is for the case when the current element is able to handle an
// attribute which is a container itself, this element will push its
// data directly into the attribute container
template <typename Component>
bool dispatch_container(Component const& component, mpl::true_) const
{
return f(component, attr);
}
///////////////////////////////////////////////////////////////////////
// this is for the case when the current element doesn't expect an
// attribute
template <typename Component>
bool dispatch_attribute(Component const& component, mpl::false_) const
{
return f(component, unused);
}
// the current element expects an attribute
template <typename Component>
bool dispatch_attribute(Component const& component, mpl::true_) const
{
typedef typename traits::container_value<Attr>::type value_type;
typedef typename traits::attribute_of<
Component, context_type, iterator_type>::type
rhs_attribute;
// this predicate detects, whether the attribute of the current
// element is a substitute for the value type of the container
// attribute
typedef mpl::and_<
traits::handles_container<
Component, Attr, context_type, iterator_type>
, traits::pass_through_container<
Attr, value_type, rhs_attribute, Sequence, qi::domain>
> predicate;
return dispatch_container(component, predicate());
}
// Dispatches to dispatch_main depending on the attribute type
// of the Component
template <typename Component>
bool operator()(Component const& component) const
{
// we need to dispatch depending on the type of the attribute
// of the current element (component). If this is has no attribute
// we shouldn't pass an attribute at all.
typedef typename traits::not_is_unused<
typename traits::attribute_of<
Component, context_type, iterator_type
>::type
>::type predicate;
// ensure the attribute is actually a container type
traits::make_container(attr);
return dispatch_attribute(component, predicate());
}
F f;
Attr& attr;
private:
// silence MSVC warning C4512: assignment operator could not be generated
pass_container& operator= (pass_container const&);
};
///////////////////////////////////////////////////////////////////////////
// Utility function to make a pass_container for container components
// (kleene, list, plus, repeat)
template <typename F, typename Attr>
inline pass_container<F, Attr, mpl::false_>
make_pass_container(F const& f, Attr& attr)
{
return pass_container<F, Attr, mpl::false_>(f, attr);
}
// Utility function to make a pass_container for sequences
template <typename F, typename Attr>
inline pass_container<F, Attr, mpl::true_>
make_sequence_pass_container(F const& f, Attr& attr)
{
return pass_container<F, Attr, mpl::true_>(f, attr);
}
}}}}
#endif
@@ -0,0 +1,70 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_PASS_FUNCTION_FEBRUARY_05_2007_1138AM)
#define SPIRIT_PASS_FUNCTION_FEBRUARY_05_2007_1138AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/optional.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Iterator, typename Context, typename Skipper>
struct pass_function
{
pass_function(
Iterator& first_, Iterator const& last_
, Context& context_, Skipper const& skipper_)
: first(first_)
, last(last_)
, context(context_)
, skipper(skipper_)
{
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, Attribute& attr)
{
// return true if the parser succeeds
return component.parse(first, last, context, skipper, attr);
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, boost::optional<Attribute>& attr)
{
// return true if the parser succeeds
Attribute val;
if (component.parse(first, last, context, skipper, val))
{
attr = val;
return true;
}
return false;
}
template <typename Component>
bool operator()(Component const& component)
{
// return true if the parser succeeds
return component.parse(first, last, context, skipper, unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
private:
// silence MSVC warning C4512: assignment operator could not be generated
pass_function& operator= (pass_function const&);
};
}}}}
#endif
@@ -0,0 +1,88 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_PERMUTE_FUNCTION_MARCH_13_2007_1129AM)
#define SPIRIT_PERMUTE_FUNCTION_MARCH_13_2007_1129AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/optional.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Iterator, typename Context, typename Skipper>
struct permute_function
{
permute_function(
Iterator& first_, Iterator const& last_
, Context& context_, Skipper const& skipper_)
: first(first_)
, last(last_)
, context(context_)
, skipper(skipper_)
{
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, Attribute& attr)
{
// return true if the parser succeeds and the slot is not yet taken
if (!*taken && component.parse(first, last, context, skipper, attr))
{
*taken = true;
++taken;
return true;
}
++taken;
return false;
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, boost::optional<Attribute>& attr)
{
// return true if the parser succeeds and the slot is not yet taken
Attribute val;
if (!*taken && component.parse(first, last, context, skipper, val))
{
attr = val;
*taken = true;
++taken;
return true;
}
++taken;
return false;
}
template <typename Component>
bool operator()(Component const& component)
{
// return true if the parser succeeds and the slot is not yet taken
if (!*taken && component.parse(first, last, context, skipper, unused))
{
*taken = true;
++taken;
return true;
}
++taken;
return false;
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
bool* taken;
private:
// silence MSVC warning C4512: assignment operator could not be generated
permute_function& operator= (permute_function const&);
};
}}}}
#endif
@@ -0,0 +1,89 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_STRING_PARSE_APR_18_2006_1125PM)
#define BOOST_SPIRIT_STRING_PARSE_APR_18_2006_1125PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/detail/assign_to.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Char, typename Iterator, typename Attribute>
inline bool string_parse(
Char const* str
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
Char ch = *str;
for (; !!ch; ++i)
{
if (i == last || (ch != *i))
return false;
ch = *++str;
}
spirit::traits::assign_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute>
inline bool string_parse(
String const& str
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
typename String::const_iterator stri = str.begin();
typename String::const_iterator str_last = str.end();
for (; stri != str_last; ++stri, ++i)
if (i == last || (*stri != *i))
return false;
spirit::traits::assign_to(first, i, attr);
first = i;
return true;
}
template <typename Char, typename Iterator, typename Attribute>
inline bool string_parse(
Char const* uc_i, Char const* lc_i
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
spirit::traits::assign_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute>
inline bool string_parse(
String const& ucstr, String const& lcstr
, Iterator& first, Iterator const& last, Attribute& attr)
{
typename String::const_iterator uc_i = ucstr.begin();
typename String::const_iterator uc_last = ucstr.end();
typename String::const_iterator lc_i = lcstr.begin();
Iterator i = first;
for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
spirit::traits::assign_to(first, i, attr);
first = i;
return true;
}
}}}}
#endif
@@ -0,0 +1,63 @@
// 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(BOOST_SPIRIT_QI_UNUSED_SKIPPER_JUL_25_2009_0921AM)
#define BOOST_SPIRIT_QI_UNUSED_SKIPPER_JUL_25_2009_0921AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Skipper>
struct unused_skipper : unused_type
{
unused_skipper(Skipper const& skipper_)
: skipper(skipper_) {}
Skipper const& skipper;
private:
// silence MSVC warning C4512: assignment operator could not be generated
unused_skipper& operator= (unused_skipper const&);
};
template <typename Skipper>
struct is_unused_skipper
: mpl::false_ {};
template <typename Skipper>
struct is_unused_skipper<unused_skipper<Skipper> >
: mpl::true_ {};
template <>
struct is_unused_skipper<unused_type>
: mpl::true_ {};
// If a surrounding lexeme[] directive was specified, the current
// skipper is of the type unused_skipper. In this case we
// re-activate the skipper which was active before the skip[]
// directive.
template <typename Skipper>
inline Skipper const&
get_skipper(unused_skipper<Skipper> const& u)
{
return u.skipper;
}
// If no surrounding lexeme[] directive was specified we keep what we got.
template <typename Skipper>
inline Skipper const&
get_skipper(Skipper const& u)
{
return u;
}
}}}}
#endif
@@ -0,0 +1,26 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_DIRECTIVE_FEBRUARY_05_2007_0313PM)
#define BOOST_SPIRIT_DIRECTIVE_FEBRUARY_05_2007_0313PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/directive/as.hpp>
#include <boost/spirit/home/qi/directive/encoding.hpp>
#include <boost/spirit/home/qi/directive/hold.hpp>
#include <boost/spirit/home/qi/directive/lexeme.hpp>
#include <boost/spirit/home/qi/directive/no_skip.hpp>
#include <boost/spirit/home/qi/directive/matches.hpp>
#include <boost/spirit/home/qi/directive/no_case.hpp>
#include <boost/spirit/home/qi/directive/omit.hpp>
#include <boost/spirit/home/qi/directive/raw.hpp>
#include <boost/spirit/home/qi/directive/repeat.hpp>
#include <boost/spirit/home/qi/directive/skip.hpp>
#endif
@@ -0,0 +1,178 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2010 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_AS_DECEMBER_6_2010_1013AM)
#define SPIRIT_AS_DECEMBER_6_2010_1013AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/range/iterator_range.hpp>
#include <string>
namespace boost { namespace spirit { namespace qi
{
template <typename T>
struct as
: stateful_tag_type<T, tag::as>
{
//~ BOOST_SPIRIT_ASSERT_MSG(
//~ (traits::is_container<T>::type::value),
//~ error_type_must_be_a_container,
//~ (T));
};
}}}
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables as_string[...]
template <>
struct use_directive<qi::domain, tag::as_string>
: mpl::true_ {};
// enables as_wstring[...]
template <>
struct use_directive<qi::domain, tag::as_wstring>
: mpl::true_ {};
// enables as<T>[...]
template <typename T>
struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> >
: mpl::true_
{};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::as_string;
using spirit::as_wstring;
#endif
using spirit::as_string_type;
using spirit::as_wstring_type;
template <typename Subject, typename T>
struct as_directive : unary_parser<as_directive<Subject, T> >
{
typedef Subject subject_type;
as_directive(Subject const& subject_)
: subject(subject_) {}
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
{
Iterator i = first;
T as_attr;
if (subject.parse(i, last, context, skipper, as_attr))
{
spirit::traits::assign_to(as_attr, attr_);
first = i;
return true;
}
return false;
}
template <typename Iterator, typename Context, typename Skipper>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, T& attr_) const
{
Iterator i = first;
if (subject.parse(i, last, context, skipper, attr_))
{
first = i;
return true;
}
return false;
}
template <typename Context>
info what(Context& context) const
{
return info("as", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::as_string, Subject, Modifiers>
{
typedef as_directive<Subject, std::string> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
template <typename Subject, typename Modifiers>
struct make_directive<tag::as_wstring, Subject, Modifiers>
{
typedef as_directive<Subject, std::basic_string<wchar_t> > result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
template <typename T, typename Subject, typename Modifiers>
struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
{
typedef as_directive<Subject, T> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T>
struct has_semantic_action<qi::as_directive<Subject, T> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::as_directive<Subject, T>, Attribute
, Context, Iterator>
: mpl::false_ {};
}}}
#endif
@@ -0,0 +1,32 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_ENCODING_MARCH_05_2010_0528PM)
#define SPIRIT_ENCODING_MARCH_05_2010_0528PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding>
struct use_directive<
qi::domain, tag::char_code<tag::encoding, CharEncoding> > // enables encoding
: mpl::true_ {};
template <typename CharEncoding>
struct is_modifier_directive<qi::domain, tag::char_code<tag::encoding, CharEncoding> >
: mpl::true_ {};
}}
#endif
@@ -0,0 +1,109 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_HOLD_FEBRUARY_6_2010_0917AM)
#define SPIRIT_HOLD_FEBRUARY_6_2010_0917AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<qi::domain, tag::hold> // enables hold
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::hold;
#endif
using spirit::hold_type;
template <typename Subject>
struct hold_directive : unary_parser<hold_directive<Subject> >
{
typedef Subject subject_type;
hold_directive(Subject const& subject_)
: subject(subject_) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
traits::attribute_of<subject_type, Context, Iterator>::type
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
{
Attribute copy(attr_);
if (subject.parse(first, last, context, skipper, copy))
{
traits::swap_impl(copy, attr_);
return true;
}
return false;
}
template <typename Context>
info what(Context& context) const
{
return info("hold", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::hold, Subject, Modifiers>
{
typedef hold_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::hold_directive<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::hold_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,120 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_LEXEME_MARCH_24_2007_0802AM)
#define SPIRIT_LEXEME_MARCH_24_2007_0802AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<qi::domain, tag::lexeme> // enables lexeme
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lexeme;
#endif
using spirit::lexeme_type;
template <typename Subject>
struct lexeme_directive : unary_parser<lexeme_directive<Subject> >
{
typedef Subject subject_type;
lexeme_directive(Subject const& subject_)
: subject(subject_) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
traits::attribute_of<subject_type, Context, Iterator>::type
type;
};
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
typename disable_if<detail::is_unused_skipper<Skipper>, bool>::type
parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
qi::skip_over(first, last, skipper);
return subject.parse(first, last, context
, detail::unused_skipper<Skipper>(skipper), attr_);
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
typename enable_if<detail::is_unused_skipper<Skipper>, bool>::type
parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
// no need to pre-skip if skipper is unused
//- qi::skip_over(first, last, skipper);
return subject.parse(first, last, context
, skipper, attr_);
}
template <typename Context>
info what(Context& context) const
{
return info("lexeme", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::lexeme, Subject, Modifiers>
{
typedef lexeme_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::lexeme_directive<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::lexeme_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,108 @@
/*=============================================================================
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_MATCHES_JAN_07_2010_0745PM)
#define SPIRIT_MATCHES_JAN_07_2010_0745PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<qi::domain, tag::matches> // enables matches
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::matches;
#endif
using spirit::matches_type;
///////////////////////////////////////////////////////////////////////////
// matches_directive returns whether the embedded parser matched
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct matches_directive : unary_parser<matches_directive<Subject> >
{
typedef Subject subject_type;
matches_directive(Subject const& subject_)
: subject(subject_) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef bool 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
{
bool result = subject.parse(first, last, context, skipper, unused);
spirit::traits::assign_to(result, attr_);
return true;
}
template <typename Context>
info what(Context& context) const
{
return info("matches", subject.what(context));
}
Subject subject;
private:
// silence MSVC warning C4512: assignment operator could not be generated
matches_directive& operator= (matches_directive const&);
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::matches, Subject, Modifiers>
{
typedef matches_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::matches_directive<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::matches_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,32 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_NO_CASE_OCTOBER_25_2008_0424PM)
#define SPIRIT_NO_CASE_OCTOBER_25_2008_0424PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <typename CharEncoding>
struct use_directive<
qi::domain, tag::char_code<tag::no_case, CharEncoding> > // enables no_case
: mpl::true_ {};
template <typename CharEncoding>
struct is_modifier_directive<qi::domain, tag::char_code<tag::no_case, CharEncoding> >
: mpl::true_ {};
}}
#endif
@@ -0,0 +1,120 @@
/*=============================================================================
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_NO_SKIP_JAN_16_2010_0802PM)
#define SPIRIT_NO_SKIP_JAN_16_2010_0802PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<qi::domain, tag::no_skip> // enables no_skip
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::no_skip;
#endif
using spirit::no_skip_type;
// same as lexeme[], but does not pre-skip
template <typename Subject>
struct no_skip_directive : unary_parser<no_skip_directive<Subject> >
{
typedef Subject subject_type;
no_skip_directive(Subject const& subject_)
: subject(subject_) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
traits::attribute_of<subject_type, Context, Iterator>::type
type;
};
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
typename disable_if<detail::is_unused_skipper<Skipper>, bool>::type
parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
return subject.parse(first, last, context
, detail::unused_skipper<Skipper>(skipper), attr_);
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
typename enable_if<detail::is_unused_skipper<Skipper>, bool>::type
parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
return subject.parse(first, last, context
, skipper, attr_);
}
template <typename Context>
info what(Context& context) const
{
return info("no_skip", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::no_skip, Subject, Modifiers>
{
typedef no_skip_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::no_skip_directive<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::no_skip_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,107 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_OMIT_MARCH_24_2007_0802AM)
#define SPIRIT_OMIT_MARCH_24_2007_0802AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<qi::domain, tag::omit> // enables omit
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::omit;
#endif
using spirit::omit_type;
///////////////////////////////////////////////////////////////////////////
// omit_directive forces the attribute of subject parser
// to be unused_type
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct omit_directive : unary_parser<omit_directive<Subject> >
{
typedef Subject subject_type;
omit_directive(Subject const& subject_)
: subject(subject_) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef unused_type 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
{
return subject.parse(first, last, context, skipper, attr_);
}
template <typename Context>
info what(Context& context) const
{
return info("omit", subject.what(context));
}
Subject subject;
private:
// silence MSVC warning C4512: assignment operator could not be generated
omit_directive& operator= (omit_directive const&);
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::omit, Subject, Modifiers>
{
typedef omit_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::omit_directive<Subject> >
: mpl::false_ {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::omit_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,111 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_RAW_APRIL_9_2007_0912AM)
#define SPIRIT_RAW_APRIL_9_2007_0912AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/range/iterator_range.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<qi::domain, tag::raw> // enables raw
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::raw;
#endif
using spirit::raw_type;
template <typename Subject>
struct raw_directive : unary_parser<raw_directive<Subject> >
{
typedef Subject subject_type;
raw_directive(Subject const& subject_)
: subject(subject_) {}
template <typename Context, typename Iterator>
struct attribute
{
typedef iterator_range<Iterator> 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
{
qi::skip_over(first, last, skipper);
Iterator i = first;
if (subject.parse(i, last, context, skipper, unused))
{
spirit::traits::assign_to(first, i, attr_);
first = i;
return true;
}
return false;
}
template <typename Context>
info what(Context& context) const
{
return info("raw", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::raw, Subject, Modifiers>
{
typedef raw_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::raw_directive<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::raw_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,297 @@
/*=============================================================================
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_REPEAT_NOVEMBER_14_2008_1148AM)
#define SPIRIT_REPEAT_NOVEMBER_14_2008_1148AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/qi/operator/kleene.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/qi/detail/fail_function.hpp>
#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/at.hpp>
#include <vector>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<qi::domain, tag::repeat> // enables repeat[p]
: mpl::true_ {};
template <typename T>
struct use_directive<qi::domain
, terminal_ex<tag::repeat // enables repeat(exact)[p]
, fusion::vector1<T> >
> : mpl::true_ {};
template <typename T>
struct use_directive<qi::domain
, terminal_ex<tag::repeat // enables repeat(min, max)[p]
, fusion::vector2<T, T> >
> : mpl::true_ {};
template <typename T>
struct use_directive<qi::domain
, terminal_ex<tag::repeat // enables repeat(min, inf)[p]
, fusion::vector2<T, inf_type> >
> : mpl::true_ {};
template <> // enables *lazy* repeat(exact)[p]
struct use_lazy_directive<
qi::domain
, tag::repeat
, 1 // arity
> : mpl::true_ {};
template <> // enables *lazy* repeat(min, max)[p]
struct use_lazy_directive< // and repeat(min, inf)[p]
qi::domain
, tag::repeat
, 2 // arity
> : mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::repeat;
using spirit::inf;
#endif
using spirit::repeat_type;
using spirit::inf_type;
template <typename T>
struct exact_iterator // handles repeat(exact)[p]
{
exact_iterator(T const exact_)
: exact(exact_) {}
typedef T type;
T start() const { return 0; }
bool got_max(T i) const { return i >= exact; }
bool got_min(T i) const { return i >= exact; }
T const exact;
private:
// silence MSVC warning C4512: assignment operator could not be generated
exact_iterator& operator= (exact_iterator const&);
};
template <typename T>
struct finite_iterator // handles repeat(min, max)[p]
{
finite_iterator(T const min_, T const max_)
: min BOOST_PREVENT_MACRO_SUBSTITUTION (min_)
, max BOOST_PREVENT_MACRO_SUBSTITUTION (max_) {}
typedef T type;
T start() const { return 0; }
bool got_max(T i) const { return i >= max; }
bool got_min(T i) const { return i >= min; }
T const min;
T const max;
private:
// silence MSVC warning C4512: assignment operator could not be generated
finite_iterator& operator= (finite_iterator const&);
};
template <typename T>
struct infinite_iterator // handles repeat(min, inf)[p]
{
infinite_iterator(T const min_)
: min BOOST_PREVENT_MACRO_SUBSTITUTION (min_) {}
typedef T type;
T start() const { return 0; }
bool got_max(T /*i*/) const { return false; }
bool got_min(T i) const { return i >= min; }
T const min;
private:
// silence MSVC warning C4512: assignment operator could not be generated
infinite_iterator& operator= (infinite_iterator const&);
};
template <typename Subject, typename LoopIter>
struct repeat_parser : unary_parser<repeat_parser<Subject, LoopIter> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
// Build a std::vector from the subject's attribute. Note
// that build_std_vector may return unused_type if the
// subject's attribute is an unused_type.
typedef typename
traits::build_std_vector<
typename traits::attribute_of<
Subject, Context, Iterator>::type
>::type
type;
};
repeat_parser(Subject const& subject_, LoopIter const& iter_)
: subject(subject_), iter(iter_) {}
template <typename F>
bool parse_container(F f) const
{
typename LoopIter::type i = iter.start();
for (/**/; !iter.got_min(i); ++i)
{
if (f (subject))
return false;
}
// parse some more up to the maximum specified
typename F::iterator_type save = f.f.first;
for (/**/; !iter.got_max(i); ++i)
{
if (f (subject))
break;
save = f.f.first;
}
f.f.first = save;
return true;
}
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::fail_function<Iterator, Context, Skipper>
fail_function;
// ensure the attribute is actually a container type
traits::make_container(attr_);
Iterator iter_local = first;
fail_function f(iter_local, last, context, skipper);
if (!parse_container(detail::make_pass_container(f, attr_)))
return false;
first = f.first;
return true;
}
template <typename Context>
info what(Context& context) const
{
return info("repeat", subject.what(context));
}
Subject subject;
LoopIter iter;
private:
// silence MSVC warning C4512: assignment operator could not be generated
repeat_parser& operator= (repeat_parser const&);
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::repeat, Subject, Modifiers>
{
typedef kleene<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::repeat, fusion::vector1<T> >, Subject, Modifiers>
{
typedef exact_iterator<T> iterator_type;
typedef repeat_parser<Subject, iterator_type> result_type;
template <typename Terminal>
result_type operator()(
Terminal const& term, Subject const& subject, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args));
}
};
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::repeat, fusion::vector2<T, T> >, Subject, Modifiers>
{
typedef finite_iterator<T> iterator_type;
typedef repeat_parser<Subject, iterator_type> result_type;
template <typename Terminal>
result_type operator()(
Terminal const& term, Subject const& subject, unused_type) const
{
return result_type(subject,
iterator_type(
fusion::at_c<0>(term.args)
, fusion::at_c<1>(term.args)
)
);
}
};
template <typename T, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::repeat
, fusion::vector2<T, inf_type> >, Subject, Modifiers>
{
typedef infinite_iterator<T> iterator_type;
typedef repeat_parser<Subject, iterator_type> result_type;
template <typename Terminal>
result_type operator()(
Terminal const& term, Subject const& subject, unused_type) const
{
return result_type(subject, fusion::at_c<0>(term.args));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename LoopIter>
struct has_semantic_action<qi::repeat_parser<Subject, LoopIter> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename LoopIter, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::repeat_parser<Subject, LoopIter>
, Attribute, Context, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,202 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_SKIP_JANUARY_26_2008_0422PM)
#define SPIRIT_SKIP_JANUARY_26_2008_0422PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/qi/operator/kleene.hpp>
#include <boost/spirit/home/qi/directive/lexeme.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<qi::domain, tag::skip> // enables skip[p]
: mpl::true_ {};
template <typename T>
struct use_directive<qi::domain
, terminal_ex<tag::skip // enables skip(s)[p]
, fusion::vector1<T> >
> : boost::spirit::traits::matches<qi::domain, T> {};
template <> // enables *lazy* skip(s)[p]
struct use_lazy_directive<
qi::domain
, tag::skip
, 1 // arity
> : mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::skip;
#endif
using spirit::skip_type;
template <typename Subject>
struct reskip_parser : unary_parser<reskip_parser<Subject> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
traits::attribute_of<Subject, Context, Iterator>::type
type;
};
reskip_parser(Subject const& subject_)
: subject(subject_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
typename enable_if<detail::is_unused_skipper<Skipper>, bool>::type
parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& u // --> The skipper is reintroduced
, Attribute& attr_) const
{
return subject.parse(first, last, context
, detail::get_skipper(u), attr_);
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
typename disable_if<detail::is_unused_skipper<Skipper>, bool>::type
parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
return subject.parse(first, last, context
, skipper, attr_);
}
template <typename Context>
info what(Context& context) const
{
return info("skip", subject.what(context));
}
Subject subject;
};
template <typename Subject, typename Skipper>
struct skip_parser : unary_parser<skip_parser<Subject, Skipper> >
{
typedef Subject subject_type;
typedef Skipper skipper_type;
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
traits::attribute_of<Subject, Context, Iterator>::type
type;
};
skip_parser(Subject const& subject_, Skipper const& skipper_)
: subject(subject_), skipper(skipper_) {}
template <typename Iterator, typename Context
, typename Skipper_, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper_ const& //skipper --> bypass the supplied skipper
, Attribute& attr_) const
{
return subject.parse(first, last, context, skipper, attr_);
}
template <typename Context>
info what(Context& context) const
{
return info("skip", subject.what(context));
}
Subject subject;
Skipper skipper;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::skip, Subject, Modifiers>
{
typedef reskip_parser<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
template <typename Skipper, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::skip, fusion::vector1<Skipper> >, Subject, Modifiers>
{
typedef typename
result_of::compile<qi::domain, Skipper, Modifiers>::type
skipper_type;
typedef skip_parser<Subject, skipper_type> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<qi::domain>(fusion::at_c<0>(term.args), modifiers));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::reskip_parser<Subject> >
: unary_has_semantic_action<Subject> {};
template <typename Subject, typename Skipper>
struct has_semantic_action<qi::skip_parser<Subject, Skipper> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::reskip_parser<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
template <typename Subject, typename Skipper, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::skip_parser<Subject, Skipper>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,74 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_DOMAIN_JANUARY_29_2007_0954AM)
#define BOOST_SPIRIT_DOMAIN_JANUARY_29_2007_0954AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/meta_compiler.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/spirit/home/support/context.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/cat.hpp>
namespace boost { namespace spirit { namespace qi
{
// qi's domain
struct domain {};
// bring in some of spirit parts into spirit::qi
using spirit::unused;
using spirit::unused_type;
using spirit::compile;
using spirit::info;
// You can bring these in with the using directive
// without worrying about bringing in too much.
namespace labels
{
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
using spirit::_pass_type;
using spirit::_val_type;
using spirit::_a_type;
using spirit::_b_type;
using spirit::_c_type;
using spirit::_d_type;
using spirit::_e_type;
using spirit::_f_type;
using spirit::_g_type;
using spirit::_h_type;
using spirit::_i_type;
using spirit::_j_type;
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::_pass;
using spirit::_val;
using spirit::_a;
using spirit::_b;
using spirit::_c;
using spirit::_d;
using spirit::_e;
using spirit::_f;
using spirit::_g;
using spirit::_h;
using spirit::_i;
using spirit::_j;
#endif
}
}}}
#endif
@@ -0,0 +1,16 @@
// 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(BOOST_SPIRIT_QI_MATCH_DEC_02_2009_0749PM)
#define BOOST_SPIRIT_QI_MATCH_DEC_02_2009_0749PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/stream/match_manip.hpp>
#include <boost/spirit/home/qi/stream/match_manip_attr.hpp>
#endif
@@ -0,0 +1,16 @@
// 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(BOOST_SPIRIT_QI_MATCH_AUTO_DEC_02_2009_0750PM)
#define BOOST_SPIRIT_QI_MATCH_AUTO_DEC_02_2009_0750PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/stream/match_manip.hpp>
#include <boost/spirit/home/qi/stream/detail/match_manip_auto.hpp>
#endif
@@ -0,0 +1,177 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_META_COMPILER_OCTOBER_16_2008_0347PM)
#define BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_0347PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/meta_compiler.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/string_traits.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/fusion/include/at.hpp>
namespace boost { namespace spirit
{
template <typename T>
struct use_terminal<qi::domain, T
, typename enable_if<traits::is_parser<T> >::type> // enables parsers
: mpl::true_ {};
namespace qi
{
template <typename T, typename Modifiers, typename Enable = void>
struct make_primitive // by default, return it as-is
{
typedef T result_type;
template <typename T_>
T_& operator()(T_& val, unused_type) const
{
return val;
}
template <typename T_>
T_ const& operator()(T_ const& val, unused_type) const
{
return val;
}
};
template <typename Tag, typename Elements
, typename Modifiers, typename Enable = void>
struct make_composite;
template <typename Directive, typename Body
, typename Modifiers, typename Enable = void>
struct make_directive
{
typedef Body result_type;
result_type operator()(unused_type, Body const& body, unused_type) const
{
return body; // By default, a directive simply returns its subject
}
};
}
// Qi primitive meta-compiler
template <>
struct make_component<qi::domain, proto::tag::terminal>
{
template <typename Sig>
struct result;
template <typename This, typename Elements, typename Modifiers>
struct result<This(Elements, Modifiers)>
{
typedef typename qi::make_primitive<
typename remove_const<typename Elements::car_type>::type,
typename remove_reference<Modifiers>::type>::result_type
type;
};
template <typename Elements, typename Modifiers>
typename result<make_component(Elements, Modifiers)>::type
operator()(Elements const& elements, Modifiers const& modifiers) const
{
typedef typename remove_const<typename Elements::car_type>::type term;
return qi::make_primitive<term, Modifiers>()(elements.car, modifiers);
}
};
// Qi composite meta-compiler
template <typename Tag>
struct make_component<qi::domain, Tag>
{
template <typename Sig>
struct result;
template <typename This, typename Elements, typename Modifiers>
struct result<This(Elements, Modifiers)>
{
typedef typename
qi::make_composite<Tag, Elements,
typename remove_reference<Modifiers>::type>::result_type
type;
};
template <typename Elements, typename Modifiers>
typename result<make_component(Elements, Modifiers)>::type
operator()(Elements const& elements, Modifiers const& modifiers) const
{
return qi::make_composite<Tag, Elements, Modifiers>()(
elements, modifiers);
}
};
// Qi function meta-compiler
template <>
struct make_component<qi::domain, proto::tag::function>
{
template <typename Sig>
struct result;
template <typename This, typename Elements, typename Modifiers>
struct result<This(Elements, Modifiers)>
{
typedef typename
qi::make_composite<
typename remove_const<typename Elements::car_type>::type,
typename Elements::cdr_type,
typename remove_reference<Modifiers>::type
>::result_type
type;
};
template <typename Elements, typename Modifiers>
typename result<make_component(Elements, Modifiers)>::type
operator()(Elements const& elements, Modifiers const& modifiers) const
{
return qi::make_composite<
typename remove_const<typename Elements::car_type>::type,
typename Elements::cdr_type,
Modifiers>()(elements.cdr, modifiers);
}
};
// Qi directive meta-compiler
template <>
struct make_component<qi::domain, tag::directive>
{
template <typename Sig>
struct result;
template <typename This, typename Elements, typename Modifiers>
struct result<This(Elements, Modifiers)>
{
typedef typename
qi::make_directive<
typename remove_const<typename Elements::car_type>::type,
typename remove_const<typename Elements::cdr_type::car_type>::type,
typename remove_reference<Modifiers>::type
>::result_type
type;
};
template <typename Elements, typename Modifiers>
typename result<make_component(Elements, Modifiers)>::type
operator()(Elements const& elements, Modifiers const& modifiers) const
{
return qi::make_directive<
typename remove_const<typename Elements::car_type>::type,
typename remove_const<typename Elements::cdr_type::car_type>::type,
Modifiers>()(elements.car, elements.cdr.car, modifiers);
}
};
}}
#endif
@@ -0,0 +1,21 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_NONTERMINAL_FEBRUARY_12_2007_1018AM)
#define BOOST_SPIRIT_NONTERMINAL_FEBRUARY_12_2007_1018AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/grammar.hpp>
#include <boost/spirit/home/qi/nonterminal/error_handler.hpp>
#include <boost/spirit/home/qi/nonterminal/debug_handler.hpp>
#include <boost/spirit/home/qi/nonterminal/simple_trace.hpp>
#include <boost/spirit/home/qi/nonterminal/success_handler.hpp>
#endif
@@ -0,0 +1,145 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_DEBUG_HANDLER_DECEMBER_05_2008_0734PM)
#define BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
#include <boost/spirit/home/qi/operator/expect.hpp>
#include <boost/function.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/out.hpp>
#include <iostream>
namespace boost { namespace spirit { namespace qi
{
template <
typename Iterator, typename Context
, typename Skipper, typename F>
struct debug_handler
{
typedef function<
bool(Iterator& first, Iterator const& last
, Context& context
, Skipper const& skipper
)>
function_type;
debug_handler(
function_type subject_
, F f_
, std::string const& rule_name_)
: subject(subject_)
, f(f_)
, rule_name(rule_name_)
{
}
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
f(first, last, context, pre_parse, rule_name);
try // subject might throw an exception
{
if (subject(first, last, context, skipper))
{
f(first, last, context, successful_parse, rule_name);
return true;
}
f(first, last, context, failed_parse, rule_name);
}
catch (expectation_failure<Iterator> const& e)
{
f(first, last, context, failed_parse, rule_name);
boost::throw_exception(e);
}
return false;
}
function_type subject;
F f;
std::string rule_name;
};
template <typename Iterator
, typename T1, typename T2, typename T3, typename T4, typename F>
void debug(rule<Iterator, T1, T2, T3, T4>& r, F f)
{
typedef rule<Iterator, T1, T2, T3, T4> rule_type;
typedef
debug_handler<
Iterator
, typename rule_type::context_type
, typename rule_type::skipper_type
, F>
debug_handler;
r.f = debug_handler(r.f, f, r.name());
}
struct simple_trace;
namespace detail
{
// This class provides an extra level of indirection through a
// template to produce the simple_trace type. This way, the use
// of simple_trace below is hidden behind a dependent type, so
// that compilers eagerly type-checking template definitions
// won't complain that simple_trace is incomplete.
template<typename T>
struct get_simple_trace
{
typedef simple_trace type;
};
}
template <typename Iterator
, typename T1, typename T2, typename T3, typename T4>
void debug(rule<Iterator, T1, T2, T3, T4>& r)
{
typedef rule<Iterator, T1, T2, T3, T4> rule_type;
typedef
debug_handler<
Iterator
, typename rule_type::context_type
, typename rule_type::skipper_type
, simple_trace>
debug_handler;
typedef typename qi::detail::get_simple_trace<Iterator>::type trace;
r.f = debug_handler(r.f, trace(), r.name());
}
}}}
///////////////////////////////////////////////////////////////////////////////
// Utility macro for easy enabling of rule and grammar debugging
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
#if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
#define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
#else
#define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
#endif
#endif
#define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
BOOST_SPIRIT_DEBUG_NODE(name); \
/***/
#define BOOST_SPIRIT_DEBUG_NODES(seq) \
BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \
/***/
#endif
@@ -0,0 +1,24 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)
#define BOOST_SPIRIT_DEBUG_HANDLER_STATE_APR_21_2010_0733PM
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost { namespace spirit { namespace qi
{
enum debug_handler_state
{
pre_parse
, successful_parse
, failed_parse
};
}}}
#endif
@@ -0,0 +1,53 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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)
==============================================================================*/
#ifndef BOOST_PP_IS_ITERATING
#include <boost/preprocessor/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define BOOST_PP_FILENAME_1 \
<boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, SPIRIT_ARGUMENTS_LIMIT)
#include BOOST_PP_ITERATE()
///////////////////////////////////////////////////////////////////////////////
//
// Preprocessor vertical repetition code
//
///////////////////////////////////////////////////////////////////////////////
#else // defined(BOOST_PP_IS_ITERATING)
#define N BOOST_PP_ITERATION()
template <BOOST_PP_ENUM_PARAMS(N, typename A)>
typename lazy_enable_if_c<
(params_size == N)
, proto::terminal<
spirit::qi::parameterized_nonterminal<
parameterized_subject_type
, fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> >
>
>::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& f)) const
{
typedef fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> vector_type;
typedef spirit::qi::parameterized_nonterminal<
parameterized_subject_type, vector_type> parameterized_type;
typedef typename proto::terminal<parameterized_type>::type result_type;
return result_type::make(
parameterized_type(
this->get_parameterized_subject()
, fusion::make_vector(BOOST_PP_ENUM_PARAMS(N, f)))
);
}
#undef N
#endif // defined(BOOST_PP_IS_ITERATING)
@@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2009 Francois Barel
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_PARAMETERIZED_AUGUST_09_2009_0539AM)
#define BOOST_SPIRIT_PARAMETERIZED_AUGUST_09_2009_0539AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/ref.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/qi/parser.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// parameterized_nonterminal: parser representing the invocation of a
// nonterminal, passing inherited attributes
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Params>
struct parameterized_nonterminal
: parser<parameterized_nonterminal<Subject, Params> >
{
parameterized_nonterminal(Subject const& subject, Params const& params_)
: ref(subject), params(params_)
{
}
template <typename Context, typename Iterator>
struct attribute
// Forward to subject.
: Subject::template attribute<Context, Iterator> {};
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
// Forward to subject, passing the additional
// params argument to parse.
return ref.get().parse(first, last, context, skipper, attr_, params);
}
template <typename Context>
info what(Context& context) const
{
// Forward to subject.
return ref.get().what(context);
}
boost::reference_wrapper<Subject const> ref;
Params params;
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Params, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::parameterized_nonterminal<Subject, Params>
, Attribute, Context, Iterator>
: handles_container<typename remove_const<Subject>::type
, Attribute, Context, Iterator>
{};
}}}
#endif
@@ -0,0 +1,87 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_PARSER_BINDER_DECEMBER_05_2008_0516_PM)
#define BOOST_SPIRIT_PARSER_BINDER_DECEMBER_05_2008_0516_PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/fusion/include/at.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
// parser_binder for plain rules
template <typename Parser, typename Auto>
struct parser_binder
{
parser_binder(Parser const& p_)
: p(p_) {}
template <typename Iterator, typename Skipper, typename Context>
bool call(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, mpl::true_) const
{
// If DeducedAuto is false (semantic actions is present), the
// component's attribute is unused.
return p.parse(first, last, context, skipper, unused);
}
template <typename Iterator, typename Skipper, typename Context>
bool call(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, mpl::false_) const
{
// If DeducedAuto is true (no semantic action), we pass the rule's
// attribute on to the component.
return p.parse(first, last, context, skipper
, fusion::at_c<0>(context.attributes));
}
template <typename Iterator, typename Skipper, typename Context>
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
// If Auto is false, we need to deduce whether to apply auto rule
typedef typename traits::has_semantic_action<Parser>::type auto_rule;
return call(first, last, context, skipper, auto_rule());
}
Parser p;
};
// parser_binder for auto rules
template <typename Parser>
struct parser_binder<Parser, mpl::true_>
{
parser_binder(Parser const& p_)
: p(p_) {}
template <typename Iterator, typename Skipper, typename Context>
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
// If Auto is true, we pass the rule's attribute on to the component.
return p.parse(first, last, context, skipper
, fusion::at_c<0>(context.attributes));
}
Parser p;
};
template <typename Auto, typename Parser>
inline parser_binder<Parser, Auto>
bind_parser(Parser const& p)
{
return parser_binder<Parser, Auto>(p);
}
}}}}
#endif
@@ -0,0 +1,176 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_ERROR_HANDLER_APRIL_29_2007_1042PM)
#define BOOST_SPIRIT_ERROR_HANDLER_APRIL_29_2007_1042PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/operator/expect.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/support/multi_pass_wrapper.hpp>
#include <boost/function.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace qi
{
enum error_handler_result
{
fail
, retry
, accept
, rethrow
};
namespace detail
{
// Helper template allowing to manage the inhibit clear queue flag in
// a multi_pass iterator. This is the usual specialization used for
// anything but a multi_pass iterator.
template <typename Iterator, bool active>
struct reset_on_exit
{
reset_on_exit(Iterator&) {}
};
// For 'retry' or 'fail' error handlers we need to inhibit the flushing
// of the internal multi_pass buffers which otherwise might happen at
// deterministic expectation points inside the encapsulated right hand
// side of rule.
template <typename Iterator>
struct reset_on_exit<Iterator, true>
{
reset_on_exit(Iterator& it)
: it_(it)
, inhibit_clear_queue_(spirit::traits::inhibit_clear_queue(it))
{
spirit::traits::inhibit_clear_queue(it_, true);
}
~reset_on_exit()
{
// reset inhibit flag in multi_pass on exit
spirit::traits::inhibit_clear_queue(it_, inhibit_clear_queue_);
}
Iterator& it_;
bool inhibit_clear_queue_;
};
}
template <
typename Iterator, typename Context
, typename Skipper, typename F, error_handler_result action
>
struct error_handler
{
typedef function<
bool(Iterator& first, Iterator const& last
, Context& context
, Skipper const& skipper
)>
function_type;
error_handler(function_type subject_, F f_)
: subject(subject_)
, f(f_)
{
}
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
typedef qi::detail::reset_on_exit<Iterator
, traits::is_multi_pass<Iterator>::value &&
(action == retry || action == fail)> on_exit_type;
on_exit_type on_exit(first);
for(;;)
{
try
{
Iterator i = first;
bool r = subject(i, last, context, skipper);
if (r)
first = i;
return r;
}
catch (expectation_failure<Iterator> const& x)
{
typedef
fusion::vector<
Iterator&
, Iterator const&
, Iterator const&
, info const&>
params;
error_handler_result r = action;
params args(first, last, x.first, x.what_);
f(args, context, r);
// The assertions below will fire if you are using a
// multi_pass as the underlying iterator, one of your error
// handlers forced its guarded rule to 'fail' or 'retry',
// and the error handler has not been instantiated using
// either 'fail' or 'retry' in the first place. Please see
// the multi_pass docs for more information.
switch (r)
{
case fail:
BOOST_ASSERT(
!traits::is_multi_pass<Iterator>::value ||
action == retry || action == fail);
return false;
case retry:
BOOST_ASSERT(
!traits::is_multi_pass<Iterator>::value ||
action == retry || action == fail);
continue;
case accept: return true;
case rethrow: boost::throw_exception(x);
}
}
}
return false;
}
function_type subject;
F f;
};
template <
error_handler_result action
, typename Iterator, typename T0, typename T1, typename T2
, typename F>
void on_error(rule<Iterator, T0, T1, T2>& r, F f)
{
typedef rule<Iterator, T0, T1, T2> rule_type;
typedef
error_handler<
Iterator
, typename rule_type::context_type
, typename rule_type::skipper_type
, F
, action>
error_handler;
r.f = error_handler(r.f, f);
}
// Error handling support when <action> is not
// specified. We will default to <fail>.
template <typename Iterator, typename T0, typename T1
, typename T2, typename F>
void on_error(rule<Iterator, T0, T1, T2>& r, F f)
{
on_error<fail>(r, f);
}
}}}
#endif
@@ -0,0 +1,132 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_GRAMMAR_FEBRUARY_19_2007_0236PM)
#define BOOST_SPIRIT_GRAMMAR_FEBRUARY_19_2007_0236PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
#include <boost/spirit/home/qi/reference.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace qi
{
template <
typename Iterator, typename T1, typename T2, typename T3
, typename T4>
struct grammar
: proto::extends<
typename proto::terminal<
reference<rule<Iterator, T1, T2, T3, T4> const>
>::type
, grammar<Iterator, T1, T2, T3, T4>
>
, parser<grammar<Iterator, T1, T2, T3, T4> >
, noncopyable
{
typedef Iterator iterator_type;
typedef rule<Iterator, T1, T2, T3, T4> start_type;
typedef typename start_type::sig_type sig_type;
typedef typename start_type::locals_type locals_type;
typedef typename start_type::skipper_type skipper_type;
typedef typename start_type::encoding_type encoding_type;
typedef grammar<Iterator, T1, T2, T3, T4> base_type;
typedef reference<start_type const> reference_;
typedef typename proto::terminal<reference_>::type terminal;
static size_t const params_size = start_type::params_size;
template <typename Context, typename Iterator_>
struct attribute
{
typedef typename start_type::attr_type type;
};
grammar(
start_type const& start
, std::string const& name = "unnamed-grammar")
: proto::extends<terminal, base_type>(terminal::make(reference_(start)))
, name_(name)
{}
// This constructor is used to catch if the start rule is not
// compatible with the grammar.
template <typename Iterator_,
typename T1_, typename T2_, typename T3_, typename T4_>
grammar(
rule<Iterator_, T1_, T2_, T3_, T4_> const&
, std::string const& = "unnamed-grammar")
{
// If you see the assertion below failing then the start rule
// passed to the constructor of the grammar is not compatible with
// the grammar (i.e. it uses different template parameters).
BOOST_SPIRIT_ASSERT_MSG(
(is_same<start_type, rule<Iterator_, T1_, T2_, T3_, T4_> >::value)
, incompatible_start_rule, (rule<Iterator_, T1_, T2_, T3_, T4_>));
}
std::string name() const
{
return name_;
}
void name(std::string const& str)
{
name_ = str;
}
template <typename Context, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
return this->proto_base().child0.parse(
first, last, context, skipper, attr_);
}
template <typename Context>
info what(Context&) const
{
return info(name_);
}
// bring in the operator() overloads
start_type const& get_parameterized_subject() const
{ return this->proto_base().child0.ref.get(); }
typedef start_type parameterized_subject_type;
#include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
std::string name_;
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <
typename IteratorA, typename IteratorB, typename Attribute
, typename Context, typename T1, typename T2, typename T3, typename T4>
struct handles_container<
qi::grammar<IteratorA, T1, T2, T3, T4>, Attribute, Context, IteratorB>
: traits::is_container<
typename attribute_of<
qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type
>
{};
}}}
#endif
@@ -0,0 +1,31 @@
// 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(BOOST_SPIRIT_QI_NONTERMINAL_FWD_DEC_24_2010_1105PM)
#define BOOST_SPIRIT_QI_NONTERMINAL_FWD_DEC_24_2010_1105PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi
{
// forward declaration only
template <
typename Iterator, typename T1 = unused_type
, typename T2 = unused_type, typename T3 = unused_type
, typename T4 = unused_type>
struct rule;
template <
typename Iterator, typename T1 = unused_type
, typename T2 = unused_type, typename T3 = unused_type
, typename T4 = unused_type>
struct grammar;
}}}
#endif
@@ -0,0 +1,440 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_RULE_FEBRUARY_12_2007_1020AM)
#define BOOST_SPIRIT_RULE_FEBRUARY_12_2007_1020AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/function.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/as_list.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/spirit/home/support/context.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/home/qi/reference.hpp>
#include <boost/spirit/home/qi/nonterminal/detail/parameterized.hpp>
#include <boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp>
#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace spirit { namespace qi
{
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
using spirit::_pass_type;
using spirit::_val_type;
using spirit::_a_type;
using spirit::_b_type;
using spirit::_c_type;
using spirit::_d_type;
using spirit::_e_type;
using spirit::_f_type;
using spirit::_g_type;
using spirit::_h_type;
using spirit::_i_type;
using spirit::_j_type;
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::_pass;
using spirit::_val;
using spirit::_a;
using spirit::_b;
using spirit::_c;
using spirit::_d;
using spirit::_e;
using spirit::_f;
using spirit::_g;
using spirit::_h;
using spirit::_i;
using spirit::_j;
#endif
using spirit::info;
using spirit::locals;
template <
typename Iterator, typename T1, typename T2, typename T3
, typename T4>
struct rule
: proto::extends<
typename proto::terminal<
reference<rule<Iterator, T1, T2, T3, T4> const>
>::type
, rule<Iterator, T1, T2, T3, T4>
>
, parser<rule<Iterator, T1, T2, T3, T4> >
{
typedef Iterator iterator_type;
typedef rule<Iterator, T1, T2, T3, T4> this_type;
typedef reference<this_type const> reference_;
typedef typename proto::terminal<reference_>::type terminal;
typedef proto::extends<terminal, this_type> base_type;
typedef mpl::vector<T1, T2, T3, T4> template_params;
// The rule's locals_type: a sequence of types to be used as local variables
typedef typename
spirit::detail::extract_locals<template_params>::type
locals_type;
// The rule's skip-parser type
typedef typename
spirit::detail::extract_component<
qi::domain, template_params>::type
skipper_type;
// The rule's encoding type
typedef typename
spirit::detail::extract_encoding<template_params>::type
encoding_type;
// The rule's signature
typedef typename
spirit::detail::extract_sig<template_params, encoding_type, qi::domain>::type
sig_type;
// This is the rule's attribute type
typedef typename
spirit::detail::attr_from_sig<sig_type>::type
attr_type;
typedef typename add_reference<attr_type>::type attr_reference_type;
// parameter_types is a sequence of types passed as parameters to the rule
typedef typename
spirit::detail::params_from_sig<sig_type>::type
parameter_types;
static size_t const params_size =
fusion::result_of::size<parameter_types>::type::value;
typedef context<
fusion::cons<attr_reference_type, parameter_types>
, locals_type>
context_type;
typedef function<
bool(Iterator& first, Iterator const& last
, context_type& context
, skipper_type const& skipper
)>
function_type;
typedef typename
mpl::if_<
is_same<encoding_type, unused_type>
, unused_type
, tag::char_code<tag::encoding, encoding_type>
>::type
encoding_modifier_type;
explicit rule(std::string const& name = "unnamed-rule")
: base_type(terminal::make(reference_(*this)))
, name_(name)
{
}
rule(rule const& rhs)
: base_type(terminal::make(reference_(*this)))
, name_(rhs.name_)
, f(rhs.f)
{
}
template <typename Auto, typename Expr>
static void define(rule& /*lhs*/, Expr const& /*expr*/, mpl::false_)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
}
template <typename Auto, typename Expr>
static void define(rule& lhs, Expr const& expr, mpl::true_)
{
lhs.f = detail::bind_parser<Auto>(
compile<qi::domain>(expr, encoding_modifier_type()));
}
template <typename Expr>
rule(Expr const& expr, std::string const& name = "unnamed-rule")
: base_type(terminal::make(reference_(*this)))
, name_(name)
{
define<mpl::false_>(*this, expr, traits::matches<qi::domain, Expr>());
}
rule& operator=(rule const& rhs)
{
// The following assertion fires when you try to initialize a rule
// from an uninitialized one. Did you mean to refer to the right
// hand side rule instead of assigning from it? In this case you
// should write lhs = rhs.alias();
BOOST_ASSERT(rhs.f && "Did you mean rhs.alias() instead of rhs?");
f = rhs.f;
name_ = rhs.name_;
return *this;
}
std::string const& name() const
{
return name_;
}
void name(std::string const& str)
{
name_ = str;
}
template <typename Expr>
rule& operator=(Expr const& expr)
{
define<mpl::false_>(*this, expr, traits::matches<qi::domain, Expr>());
return *this;
}
// VC7.1 has problems to resolve 'rule' without explicit template parameters
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1400)
// g++ 3.3 barfs if this is a member function :(
template <typename Expr>
friend rule& operator%=(rule& r, Expr const& expr)
{
define<mpl::true_>(r, expr, traits::matches<qi::domain, Expr>());
return r;
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
// non-const version needed to suppress proto's %= kicking in
template <typename Expr>
friend rule& operator%=(rule& r, Expr& expr)
{
return r %= static_cast<Expr const&>(expr);
}
#else
// for rvalue references
template <typename Expr>
friend rule& operator%=(rule& r, Expr&& expr)
{
define<mpl::true_>(r, expr, traits::matches<qi::domain, Expr>());
return r;
}
#endif
#else
// both friend functions have to be defined out of class as VC7.1
// will complain otherwise
template <typename OutputIterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr const& expr);
// non-const version needed to suppress proto's %= kicking in
template <typename OutputIterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr& expr);
#endif
template <typename Context, typename Iterator_>
struct attribute
{
typedef attr_type type;
};
template <typename Context, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr_param) const
{
if (f)
{
// do a preskip if this is an implied lexeme
if (is_same<skipper_type, unused_type>::value)
qi::skip_over(first, last, skipper);
typedef traits::make_attribute<attr_type, Attribute> make_attribute;
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
typename make_attribute::type, attr_type, domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr_param);
typename transform::type attr_ = transform::pre(made_attr);
// If you are seeing a compilation error here, you are probably
// trying to use a rule or a grammar which has inherited
// attributes, without passing values for them.
context_type context(attr_);
// If you are seeing a compilation error here stating that the
// fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
{
// do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr_param, attr_);
return true;
}
// inform attribute transformation of failed rhs
traits::fail_transform(attr_param, attr_);
}
return false;
}
template <typename Context, typename Skipper
, typename Attribute, typename Params>
bool parse(Iterator& first, Iterator const& last
, Context& caller_context, Skipper const& skipper
, Attribute& attr_param, Params const& params) const
{
if (f)
{
// do a preskip if this is an implied lexeme
if (is_same<skipper_type, unused_type>::value)
qi::skip_over(first, last, skipper);
typedef traits::make_attribute<attr_type, Attribute> make_attribute;
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
typename make_attribute::type, attr_type, domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr_param);
typename transform::type attr_ = transform::pre(made_attr);
// If you are seeing a compilation error here, you are probably
// trying to use a rule or a grammar which has inherited
// attributes, passing values of incompatible types for them.
context_type context(attr_, params, caller_context);
// If you are seeing a compilation error here stating that the
// fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
{
// do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr_param, attr_);
return true;
}
// inform attribute transformation of failed rhs
traits::fail_transform(attr_param, attr_);
}
return false;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info(name_);
}
reference_ alias() const
{
return reference_(*this);
}
typename proto::terminal<this_type>::type copy() const
{
typename proto::terminal<this_type>::type result = {*this};
return result;
}
// bring in the operator() overloads
rule const& get_parameterized_subject() const { return *this; }
typedef rule parameterized_subject_type;
#include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
std::string name_;
function_type f;
};
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
template <typename OutputIterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr const& expr)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
typedef typename
rule<OutputIterator_, T1_, T2_, T3_, T4_>::encoding_modifier_type
encoding_modifier_type;
r.f = detail::bind_parser<mpl::true_>(
compile<qi::domain>(expr, encoding_modifier_type()));
return r;
}
template <typename Iterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
rule<Iterator_, T1_, T2_, T3_, T4_>& operator%=(
rule<Iterator_, T1_, T2_, T3_, T4_>& r, Expr& expr)
{
return r %= static_cast<Expr const&>(expr);
}
#endif
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <
typename IteratorA, typename IteratorB, typename Attribute
, typename Context, typename T1, typename T2, typename T3, typename T4>
struct handles_container<
qi::rule<IteratorA, T1, T2, T3, T4>, Attribute, Context, IteratorB>
: traits::is_container<
typename attribute_of<
qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type
>
{};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,135 @@
/*=============================================================================
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(BOOST_SPIRIT_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
#define BOOST_SPIRIT_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
#include <boost/fusion/include/out.hpp>
#include <iostream>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/spirit/home/support/attributes.hpp>
// The stream to use for debug output
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#endif
// number of tokens to print while debugging
#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
#endif
// number of spaces to indent
#if !defined(BOOST_SPIRIT_DEBUG_INDENT)
#define BOOST_SPIRIT_DEBUG_INDENT 2
#endif
namespace boost { namespace spirit { namespace qi
{
namespace detail
{
template<typename Char>
inline void token_printer(std::ostream& o, Char c)
{
// allow to customize the token printer routine
spirit::traits::print_token(o, c);
}
}
struct simple_trace
{
int& get_indent() const
{
static int indent = 0;
return indent;
}
void print_indent(int n) const
{
n *= BOOST_SPIRIT_DEBUG_INDENT;
for (int i = 0; i != n; ++i)
BOOST_SPIRIT_DEBUG_OUT << ' ';
}
template <typename Iterator>
void print_some(
char const* tag
, int /*indent*/
, Iterator first, Iterator const& last) const
{
print_indent(get_indent());
BOOST_SPIRIT_DEBUG_OUT << '<' << tag << '>';
int const n = BOOST_SPIRIT_DEBUG_PRINT_SOME;
for (int i = 0; first != last && i != n && *first; ++i, ++first)
detail::token_printer(BOOST_SPIRIT_DEBUG_OUT, *first);
BOOST_SPIRIT_DEBUG_OUT << "</" << tag << '>' << std::endl;
// $$$ FIXME convert invalid xml characters (e.g. '<') to valid
// character entities. $$$
}
template <typename Iterator, typename Context, typename State>
void operator()(
Iterator const& first
, Iterator const& last
, Context const& context
, State state
, std::string const& rule_name) const
{
switch (state)
{
case pre_parse:
print_indent(get_indent()++);
BOOST_SPIRIT_DEBUG_OUT
<< '<' << rule_name << '>'
<< std::endl;
print_some("try", get_indent(), first, last);
break;
case successful_parse:
print_some("success", get_indent(), first, last);
print_indent(get_indent());
BOOST_SPIRIT_DEBUG_OUT
<< "<attributes>";
traits::print_attribute(
BOOST_SPIRIT_DEBUG_OUT,
context.attributes
);
BOOST_SPIRIT_DEBUG_OUT
<< "</attributes>";
if (!fusion::empty(context.locals))
BOOST_SPIRIT_DEBUG_OUT
<< "<locals>"
<< context.locals
<< "</locals>";
BOOST_SPIRIT_DEBUG_OUT << std::endl;
print_indent(--get_indent());
BOOST_SPIRIT_DEBUG_OUT
<< "</" << rule_name << '>'
<< std::endl;
break;
case failed_parse:
print_indent(get_indent());
BOOST_SPIRIT_DEBUG_OUT << "<fail/>" << std::endl;
print_indent(--get_indent());
BOOST_SPIRIT_DEBUG_OUT
<< "</" << rule_name << '>'
<< std::endl;
break;
}
}
};
}}}
#endif
@@ -0,0 +1,83 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_SUCCESS_HANDLER_FEBRUARY_25_2011_1051AM)
#define BOOST_SPIRIT_SUCCESS_HANDLER_FEBRUARY_25_2011_1051AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/function.hpp>
namespace boost { namespace spirit { namespace qi
{
template <
typename Iterator, typename Context
, typename Skipper, typename F
>
struct success_handler
{
typedef function<
bool(Iterator& first, Iterator const& last
, Context& context
, Skipper const& skipper
)>
function_type;
success_handler(function_type subject_, F f_)
: subject(subject_)
, f(f_)
{
}
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
Iterator i = first;
bool r = subject(i, last, context, skipper);
if (r)
{
typedef
fusion::vector<
Iterator&
, Iterator const&
, Iterator const&>
params;
skip_over(first, last, skipper);
params args(first, last, i);
f(args, context);
first = i;
}
return r;
}
function_type subject;
F f;
};
template <
typename Iterator, typename T0, typename T1, typename T2
, typename F>
void on_success(rule<Iterator, T0, T1, T2>& r, F f)
{
typedef rule<Iterator, T0, T1, T2> rule_type;
typedef
success_handler<
Iterator
, typename rule_type::context_type
, typename rule_type::skipper_type
, F>
success_handler;
r.f = success_handler(r.f, f);
}
}}}
#endif
@@ -0,0 +1,19 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_FEBRUARY_05_2007_1231PM)
#define BOOST_SPIRIT_NUMERIC_FEBRUARY_05_2007_1231PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/numeric/bool.hpp>
#include <boost/spirit/home/qi/numeric/int.hpp>
#include <boost/spirit/home/qi/numeric/uint.hpp>
#include <boost/spirit/home/qi/numeric/real.hpp>
#endif
@@ -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
@@ -0,0 +1,27 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_OPERATOR_FEBRUARY_02_2007_0558PM)
#define BOOST_SPIRIT_OPERATOR_FEBRUARY_02_2007_0558PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/operator/sequence.hpp>
#include <boost/spirit/home/qi/operator/expect.hpp>
#include <boost/spirit/home/qi/operator/alternative.hpp>
#include <boost/spirit/home/qi/operator/sequential_or.hpp>
#include <boost/spirit/home/qi/operator/permutation.hpp>
#include <boost/spirit/home/qi/operator/difference.hpp>
#include <boost/spirit/home/qi/operator/list.hpp>
#include <boost/spirit/home/qi/operator/optional.hpp>
#include <boost/spirit/home/qi/operator/kleene.hpp>
#include <boost/spirit/home/qi/operator/plus.hpp>
#include <boost/spirit/home/qi/operator/and_predicate.hpp>
#include <boost/spirit/home/qi/operator/not_predicate.hpp>
#endif
@@ -0,0 +1,118 @@
/*=============================================================================
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_ALTERNATIVE_FEBRUARY_05_2007_1153AM)
#define SPIRIT_ALTERNATIVE_FEBRUARY_05_2007_1153AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/detail/alternative_function.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/fusion/include/any.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/for_each.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::bitwise_or> // enables |
: mpl::true_ {};
template <>
struct flatten_tree<qi::domain, proto::tag::bitwise_or> // flattens |
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Elements>
struct alternative : nary_parser<alternative<Elements> >
{
template <typename Context, typename Iterator>
struct attribute
{
// Put all the element attributes in a tuple
typedef typename traits::build_attribute_sequence<
Elements, Context, traits::alternative_attribute_transform
, Iterator, qi::domain
>::type all_attributes;
// Ok, now make a variant over the attribute sequence. Note that
// build_variant makes sure that 1) all attributes in the variant
// are unique 2) puts the unused attribute, if there is any, to
// the front and 3) collapses single element variants, variant<T>
// to T.
typedef typename
traits::build_variant<all_attributes>::type
type;
};
alternative(Elements const& elements_)
: elements(elements_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
detail::alternative_function<Iterator, Context, Skipper, Attribute>
f(first, last, context, skipper, attr_);
// return true if *any* of the parsers succeed
return fusion::any(elements, f);
}
template <typename Context>
info what(Context& context) const
{
info result("alternative");
fusion::for_each(elements,
spirit::detail::what_function<Context>(result, context));
return result;
}
Elements elements;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::bitwise_or, Elements, Modifiers>
: make_nary_composite<Elements, alternative>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Elements>
struct has_semantic_action<qi::alternative<Elements> >
: nary_has_semantic_action<Elements> {};
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::alternative<Elements>, Attribute, Context
, Iterator>
: nary_handles_container<Elements, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,92 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_AND_PREDICATE_MARCH_23_2007_0617PM)
#define SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/at.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::address_of> // enables &p
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Subject>
struct and_predicate : unary_parser<and_predicate<Subject> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
and_predicate(Subject const& subject_)
: subject(subject_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& /*attr*/) const
{
Iterator i = first;
return subject.parse(i, last, context, skipper, unused);
}
template <typename Context>
info what(Context& context) const
{
return info("and-predicate", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::address_of, Elements, Modifiers>
: make_unary_composite<Elements, and_predicate>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::and_predicate<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::and_predicate<Subject>, Attribute, Context
, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,112 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_DIFFERENCE_FEBRUARY_11_2007_1250PM)
#define SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/at.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::minus> // enables -
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Left, typename Right>
struct difference : binary_parser<difference<Left, Right> >
{
typedef Left left_type;
typedef Right right_type;
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
traits::attribute_of<left_type, Context, Iterator>::type
type;
};
difference(Left const& left_, Right const& right_)
: left(left_), right(right_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
// Unlike classic Spirit, with this version of difference, the rule
// lit("policeman") - "police" will always fail to match.
// Spirit2 does not count the matching chars while parsing and
// there is no reliable and fast way to check if the LHS matches
// more than the RHS.
// Try RHS first
Iterator start = first;
if (right.parse(first, last, context, skipper, unused))
{
// RHS succeeds, we fail.
first = start;
return false;
}
// RHS fails, now try LHS
return left.parse(first, last, context, skipper, attr_);
}
template <typename Context>
info what(Context& context) const
{
return info("difference",
std::make_pair(left.what(context), right.what(context)));
}
Left left;
Right right;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::minus, Elements, Modifiers>
: make_binary_composite<Elements, difference>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Left, typename Right>
struct has_semantic_action<qi::difference<Left, Right> >
: binary_has_semantic_action<Left, Right> {};
///////////////////////////////////////////////////////////////////////////
template <typename Left, typename Right, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::difference<Left, Right>, Attribute, Context
, Iterator>
: binary_handles_container<Left, Right, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,103 @@
/*=============================================================================
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_EXPECT_APRIL_29_2007_0445PM)
#define SPIRIT_EXPECT_APRIL_29_2007_0445PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/operator/sequence_base.hpp>
#include <boost/spirit/home/qi/detail/expect_function.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <stdexcept>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::greater> // enables >
: mpl::true_ {};
template <>
struct flatten_tree<qi::domain, proto::tag::greater> // flattens >
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Iterator>
struct expectation_failure : std::runtime_error
{
expectation_failure(Iterator first_, Iterator last_, info const& what)
: std::runtime_error("boost::spirit::qi::expectation_failure")
, first(first_), last(last_), what_(what)
{}
~expectation_failure() throw() {}
Iterator first;
Iterator last;
info what_;
};
template <typename Elements>
struct expect : sequence_base<expect<Elements>, Elements>
{
friend struct sequence_base<expect<Elements>, Elements>;
expect(Elements const& elements)
: sequence_base<expect<Elements>, Elements>(elements) {}
private:
template <typename Iterator, typename Context, typename Skipper>
static detail::expect_function<
Iterator, Context, Skipper
, expectation_failure<Iterator> >
fail_function(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper)
{
return detail::expect_function<
Iterator, Context, Skipper, expectation_failure<Iterator> >
(first, last, context, skipper);
}
std::string id() const { return "expect"; }
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::greater, Elements, Modifiers>
: make_nary_composite<Elements, expect>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Elements>
struct has_semantic_action<qi::expect<Elements> >
: nary_has_semantic_action<Elements> {};
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::expect<Elements>, Attribute, Context
, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,134 @@
/*=============================================================================
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_KLEENE_JANUARY_07_2007_0818AM)
#define SPIRIT_KLEENE_JANUARY_07_2007_0818AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/qi/detail/fail_function.hpp>
#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
//[composite_parsers_kleene_enable_
template <>
struct use_operator<qi::domain, proto::tag::dereference> // enables *p
: mpl::true_ {};
//]
}}
namespace boost { namespace spirit { namespace qi
{
//[composite_parsers_kleene
template <typename Subject>
struct kleene : unary_parser<kleene<Subject> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
// Build a std::vector from the subject's attribute. Note
// that build_std_vector may return unused_type if the
// subject's attribute is an unused_type.
typedef typename
traits::build_std_vector<
typename traits::
attribute_of<Subject, Context, Iterator>::type
>::type
type;
};
kleene(Subject const& subject_)
: subject(subject_) {}
template <typename F>
bool parse_container(F f) const
{
while (!f (subject))
;
return true;
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
// ensure the attribute is actually a container type
traits::make_container(attr_);
typedef detail::fail_function<Iterator, Context, Skipper>
fail_function;
Iterator iter = first;
fail_function f(iter, last, context, skipper);
parse_container(detail::make_pass_container(f, attr_));
first = f.first;
return true;
}
template <typename Context>
info what(Context& context) const
{
return info("kleene", subject.what(context));
}
Subject subject;
};
//]
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
//[composite_parsers_kleene_generator
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::dereference, Elements, Modifiers>
: make_unary_composite<Elements, kleene>
{};
//]
// ///////////////////////////////////////////////////////////////////////////
// // Define what attributes are compatible with a kleene
// template <typename Attribute, typename Subject, typename Context, typename Iterator>
// struct is_attribute_compatible<Attribute, kleene<Subject>, Context, Iterator>
// : traits::is_container_compatible<qi::domain, Attribute
// , kleene<Subject>, Context, Iterator>
// {};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::kleene<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::kleene<Subject>, Attribute
, Context, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,135 @@
/*=============================================================================
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_LIST_MARCH_24_2007_1031AM)
#define SPIRIT_LIST_MARCH_24_2007_1031AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/qi/detail/fail_function.hpp>
#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <vector>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::modulus> // enables p % d
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Left, typename Right>
struct list : binary_parser<list<Left, Right> >
{
typedef Left left_type;
typedef Right right_type;
template <typename Context, typename Iterator>
struct attribute
{
// Build a std::vector from the LHS's attribute. Note
// that build_std_vector may return unused_type if the
// subject's attribute is an unused_type.
typedef typename
traits::build_std_vector<
typename traits::
attribute_of<Left, Context, Iterator>::type
>::type
type;
};
list(Left const& left_, Right const& right_)
: left(left_), right(right_) {}
template <typename F>
bool parse_container(F f) const
{
// in order to succeed we need to match at least one element
if (f (left))
return false;
typename F::iterator_type save = f.f.first;
while (right.parse(f.f.first, f.f.last, f.f.context, f.f.skipper, unused)
&& !f (left))
{
save = f.f.first;
}
f.f.first = save;
return true;
}
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::fail_function<Iterator, Context, Skipper>
fail_function;
// ensure the attribute is actually a container type
traits::make_container(attr_);
Iterator iter = first;
fail_function f(iter, last, context, skipper);
if (!parse_container(detail::make_pass_container(f, attr_)))
return false;
first = f.first;
return true;
}
template <typename Context>
info what(Context& context) const
{
return info("list",
std::make_pair(left.what(context), right.what(context)));
}
Left left;
Right right;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::modulus, Elements, Modifiers>
: make_binary_composite<Elements, list>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Left, typename Right>
struct has_semantic_action<qi::list<Left, Right> >
: binary_has_semantic_action<Left, Right> {};
///////////////////////////////////////////////////////////////////////////
template <typename Left, typename Right, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::list<Left, Right>, Attribute, Context
, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,91 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_NOT_PREDICATE_MARCH_23_2007_0618PM)
#define SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::logical_not> // enables !p
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Subject>
struct not_predicate : unary_parser<not_predicate<Subject> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
not_predicate(Subject const& subject_)
: subject(subject_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& /*attr*/) const
{
Iterator i = first;
return !subject.parse(i, last, context, skipper, unused);
}
template <typename Context>
info what(Context& context) const
{
return info("not-predicate", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::logical_not, Elements, Modifiers>
: make_unary_composite<Elements, not_predicate>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::not_predicate<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::not_predicate<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,135 @@
/*=============================================================================
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_OPTIONAL_MARCH_23_2007_1117PM)
#define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/optional.hpp>
#include <vector>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::negate> // enables -p
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Subject>
struct optional : unary_parser<optional<Subject> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
// Build a boost::optional from the subject's attribute. Note
// that boost::optional may return unused_type if the
// subject's attribute is an unused_type.
typedef typename
traits::build_optional<
typename traits::
attribute_of<Subject, Context, Iterator>::type
>::type
type;
};
optional(Subject const& subject_)
: subject(subject_) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse_impl(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_, mpl::false_) const
{
// create a local value if Attribute is not unused_type
typename spirit::result_of::optional_value<Attribute>::type val =
typename spirit::result_of::optional_value<Attribute>::type();
if (subject.parse(first, last, context, skipper, val))
{
// assign the parsed value into our attribute
spirit::traits::assign_to(val, attr_);
}
return true;
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse_impl(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_, mpl::true_) const
{
subject.parse(first, last, context, skipper, attr_);
return true;
}
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 typename spirit::result_of::optional_value<Attribute>::type
attribute_type;
return parse_impl(first, last, context, skipper, attr_
, traits::is_container<attribute_type>());
}
template <typename Context>
info what(Context& context) const
{
return info("optional", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::negate, Elements, Modifiers>
: make_unary_composite<Elements, optional>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::optional<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::optional<Subject>, Attribute
, Context, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,146 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_PERMUTATION_OR_MARCH_13_2007_1145PM)
#define SPIRIT_PERMUTATION_OR_MARCH_13_2007_1145PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/detail/permute_function.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/algorithm/any_if_ns.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/optional.hpp>
#include <boost/foreach.hpp>
#include <boost/array.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::bitwise_xor> // enables ^
: mpl::true_ {};
template <>
struct flatten_tree<qi::domain, proto::tag::bitwise_xor> // flattens ^
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Elements>
struct permutation : nary_parser<permutation<Elements> >
{
template <typename Context, typename Iterator>
struct attribute
{
// Put all the element attributes in a tuple,
// wrapping each element in a boost::optional
typedef typename traits::build_attribute_sequence<
Elements, Context, traits::permutation_attribute_transform
, Iterator, qi::domain
>::type all_attributes;
// Now, build a fusion vector over the attributes. Note
// that build_fusion_vector 1) removes all unused attributes
// and 2) may return unused_type if all elements have
// unused_type(s).
typedef typename
traits::build_fusion_vector<all_attributes>::type
type;
};
permutation(Elements const& elements_)
: elements(elements_) {}
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 traits::attribute_not_unused<Context, Iterator> predicate;
detail::permute_function<Iterator, Context, Skipper>
f(first, last, context, skipper);
boost::array<bool, fusion::result_of::size<Elements>::value> flags;
BOOST_FOREACH(bool& taken, flags)
{
taken = false;
}
// wrap the attribute in a tuple if it is not a tuple
typename traits::wrap_if_not_tuple<Attribute>::type attr_local(attr_);
// We have a bool array 'flags' with one flag for each parser.
// permute_function sets the slot to true when the corresponding
// parser successful matches. We loop until there are no more
// successful parsers.
bool result = false;
f.taken = flags.begin();
while (spirit::any_if_ns(elements, attr_local, f, predicate()))
{
f.taken = flags.begin();
result = true;
}
return result;
}
template <typename Context>
info what(Context& context) const
{
info result("permutation");
fusion::for_each(elements,
spirit::detail::what_function<Context>(result, context));
return result;
}
Elements elements;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::bitwise_xor, Elements, Modifiers>
: make_nary_composite<Elements, permutation>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// We specialize this for permutation (see support/attributes.hpp).
// For permutation, we only wrap the attribute in a tuple IFF
// it is not already a fusion tuple.
template <typename Elements, typename Attribute>
struct pass_attribute<qi::permutation<Elements>, Attribute>
: wrap_if_not_tuple<Attribute> {};
///////////////////////////////////////////////////////////////////////////
template <typename Elements>
struct has_semantic_action<qi::permutation<Elements> >
: nary_has_semantic_action<Elements> {};
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::permutation<Elements>, Attribute, Context
, Iterator>
: nary_handles_container<Elements, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,125 @@
/*=============================================================================
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_PLUS_MARCH_13_2007_0127PM)
#define SPIRIT_PLUS_MARCH_13_2007_0127PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/qi/detail/fail_function.hpp>
#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::unary_plus> // enables +p
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Subject>
struct plus : unary_parser<plus<Subject> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
// Build a std::vector from the subject's attribute. Note
// that build_std_vector may return unused_type if the
// subject's attribute is an unused_type.
typedef typename
traits::build_std_vector<
typename traits::attribute_of<
Subject, Context, Iterator>::type
>::type
type;
};
plus(Subject const& subject_)
: subject(subject_) {}
template <typename F>
bool parse_container(F f) const
{
// in order to succeed we need to match at least one element
if (f (subject))
return false;
while (!f (subject))
;
return true;
}
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::fail_function<Iterator, Context, Skipper>
fail_function;
// ensure the attribute is actually a container type
traits::make_container(attr_);
Iterator iter = first;
fail_function f(iter, last, context, skipper);
if (!parse_container(detail::make_pass_container(f, attr_)))
return false;
first = f.first;
return true;
}
template <typename Context>
info what(Context& context) const
{
return info("plus", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::unary_plus, Elements, Modifiers>
: make_unary_composite<Elements, plus>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<qi::plus<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::plus<Subject>, Attribute, Context
, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,96 @@
/*=============================================================================
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_SEQUENCE_APR_22_2006_0811AM)
#define SPIRIT_SEQUENCE_APR_22_2006_0811AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/operator/sequence_base.hpp>
#include <boost/spirit/home/qi/detail/fail_function.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::shift_right> // enables >>
: mpl::true_ {};
template <>
struct flatten_tree<qi::domain, proto::tag::shift_right> // flattens >>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Elements>
struct sequence : sequence_base<sequence<Elements>, Elements>
{
friend struct sequence_base<sequence<Elements>, Elements>;
sequence(Elements const& elements)
: sequence_base<sequence<Elements>, Elements>(elements) {}
private:
template <typename Iterator, typename Context, typename Skipper>
static detail::fail_function<Iterator, Context, Skipper>
fail_function(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper)
{
return detail::fail_function<Iterator, Context, Skipper>
(first, last, context, skipper);
}
std::string id() const { return "sequence"; }
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::shift_right, Elements, Modifiers>
: make_nary_composite<Elements, sequence>
{};
// ///////////////////////////////////////////////////////////////////////////
// // Define what attributes are compatible with a sequence
// template <typename Attribute, typename Elements, typename Context, typename Iterator>
// struct is_attribute_compatible<Attribute, sequence<Elements>, Context, Iterator>
// : mpl::or_<
// is_convertible<Attribute
// , typename traits::attribute_of<sequence<Elements>, Context, Iterator>::type>
// , traits::is_fusion_sequence_compatible<qi::domain, Attribute
// , sequence<Elements>, Context, Iterator>
// , traits::is_container_compatible<qi::domain, Attribute
// , sequence<Elements>, Context, Iterator>
// >
// {};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Elements>
struct has_semantic_action<qi::sequence<Elements> >
: nary_has_semantic_action<Elements> {};
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::sequence<Elements>, Attribute, Context
, Iterator>
: mpl::true_ {};
}}}
#endif
@@ -0,0 +1,140 @@
/*=============================================================================
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_SEQUENCE_BASE_APRIL_22_2006_0811AM)
#define SPIRIT_SEQUENCE_BASE_APRIL_22_2006_0811AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/algorithm/any_if.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/sequence_base_id.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace qi
{
template <typename Derived, typename Elements>
struct sequence_base // this class is shared by sequence and expect
: nary_parser<Derived>
{
typedef Elements elements_type;
struct sequence_base_id;
template <typename Context, typename Iterator>
struct attribute
{
// Put all the element attributes in a tuple
typedef typename traits::build_attribute_sequence<
Elements, Context, traits::sequence_attribute_transform
, Iterator, qi::domain
>::type all_attributes;
// Now, build a fusion vector over the attributes. Note
// that build_fusion_vector 1) removes all unused attributes
// and 2) may return unused_type if all elements have
// unused_type(s).
typedef typename
traits::build_fusion_vector<all_attributes>::type
type_;
// Finally, strip single element vectors into its
// naked form: vector1<T> --> T
typedef typename
traits::strip_single_element_vector<type_>::type
type;
};
sequence_base(Elements const& elements_)
: elements(elements_) {}
// standard case. Attribute is a fusion tuple
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse_impl(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_, mpl::false_) const
{
Iterator iter = first;
typedef traits::attribute_not_unused<Context, Iterator> predicate;
// wrap the attribute in a tuple if it is not a tuple or if the
// attribute of this sequence is a single element tuple
typedef typename attribute<Context, Iterator>::type_ attr_type_;
typename traits::wrap_if_not_tuple<Attribute
, typename mpl::and_<
traits::one_element_sequence<attr_type_>
, mpl::not_<traits::one_element_sequence<Attribute> >
>::type
>::type attr_local(attr_);
// return false if *any* of the parsers fail
if (spirit::any_if(elements, attr_local
, Derived::fail_function(iter, last, context, skipper), predicate()))
return false;
first = iter;
return true;
}
// Special case when Attribute is an stl container
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse_impl(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_, mpl::true_) const
{
// ensure the attribute is actually a container type
traits::make_container(attr_);
Iterator iter = first;
// return false if *any* of the parsers fail
if (fusion::any(elements
, detail::make_sequence_pass_container(
Derived::fail_function(iter, last, context, skipper), attr_))
)
return false;
first = iter;
return true;
}
// main parse function. Dispatches to parse_impl depending
// on the Attribute 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
{
return parse_impl(first, last, context, skipper, attr_
, traits::is_container<Attribute>());
}
template <typename Context>
info what(Context& context) const
{
info result(this->derived().id());
fusion::for_each(elements,
spirit::detail::what_function<Context>(result, context));
return result;
}
Elements elements;
};
}}}
#endif
@@ -0,0 +1,127 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_SEQUENTIAL_OR_MARCH_12_2007_1130PM)
#define SPIRIT_SEQUENTIAL_OR_MARCH_12_2007_1130PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/detail/pass_function.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/spirit/home/support/algorithm/any_if_ns.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/for_each.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::logical_or> // enables ||
: mpl::true_ {};
template <>
struct flatten_tree<qi::domain, proto::tag::logical_or> // flattens ||
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
template <typename Elements>
struct sequential_or : nary_parser<sequential_or<Elements> >
{
template <typename Context, typename Iterator>
struct attribute
{
// Put all the element attributes in a tuple,
// wrapping each element in a boost::optional
typedef typename traits::build_attribute_sequence<
Elements, Context, traits::sequential_or_attribute_transform
, Iterator, qi::domain
>::type all_attributes;
// Now, build a fusion vector over the attributes. Note
// that build_fusion_vector 1) removes all unused attributes
// and 2) may return unused_type if all elements have
// unused_type(s).
typedef typename
traits::build_fusion_vector<all_attributes>::type
type;
};
sequential_or(Elements const& elements_)
: elements(elements_) {}
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 traits::attribute_not_unused<Context, Iterator> predicate;
detail::pass_function<Iterator, Context, Skipper>
f(first, last, context, skipper);
// wrap the attribute in a tuple if it is not a tuple
typename traits::wrap_if_not_tuple<Attribute>::type attr_local(attr_);
// return true if *any* of the parsers succeed
// (we use the non-short-circuiting version: any_if_ns
// to force all elements to be tested)
return spirit::any_if_ns(elements, attr_local, f, predicate());
}
template <typename Context>
info what(Context& context) const
{
info result("sequential-or");
fusion::for_each(elements,
spirit::detail::what_function<Context>(result, context));
return result;
}
Elements elements;
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers>
struct make_composite<proto::tag::logical_or, Elements, Modifiers>
: make_nary_composite<Elements, sequential_or>
{};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// We specialize this for sequential_or (see support/attributes.hpp).
// For sequential_or, we only wrap the attribute in a tuple IFF
// it is not already a fusion tuple.
template <typename Elements, typename Attribute>
struct pass_attribute<qi::sequential_or<Elements>, Attribute>
: wrap_if_not_tuple<Attribute> {};
///////////////////////////////////////////////////////////////////////////
template <typename Elements>
struct has_semantic_action<qi::sequential_or<Elements> >
: nary_has_semantic_action<Elements> {};
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::sequential_or<Elements>, Attribute, Context
, Iterator>
: nary_handles_container<Elements, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,215 @@
/*=============================================================================
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(BOOST_SPIRIT_PARSE_APRIL_16_2006_0442PM)
#define BOOST_SPIRIT_PARSE_APRIL_16_2006_0442PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/context.hpp>
#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/home/qi/detail/parse.hpp>
#include <boost/concept_check.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr>
inline bool
parse(
Iterator& first
, Iterator last
, Expr const& expr)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
return detail::parse_impl<Expr>::call(first, last, expr);
}
template <typename Iterator, typename Expr>
inline bool
parse(
Iterator const& first_
, Iterator last
, Expr const& expr)
{
Iterator first = first_;
return qi::parse(first, last, expr);
}
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename T>
struct make_context
{
typedef context<fusion::cons<T&>, locals<> > type;
};
template <>
struct make_context<unused_type>
{
typedef unused_type type;
};
}
template <typename Iterator, typename Expr, typename Attr>
inline bool
parse(
Iterator& first
, Iterator last
, Expr const& expr
, Attr& attr)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
typename detail::make_context<Attr>::type context(attr);
return compile<qi::domain>(expr).parse(first, last, context, unused, attr);
}
template <typename Iterator, typename Expr, typename Attr>
inline bool
parse(
Iterator const& first_
, Iterator last
, Expr const& expr
, Attr& attr)
{
Iterator first = first_;
return qi::parse(first, last, expr, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr, typename Skipper>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
return detail::phrase_parse_impl<Expr>::call(
first, last, expr, skipper, post_skip);
}
template <typename Iterator, typename Expr, typename Skipper>
inline bool
phrase_parse(
Iterator const& first_
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
{
Iterator first = first_;
return qi::phrase_parse(first, last, expr, skipper, post_skip);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip
, Attr& attr)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then either the expression (expr) or skipper is not a valid
// spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
typedef
typename result_of::compile<qi::domain, Skipper>::type
skipper_type;
skipper_type const skipper_ = compile<qi::domain>(skipper);
typename detail::make_context<Attr>::type context(attr);
if (!compile<qi::domain>(expr).parse(
first, last, context, skipper_, attr))
return false;
if (post_skip == skip_flag::postskip)
qi::skip_over(first, last, skipper_);
return true;
}
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
inline bool
phrase_parse(
Iterator const& first_
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip
, Attr& attr)
{
Iterator first = first_;
return qi::phrase_parse(first, last, expr, skipper, post_skip, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr const& expr
, Skipper const& skipper
, Attr& attr)
{
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
}
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
inline bool
phrase_parse(
Iterator const& first_
, Iterator last
, Expr const& expr
, Skipper const& skipper
, Attr& attr)
{
Iterator first = first_;
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
}
}}}
#endif
@@ -0,0 +1,177 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// Copyright (c) 2001-2011 Joel de Guzman
// Copyright (c) 2009 Carl Barron
//
// 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_PP_IS_ITERATING)
#if !defined(BOOST_SPIRIT_PARSE_ATTR_APRIL_24_2009_1043AM)
#define BOOST_SPIRIT_PARSE_ATTR_APRIL_24_2009_1043AM
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iterate.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define BOOST_PP_FILENAME_1 <boost/spirit/home/qi/parse_attr.hpp>
#define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT)
#include BOOST_PP_ITERATE()
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Preprocessor vertical repetition code
//
///////////////////////////////////////////////////////////////////////////////
#else // defined(BOOST_PP_IS_ITERATING)
#define N BOOST_PP_ITERATION()
#define BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE(z, n, A) BOOST_PP_CAT(A, n)&
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr
, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline bool
parse(
Iterator& first
, Iterator last
, Expr const& expr
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
// Make sure the iterator is at least a forward_iterator. If you got an
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
typedef fusion::vector<
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
> vector_type;
vector_type lattr (BOOST_PP_ENUM_PARAMS(N, attr));
return compile<qi::domain>(expr).parse(first, last, unused, unused, lattr);
}
template <typename Iterator, typename Expr
, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline bool
parse(
Iterator const& first_
, Iterator last
, Expr const& expr
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
Iterator first = first_;
return qi::parse(first, last, expr, BOOST_PP_ENUM_PARAMS(N, attr));
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr, typename Skipper
, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
// Make sure the iterator is at least a forward_iterator. If you got an
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then either the expression (expr) or skipper is not a valid
// spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
typedef
typename result_of::compile<qi::domain, Skipper>::type
skipper_type;
skipper_type const skipper_ = compile<qi::domain>(skipper);
typedef fusion::vector<
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
> vector_type;
vector_type lattr (BOOST_PP_ENUM_PARAMS(N, attr));
if (!compile<qi::domain>(expr).parse(
first, last, unused, skipper_, lattr))
return false;
if (post_skip == skip_flag::postskip)
qi::skip_over(first, last, skipper_);
return true;
}
template <typename Iterator, typename Expr, typename Skipper
, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline bool
phrase_parse(
Iterator const& first_
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
Iterator first = first_;
return qi::phrase_parse(first, last, expr, skipper, post_skip
, BOOST_PP_ENUM_PARAMS(N, attr));
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr, typename Skipper
, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip
, BOOST_PP_ENUM_PARAMS(N, attr));
}
template <typename Iterator, typename Expr, typename Skipper
, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline bool
phrase_parse(
Iterator const& first_
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
Iterator first = first_;
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip
, BOOST_PP_ENUM_PARAMS(N, attr));
}
}}}
#undef BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE
#undef N
#endif
@@ -0,0 +1,140 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_PARSER_OCTOBER_16_2008_0254PM)
#define BOOST_SPIRIT_PARSER_OCTOBER_16_2008_0254PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/has_xxx.hpp>
#include <boost/spirit/home/qi/domain.hpp>
namespace boost { namespace spirit { namespace qi
{
//[parser_base_parser
template <typename Derived>
struct parser
{
struct parser_id;
typedef Derived derived_type;
typedef qi::domain domain;
// Requirement: p.parse(f, l, context, skip, attr) -> bool
//
// p: a parser
// f, l: first/last iterator pair
// context: enclosing rule context (can be unused_type)
// skip: skipper (can be unused_type)
// attr: attribute (can be unused_type)
// Requirement: p.what(context) -> info
//
// p: a parser
// context: enclosing rule context (can be unused_type)
// Requirement: P::template attribute<Ctx, Iter>::type
//
// P: a parser type
// Ctx: A context type (can be unused_type)
// Iter: An iterator type (can be unused_type)
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
};
//]
template <typename Derived>
struct primitive_parser : parser<Derived>
{
struct primitive_parser_id;
};
template <typename Derived>
struct nary_parser : parser<Derived>
{
struct nary_parser_id;
// Requirement: p.elements -> fusion sequence
//
// p: a composite parser
// Requirement: P::elements_type -> fusion sequence
//
// P: a composite parser type
};
template <typename Derived>
struct unary_parser : parser<Derived>
{
struct unary_parser_id;
// Requirement: p.subject -> subject parser
//
// p: a unary parser
// Requirement: P::subject_type -> subject parser type
//
// P: a unary parser type
};
template <typename Derived>
struct binary_parser : parser<Derived>
{
struct binary_parser_id;
// Requirement: p.left -> left parser
//
// p: a binary parser
// Requirement: P::left_type -> left parser type
//
// P: a binary parser type
// Requirement: p.right -> right parser
//
// p: a binary parser
// Requirement: P::right_type -> right parser type
//
// P: a binary parser type
};
}}}
namespace boost { namespace spirit { namespace traits // classification
{
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(parser_id)
BOOST_MPL_HAS_XXX_TRAIT_DEF(primitive_parser_id)
BOOST_MPL_HAS_XXX_TRAIT_DEF(nary_parser_id)
BOOST_MPL_HAS_XXX_TRAIT_DEF(unary_parser_id)
BOOST_MPL_HAS_XXX_TRAIT_DEF(binary_parser_id)
}
// parser type identification
template <typename T>
struct is_parser : detail::has_parser_id<T> {};
template <typename T>
struct is_primitive_parser : detail::has_primitive_parser_id<T> {};
template <typename T>
struct is_nary_parser : detail::has_nary_parser_id<T> {};
template <typename T>
struct is_unary_parser : detail::has_unary_parser_id<T> {};
template <typename T>
struct is_binary_parser : detail::has_binary_parser_id<T> {};
}}}
#endif
@@ -0,0 +1,69 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_REFERENCE_OCTOBER_31_2008_1218AM)
#define BOOST_SPIRIT_REFERENCE_OCTOBER_31_2008_1218AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/ref.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// reference is a parser that references another parser (its Subject)
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct reference : parser<reference<Subject> >
{
typedef Subject subject_type;
reference(Subject& subject)
: ref(subject) {}
template <typename Context, typename Iterator>
struct attribute : Subject::template attribute<Context, Iterator> {};
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
return ref.get().parse(first, last, context, skipper, attr_);
}
template <typename Context>
info what(Context& context) const
{
// the reference is transparent (does not add any info)
return ref.get().what(context);
}
boost::reference_wrapper<Subject> ref;
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::reference<Subject>, Attribute, Context
, Iterator>
: handles_container<typename remove_const<Subject>::type
, Attribute, Context, Iterator>
{};
}}}
#endif
@@ -0,0 +1,29 @@
/*=============================================================================
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(BOOST_SPIRIT_SKIP_FLAG_DEC_02_2009_0412PM)
#define BOOST_SPIRIT_SKIP_FLAG_DEC_02_2009_0412PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
BOOST_SCOPED_ENUM_START(skip_flag)
{
postskip, // force post-skipping in phrase_parse()
dont_postskip // inhibit post-skipping in phrase_parse()
};
BOOST_SCOPED_ENUM_END
}}}
#endif
@@ -0,0 +1,44 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_SKIP_APRIL_16_2006_0625PM)
#define BOOST_SPIRIT_SKIP_APRIL_16_2006_0625PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// Move the /first/ iterator to the first non-matching position
// given a skip-parser. The function is a no-op if unused_type is
// passed as the skip-parser.
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename T>
inline void skip_over(Iterator& first, Iterator const& last, T const& skipper)
{
while (first != last && skipper.parse(first, last, unused, unused, unused))
/***/;
}
template <typename Iterator>
inline void skip_over(Iterator&, Iterator const&, unused_type)
{
}
template <typename Iterator, typename Skipper>
inline void skip_over(Iterator&, Iterator const&
, detail::unused_skipper<Skipper> const&)
{
}
}}}
#endif
@@ -0,0 +1,17 @@
/*=============================================================================
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(BOOST_SPIRIT_STREAM_MAY_05_2007_1227PM)
#define BOOST_SPIRIT_STREAM_MAY_05_2007_1227PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/stream/stream.hpp>
#endif
@@ -0,0 +1,80 @@
/*=============================================================================
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(BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM)
#define BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/iostreams/stream.hpp>
#include <boost/detail/iterator.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
struct iterator_source
{
typedef typename
boost::detail::iterator_traits<Iterator>::value_type
char_type;
typedef boost::iostreams::seekable_device_tag category;
iterator_source (Iterator const& first_, Iterator const& last_)
: first(first_), last(last_), pos(0)
{}
// Read up to n characters from the input sequence into the buffer s,
// returning the number of characters read, or -1 to indicate
// end-of-sequence.
std::streamsize read (char_type* s, std::streamsize n)
{
if (first == last)
return -1;
std::streamsize bytes_read = 0;
while (n--) {
*s = *first;
++s; ++bytes_read;
if (++first == last)
break;
}
pos += bytes_read;
return bytes_read;
}
// Write is implemented only to satisfy the requirements of a
// boost::iostreams::seekable_device. We need to have see support to
// be able to figure out how many characters have been actually
// consumed by the stream.
std::streamsize write(const char_type*, std::streamsize)
{
BOOST_ASSERT(false); // not supported
return -1;
}
std::streampos seek(boost::iostreams::stream_offset, std::ios_base::seekdir way)
{
BOOST_ASSERT(way == std::ios_base::cur); // only support queries
return pos; // return current position
}
Iterator first;
Iterator const& last;
std::streamsize pos;
private:
// silence MSVC warning C4512: assignment operator could not be generated
iterator_source& operator= (iterator_source const&);
};
}}}}
#endif
@@ -0,0 +1,230 @@
/*=============================================================================
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(BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM)
#define BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/support/iterators/istream_iterator.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/mpl/bool.hpp>
#include <iterator>
#include <string>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr
, typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_
, typename Skipper = unused_type, typename Attribute = unused_type const>
struct match_manip
{
// This assertion makes sure we don't hit the only code path which is
// not implemented (because it isn't needed), where both, the
// expression and the attribute need to be held as a copy.
BOOST_SPIRIT_ASSERT_MSG(!CopyExpr::value || !CopyAttr::value
, error_invalid_should_not_happen, ());
match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
: expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
match_manip(Expr const& xpr, Skipper const& s
, BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
: expr(xpr), skipper(s), attr(a), post_skip(ps) {}
Expr const& expr;
Skipper const& skipper;
Attribute& attr;
BOOST_SCOPED_ENUM(skip_flag) const post_skip;
private:
// silence MSVC warning C4512: assignment operator could not be generated
match_manip& operator= (match_manip const&);
};
template <typename Expr, typename Skipper, typename Attribute>
struct match_manip<Expr, mpl::false_, mpl::true_, Skipper, Attribute>
{
match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
: expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
match_manip(Expr const& xpr, Skipper const& s
, BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
: expr(xpr), skipper(s), attr(a), post_skip(ps) {}
Expr const& expr;
Skipper const& skipper;
Attribute attr;
BOOST_SCOPED_ENUM(skip_flag) const post_skip;
private:
// silence MSVC warning C4512: assignment operator could not be generated
match_manip& operator= (match_manip const&);
};
template <typename Expr, typename Skipper, typename Attribute>
struct match_manip<Expr, mpl::true_, mpl::false_, Skipper, Attribute>
{
match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
: expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
match_manip(Expr const& xpr, Skipper const& s
, BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
: expr(xpr), skipper(s), attr(a), post_skip(ps) {}
Expr expr;
Skipper const& skipper;
Attribute& attr;
BOOST_SCOPED_ENUM(skip_flag) const post_skip;
private:
// silence MSVC warning C4512: assignment operator could not be generated
match_manip& operator= (match_manip const&);
};
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable = void>
struct match
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
// Did you intend to use the auto_ facilities while forgetting to
// #include <boost/spirit/include/qi_match_auto.hpp>?
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
};
template <typename Expr>
struct match<Expr
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
{
typedef match_manip<Expr> type;
static type call(Expr const& expr)
{
return type(expr, unused, unused);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Skipper, typename Enable = void>
struct phrase_match
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
// Did you intend to use the auto_ facilities while forgetting to
// #include <boost/spirit/include/qi_match_auto.hpp>?
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
};
template <typename Expr, typename Skipper>
struct phrase_match<Expr, Skipper
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
{
typedef match_manip<Expr, mpl::false_, mpl::false_, Skipper> type;
static type call(
Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the delimiter is not a valid spirit karma expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
return type(expr, skipper, post_skip, unused);
}
};
///////////////////////////////////////////////////////////////////////////
template<typename Char, typename Traits, typename Expr
, typename CopyExpr, typename CopyAttr>
inline std::basic_istream<Char, Traits> &
operator>>(std::basic_istream<Char, Traits> &is,
match_manip<Expr, CopyExpr, CopyAttr> const& fm)
{
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
input_iterator f(is);
input_iterator l;
if (!qi::parse(f, l, fm.expr))
{
is.setstate(std::ios_base::failbit);
}
return is;
}
///////////////////////////////////////////////////////////////////////////
template<typename Char, typename Traits, typename Expr
, typename CopyExpr, typename CopyAttr
, typename Attribute>
inline std::basic_istream<Char, Traits> &
operator>>(std::basic_istream<Char, Traits> &is,
match_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm)
{
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
input_iterator f(is);
input_iterator l;
if (!qi::parse(f, l, fm.expr, fm.attr))
{
is.setstate(std::ios_base::failbit);
}
return is;
}
///////////////////////////////////////////////////////////////////////////
template<typename Char, typename Traits, typename Expr
, typename CopyExpr, typename CopyAttr
, typename Skipper>
inline std::basic_istream<Char, Traits> &
operator>>(std::basic_istream<Char, Traits> &is,
match_manip<Expr, CopyExpr, CopyAttr, Skipper> const& fm)
{
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
input_iterator f(is);
input_iterator l;
if (!qi::phrase_parse(
f, l, fm.expr, fm.skipper, fm.post_skip))
{
is.setstate(std::ios_base::failbit);
}
return is;
}
///////////////////////////////////////////////////////////////////////////
template<typename Char, typename Traits, typename Expr
, typename CopyExpr, typename CopyAttr
, typename Attribute, typename Skipper
>
inline std::basic_istream<Char, Traits> &
operator>>(
std::basic_istream<Char, Traits> &is,
match_manip<Expr, CopyExpr, CopyAttr, Attribute, Skipper> const& fm)
{
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
input_iterator f(is);
input_iterator l;
if (!qi::phrase_parse(
f, l, fm.expr, fm.skipper, fm.post_skip, fm.attr))
{
is.setstate(std::ios_base::failbit);
}
return is;
}
}}}}
#endif
@@ -0,0 +1,63 @@
/*=============================================================================
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(BOOST_SPIRIT_MATCH_MANIP_AUTO_DEC_02_2009_0813PM)
#define BOOST_SPIRIT_MATCH_MANIP_AUTO_DEC_02_2009_0813PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
#include <boost/spirit/home/qi/auto/create_parser.hpp>
#include <boost/utility/enable_if.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct match<Expr
, typename enable_if<traits::meta_create_exists<qi::domain, Expr> >::type>
{
typedef typename result_of::create_parser<Expr>::type expr_type;
typedef match_manip<
expr_type, mpl::true_, mpl::false_, unused_type, Expr
> type;
static type call(Expr const& expr)
{
return type(create_parser<Expr>(), unused, const_cast<Expr&>(expr));
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Skipper>
struct phrase_match<Expr, Skipper
, typename enable_if<traits::meta_create_exists<qi::domain, Expr> >::type>
{
typedef typename result_of::create_parser<Expr>::type expr_type;
typedef match_manip<
expr_type, mpl::true_, mpl::false_, Skipper, Expr
> type;
static type call(
Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the delimiter is not a valid spirit karma expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
return type(create_parser<Expr>(), skipper, post_skip
, const_cast<Expr&>(expr));
}
};
}}}}
#endif
@@ -0,0 +1,123 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
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_MATCH_MANIP_MAY_05_2007_1202PM)
#define BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1202PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
inline typename detail::match<Expr>::type
match(
Expr const& expr)
{
return detail::match<Expr>::call(expr);
}
template <typename Expr, typename Attribute>
inline detail::match_manip<
Expr, mpl::false_, mpl::false_, unused_type, Attribute
>
match(
Expr const& xpr
, Attribute& p)
{
using qi::detail::match_manip;
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
return match_manip<Expr, mpl::false_, mpl::false_, unused_type, Attribute>(
xpr, unused, p);
}
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Skipper>
inline typename detail::phrase_match<Expr, Skipper>::type
phrase_match(
Expr const& expr
, Skipper const& s
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
{
return detail::phrase_match<Expr, Skipper>::call(expr, s, post_skip);
}
template <typename Expr, typename Skipper, typename Attribute>
inline detail::match_manip<
Expr, mpl::false_, mpl::false_, Skipper, Attribute
>
phrase_match(
Expr const& xpr
, Skipper const& s
, BOOST_SCOPED_ENUM(skip_flag) post_skip
, Attribute& p)
{
using qi::detail::match_manip;
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then either the expression (expr) or skipper is not a valid
// spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
return match_manip<Expr, mpl::false_, mpl::false_, Skipper, Attribute>(
xpr, s, post_skip, p);
}
template <typename Expr, typename Skipper, typename Attribute>
inline detail::match_manip<
Expr, mpl::false_, mpl::false_, Skipper, Attribute
>
phrase_match(
Expr const& xpr
, Skipper const& s
, Attribute& p)
{
using qi::detail::match_manip;
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then either the expression (expr) or skipper is not a valid
// spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
return match_manip<Expr, mpl::false_, mpl::false_, Skipper, Attribute>(
xpr, s, p);
}
///////////////////////////////////////////////////////////////////////////
template<typename Char, typename Traits, typename Derived>
inline std::basic_istream<Char, Traits>&
operator>>(std::basic_istream<Char, Traits>& is, parser<Derived> const& p)
{
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
input_iterator f(is);
input_iterator l;
if (!p.derived().parse(f, l, unused, unused, unused))
{
is.setstate(std::ios_base::failbit);
}
return is;
}
}}}
#endif
@@ -0,0 +1,133 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
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_PP_IS_ITERATING)
#if !defined(BOOST_SPIRIT_MATCH_MANIP_ATTR_MAY_05_2007_1202PM)
#define BOOST_SPIRIT_MATCH_MANIP_ATTR_MAY_05_2007_1202PM
#include <boost/spirit/home/qi/stream/match_manip.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/preprocessor/iterate.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define BOOST_PP_FILENAME_1 \
<boost/spirit/home/qi/stream/match_manip_attr.hpp>
#define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT)
#include BOOST_PP_ITERATE()
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Preprocessor vertical repetition code
//
///////////////////////////////////////////////////////////////////////////////
#else // defined(BOOST_PP_IS_ITERATING)
#define N BOOST_PP_ITERATION()
#define BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE(z, n, A) BOOST_PP_CAT(A, n) &
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline detail::match_manip<Expr, mpl::false_, mpl::true_, unused_type
, fusion::vector<
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
> >
match(
Expr const& xpr
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
using qi::detail::match_manip;
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
typedef fusion::vector<
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
> vector_type;
vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
return match_manip<Expr, mpl::false_, mpl::true_, unused_type, vector_type>(
xpr, unused, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Skipper
, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline detail::match_manip<Expr, mpl::false_, mpl::true_, Skipper
, fusion::vector<
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
> >
phrase_match(
Expr const& xpr
, Skipper const& s
, BOOST_SCOPED_ENUM(skip_flag) post_skip
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
using qi::detail::match_manip;
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then either the expression (expr) or skipper is not a valid
// spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
typedef fusion::vector<
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
> vector_type;
vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
return match_manip<Expr, mpl::false_, mpl::true_, Skipper, vector_type>(
xpr, s, post_skip, attr);
}
template <typename Expr, typename Skipper
, BOOST_PP_ENUM_PARAMS(N, typename A)>
inline detail::match_manip<Expr, mpl::false_, mpl::true_, Skipper
, fusion::vector<
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
> >
phrase_match(
Expr const& xpr
, Skipper const& s
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
{
using qi::detail::match_manip;
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then either the expression (expr) or skipper is not a valid
// spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
typedef fusion::vector<
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
> vector_type;
vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
return match_manip<Expr, mpl::false_, mpl::true_, Skipper, vector_type>(
xpr, s, attr);
}
}}}
#undef BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE
#undef N
#endif
@@ -0,0 +1,118 @@
/*=============================================================================
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(BOOST_SPIRIT_STREAM_MAY_05_2007_1228PM)
#define BOOST_SPIRIT_STREAM_MAY_05_2007_1228PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/detail/string_parse.hpp>
#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
#include <boost/spirit/home/qi/stream/detail/iterator_source.hpp>
#include <boost/spirit/home/support/detail/hold_any.hpp>
#include <iosfwd>
#include <sstream>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_terminal<qi::domain, tag::stream> // enables stream
: mpl::true_ {};
template <>
struct use_terminal<qi::domain, tag::wstream> // enables wstream
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::stream;
using spirit::wstream;
#endif
using spirit::stream_type;
using spirit::wstream_type;
template <typename Char = char, typename T = spirit::basic_hold_any<char> >
struct stream_parser
: primitive_parser<stream_parser<Char, T> >
{
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 qi::detail::iterator_source<Iterator> source_device;
typedef boost::iostreams::stream<source_device> instream;
qi::skip_over(first, last, skipper);
instream in(first, last); // copies 'first'
in >> attr_; // use existing operator>>()
// advance the iterator if everything is ok
if (in) {
if (!in.eof()) {
std::streamsize pos = in.tellg();
std::advance(first, pos);
} else {
first = last;
}
return true;
}
return false;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info("stream");
}
};
template <typename T, typename Char = char>
struct typed_stream
: proto::terminal<stream_parser<Char, T> >::type
{
};
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct make_stream
{
typedef stream_parser<Char> result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
template <typename Modifiers>
struct make_primitive<tag::stream, Modifiers> : make_stream<char> {};
template <typename Modifiers>
struct make_primitive<tag::wstream, Modifiers> : make_stream<wchar_t> {};
}}}
#endif
@@ -0,0 +1,17 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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_STRING_FEBRUARY_03_2007_0355PM)
#define BOOST_SPIRIT_STRING_FEBRUARY_03_2007_0355PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/string/lit.hpp>
#include <boost/spirit/home/qi/string/symbols.hpp>
#endif

Some files were not shown because too many files have changed in this diff Show More