Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:06:21

0001 /*=============================================================================
0002     Copyright (c) 2001-2014 Joel de Guzman
0003     Copyright (c) 2017 wanghan02
0004     Copyright (c) 2024 Nana Sakisaka
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 =============================================================================*/
0009 #if !defined(BOOST_SPIRIT_X3_DIFFERENCE_FEBRUARY_11_2007_1250PM)
0010 #define BOOST_SPIRIT_X3_DIFFERENCE_FEBRUARY_11_2007_1250PM
0011 
0012 #include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
0013 #include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
0014 #include <boost/spirit/home/x3/support/expectation.hpp>
0015 #include <boost/spirit/home/x3/core/parser.hpp>
0016 
0017 namespace boost { namespace spirit { namespace x3
0018 {
0019     template <typename Left, typename Right>
0020     struct difference : binary_parser<Left, Right, difference<Left, Right>>
0021     {
0022         typedef binary_parser<Left, Right, difference<Left, Right>> base_type;
0023         static bool const handles_container = Left::handles_container;
0024 
0025         constexpr difference(Left const& left, Right const& right)
0026           : base_type(left, right) {}
0027 
0028         template <typename Iterator, typename Context
0029           , typename RContext, typename Attribute>
0030         bool parse(Iterator& first, Iterator const& last
0031           , Context const& context, RContext& rcontext, Attribute& attr) const
0032         {
0033             // Try Right first
0034             Iterator start = first;
0035             if (this->right.parse(first, last, context, rcontext, unused))
0036             {
0037                 // Right succeeds, we fail.
0038                 first = start;
0039                 return false;
0040             }
0041 
0042             // In case of `Left - expect[r]`,
0043             // if Right yielded expectation error,
0044             // the whole difference expression (*this) should also yield error.
0045             // In other words, when the THROW macro was 1 (i.e. traditional behavior),
0046             // Right should already have thrown an exception.
0047         #if !BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
0048             if (has_expectation_failure(context))
0049             {
0050                 // don't rollback iterator (mimicking exception-like behavior)
0051                 return false;
0052             }
0053         #endif
0054 
0055             // Right fails, now try Left
0056             return this->left.parse(first, last, context, rcontext, attr);
0057         }
0058 
0059         template <typename Left_, typename Right_>
0060         constexpr difference<Left_, Right_>
0061         make(Left_ const& left, Right_ const& right) const
0062         {
0063             return { left, right };
0064         }
0065     };
0066 
0067     template <typename Left, typename Right>
0068     constexpr difference<
0069         typename extension::as_parser<Left>::value_type
0070       , typename extension::as_parser<Right>::value_type>
0071     operator-(Left const& left, Right const& right)
0072     {
0073         return { as_parser(left), as_parser(right) };
0074     }
0075 }}}
0076 
0077 namespace boost { namespace spirit { namespace x3 { namespace traits
0078 {
0079     template <typename Left, typename Right, typename Context>
0080     struct attribute_of<x3::difference<Left, Right>, Context>
0081         : attribute_of<Left, Context> {};
0082 
0083     template <typename Left, typename Right, typename Context>
0084     struct has_attribute<x3::difference<Left, Right>, Context>
0085         : has_attribute<Left, Context> {};
0086 }}}}
0087 
0088 #endif