/usr/include/boost/spirit/home/x3/nonterminal
Edit: /usr/include/boost/spirit/home/x3/nonterminal/rule.hpp (9791B)
/*=============================================================================
Copyright (c) 2001-2014 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_X3_RULE_JAN_08_2012_0326PM)
#define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM
#include
#include
#include
#include
#include
#include
#include
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
#include
#endif
namespace boost { namespace spirit { namespace x3
{
// default parse_rule implementation
template
inline detail::default_parse_rule_result
parse_rule(
rule /* rule_ */
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr)
{
static_assert(!is_same(context)), unused_type>::value,
"BOOST_SPIRIT_DEFINE undefined for this rule.");
return get(context).parse(first, last, context, unused, attr);
}
template
struct rule_definition : parser>
{
typedef rule_definition this_type;
typedef ID id;
typedef RHS rhs_type;
typedef rule lhs_type;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same::value;
static bool const handles_container =
traits::is_container::value;
static bool const force_attribute =
force_attribute_;
constexpr rule_definition(RHS const& rhs, char const* name)
: rhs(rhs), name(name) {}
template
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute_& attr) const
{
return detail::rule_parser
::call_rule_definition(
rhs, name, first, last
, context
, attr
, mpl::bool_());
}
RHS rhs;
char const* name;
};
template
struct rule : parser>
{
static_assert(!std::is_reference::value,
"Reference qualifier on rule attribute type is meaningless");
typedef ID id;
typedef Attribute attribute_type;
static bool const has_attribute =
!std::is_same, unused_type>::value;
static bool const handles_container =
traits::is_container::value;
static bool const force_attribute = force_attribute_;
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
rule() : name(typeid(rule).name()) {}
#else
constexpr rule() : name("unnamed") {}
#endif
constexpr rule(char const* name)
: name(name) {}
constexpr rule(rule const& r)
: name(r.name)
{
// Assert that we are not copying an unitialized static rule. If
// the static is in another TU, it may be initialized after we copy
// it. If so, its name member will be nullptr.
BOOST_ASSERT_MSG(r.name, "uninitialized rule"); // static initialization order fiasco
}
template
constexpr rule_definition<
ID, typename extension::as_parser::value_type, Attribute, force_attribute_>
operator=(RHS const& rhs) const
{
return { as_parser(rhs), name };
}
template
constexpr rule_definition<
ID, typename extension::as_parser::value_type, Attribute, true>
operator%=(RHS const& rhs) const
{
return { as_parser(rhs), name };
}
template
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute_& attr) const
{
static_assert(has_attribute,
"The rule does not have an attribute. Check your parser.");
using transform = traits::transform_attribute<
Attribute_, attribute_type, parser_id>;
using transform_attr = typename transform::type;
transform_attr attr_ = transform::pre(attr);
if (parse_rule(*this, first, last, context, attr_)) {
transform::post(attr, std::forward(attr_));
return true;
}
return false;
}
template
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, unused_type) const
{
// make sure we pass exactly the rule attribute type
attribute_type no_attr{};
return parse_rule(*this, first, last, context, no_attr);
}
char const* name;
};
namespace traits
{
template
struct is_rule : mpl::false_ {};
template
struct is_rule> : mpl::true_ {};
template
struct is_rule> : mpl::true_ {};
}
template
struct get_info>::type>
{
typedef std::string result_type;
std::string operator()(T const& r) const
{
BOOST_ASSERT_MSG(r.name, "uninitialized rule"); // static initialization order fiasco
return r.name? r.name : "uninitialized";
}
};
#define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
template \
bool parse_rule( \
rule_type rule_ \
, Iterator& first, Iterator const& last \
, Context const& context, rule_type::attribute_type& attr); \
/***/
#define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \
BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
/***/
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
#define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
using BOOST_PP_CAT(rule_name, _synonym) = decltype(rule_name); \
template \
inline bool parse_rule( \
BOOST_PP_CAT(rule_name, _synonym) /* rule_ */ \
, Iterator& first, Iterator const& last \
, Context const& context, BOOST_PP_CAT(rule_name, _synonym)::attribute_type& attr) \
{ \
using boost::spirit::x3::unused; \
static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
return def_.parse(first, last, context, unused, attr); \
} \
/***/
#else
#define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
template \
inline bool parse_rule( \
decltype(rule_name) /* rule_ */ \
, Iterator& first, Iterator const& last \
, Context const& context, decltype(rule_name)::attribute_type& attr) \
{ \
using boost::spirit::x3::unused; \
static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
return def_.parse(first, last, context, unused, attr); \
} \
/***/
#endif
#define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \
BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
/***/
#define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
template bool parse_rule( \
rule_type rule_ \
, Iterator& first, Iterator const& last \
, Context const& context, rule_type::attribute_type&); \
/***/
}}}
#endif