PageRenderTime 37ms CodeModel.GetById 19ms app.highlight 12ms RepoModel.GetById 3ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/qi/operator/difference.hpp

http://hadesmem.googlecode.com/
C++ Header | 112 lines | 75 code | 15 blank | 22 comment | 1 complexity | 86a3210f2c56e54327556634eb0ac644 MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2001-2011 Joel de Guzman
  3
  4    Distributed under the Boost Software License, Version 1.0. (See accompanying
  5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6=============================================================================*/
  7#if !defined(SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM)
  8#define SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM
  9
 10#if defined(_MSC_VER)
 11#pragma once
 12#endif
 13
 14#include <boost/spirit/home/qi/domain.hpp>
 15#include <boost/spirit/home/qi/meta_compiler.hpp>
 16#include <boost/spirit/home/qi/parser.hpp>
 17#include <boost/spirit/home/qi/detail/attributes.hpp>
 18#include <boost/spirit/home/support/info.hpp>
 19#include <boost/spirit/home/support/has_semantic_action.hpp>
 20#include <boost/spirit/home/support/handles_container.hpp>
 21#include <boost/fusion/include/at.hpp>
 22
 23namespace boost { namespace spirit
 24{
 25    ///////////////////////////////////////////////////////////////////////////
 26    // Enablers
 27    ///////////////////////////////////////////////////////////////////////////
 28    template <>
 29    struct use_operator<qi::domain, proto::tag::minus> // enables -
 30      : mpl::true_ {};
 31}}
 32
 33namespace boost { namespace spirit { namespace qi
 34{
 35    template <typename Left, typename Right>
 36    struct difference : binary_parser<difference<Left, Right> >
 37    {
 38        typedef Left left_type;
 39        typedef Right right_type;
 40
 41        template <typename Context, typename Iterator>
 42        struct attribute
 43        {
 44            typedef typename
 45                traits::attribute_of<left_type, Context, Iterator>::type
 46            type;
 47        };
 48
 49        difference(Left const& left, Right const& right)
 50          : left(left), right(right) {}
 51
 52        template <typename Iterator, typename Context
 53          , typename Skipper, typename Attribute>
 54        bool parse(Iterator& first, Iterator const& last
 55          , Context& context, Skipper const& skipper
 56          , Attribute& attr) const
 57        {
 58            // Unlike classic Spirit, with this version of difference, the rule
 59            // lit("policeman") - "police" will always fail to match.
 60
 61            // Spirit2 does not count the matching chars while parsing and
 62            // there is no reliable and fast way to check if the LHS matches
 63            // more than the RHS.
 64
 65            // Try RHS first
 66            Iterator start = first;
 67            if (right.parse(first, last, context, skipper, unused))
 68            {
 69                // RHS succeeds, we fail.
 70                first = start;
 71                return false;
 72            }
 73            // RHS fails, now try LHS
 74            return left.parse(first, last, context, skipper, attr);
 75        }
 76
 77        template <typename Context>
 78        info what(Context& context) const
 79        {
 80            return info("difference",
 81                std::make_pair(left.what(context), right.what(context)));
 82        }
 83
 84        Left left;
 85        Right right;
 86    };
 87
 88    ///////////////////////////////////////////////////////////////////////////
 89    // Parser generators: make_xxx function (objects)
 90    ///////////////////////////////////////////////////////////////////////////
 91    template <typename Elements, typename Modifiers>
 92    struct make_composite<proto::tag::minus, Elements, Modifiers>
 93      : make_binary_composite<Elements, difference>
 94    {};
 95}}}
 96
 97namespace boost { namespace spirit { namespace traits
 98{
 99    ///////////////////////////////////////////////////////////////////////////
100    template <typename Left, typename Right>
101    struct has_semantic_action<qi::difference<Left, Right> >
102      : binary_has_semantic_action<Left, Right> {};
103
104    ///////////////////////////////////////////////////////////////////////////
105    template <typename Left, typename Right, typename Attribute
106      , typename Context, typename Iterator>
107    struct handles_container<qi::difference<Left, Right>, Attribute, Context
108      , Iterator>
109      : binary_handles_container<Left, Right, Attribute, Context, Iterator> {};
110}}}
111
112#endif