boost/spirit/home/x3/directive/confix.hpp
/*=============================================================================
Copyright (c) 2009 Chris Hoeppler
Copyright (c) 2014 Lee Clagett
Copyright (c) 2017 wanghan02
Copyright (c) 2024 Nana Sakisaka
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_CONFIX_MAY_30_2014_1819PM)
#define BOOST_SPIRIT_X3_CONFIX_MAY_30_2014_1819PM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/expectation.hpp>
namespace boost { namespace spirit { namespace x3
{
template<typename Prefix, typename Subject, typename Postfix>
struct confix_directive :
unary_parser<Subject, confix_directive<Prefix, Subject, Postfix>>
{
typedef unary_parser<
Subject, confix_directive<Prefix, Subject, Postfix>> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
constexpr confix_directive(Prefix const& prefix
, Subject const& subject
, Postfix const& postfix) :
base_type(subject),
prefix(prefix),
postfix(postfix)
{
}
template<typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
Iterator save = first;
if (!(prefix.parse(first, last, context, rcontext, unused) &&
this->subject.parse(first, last, context, rcontext, attr) &&
postfix.parse(first, last, context, rcontext, unused)))
{
#if !BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
if (has_expectation_failure(context))
{
// don't rollback iterator (mimicking exception-like behavior)
return false;
}
#endif
first = save;
return false;
}
return true;
}
Prefix prefix;
Postfix postfix;
};
template<typename Prefix, typename Postfix>
struct confix_gen
{
template<typename Subject>
constexpr confix_directive<
Prefix, typename extension::as_parser<Subject>::value_type, Postfix>
operator[](Subject const& subject) const
{
return { prefix, as_parser(subject), postfix };
}
Prefix prefix;
Postfix postfix;
};
template<typename Prefix, typename Postfix>
constexpr confix_gen<typename extension::as_parser<Prefix>::value_type,
typename extension::as_parser<Postfix>::value_type>
confix(Prefix const& prefix, Postfix const& postfix)
{
return { as_parser(prefix), as_parser(postfix) };
}
}}}
#endif