PageRenderTime 21ms CodeModel.GetById 11ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://hadesmem.googlecode.com/
C++ Header | 135 lines | 96 code | 19 blank | 20 comment | 4 complexity | 2300b8fa52ef12bbf7c36017136aa219 MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2001-2011 Joel de Guzman
  3    Copyright (c) 2001-2011 Hartmut Kaiser
  4
  5    Distributed under the Boost Software License, Version 1.0. (See accompanying
  6    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7=============================================================================*/
  8#if !defined(SPIRIT_LIST_MARCH_24_2007_1031AM)
  9#define SPIRIT_LIST_MARCH_24_2007_1031AM
 10
 11#if defined(_MSC_VER)
 12#pragma once
 13#endif
 14
 15#include <boost/spirit/home/qi/meta_compiler.hpp>
 16#include <boost/spirit/home/qi/parser.hpp>
 17#include <boost/spirit/home/support/container.hpp>
 18#include <boost/spirit/home/qi/detail/attributes.hpp>
 19#include <boost/spirit/home/qi/detail/fail_function.hpp>
 20#include <boost/spirit/home/qi/detail/pass_container.hpp>
 21#include <boost/spirit/home/support/has_semantic_action.hpp>
 22#include <boost/spirit/home/support/handles_container.hpp>
 23#include <boost/spirit/home/support/info.hpp>
 24#include <vector>
 25
 26namespace boost { namespace spirit
 27{
 28    ///////////////////////////////////////////////////////////////////////////
 29    // Enablers
 30    ///////////////////////////////////////////////////////////////////////////
 31    template <>
 32    struct use_operator<qi::domain, proto::tag::modulus> // enables p % d
 33      : mpl::true_ {};
 34}}
 35
 36namespace boost { namespace spirit { namespace qi
 37{
 38    template <typename Left, typename Right>
 39    struct list : binary_parser<list<Left, Right> >
 40    {
 41        typedef Left left_type;
 42        typedef Right right_type;
 43
 44        template <typename Context, typename Iterator>
 45        struct attribute
 46        {
 47            // Build a std::vector from the LHS's attribute. Note
 48            // that build_std_vector may return unused_type if the
 49            // subject's attribute is an unused_type.
 50            typedef typename
 51                traits::build_std_vector<
 52                    typename traits::
 53                        attribute_of<Left, Context, Iterator>::type
 54                >::type
 55            type;
 56        };
 57
 58        list(Left const& left, Right const& right)
 59          : left(left), right(right) {}
 60
 61        template <typename F>
 62        bool parse_container(F f) const
 63        {
 64            // in order to succeed we need to match at least one element 
 65            if (f (left))
 66                return false;
 67
 68            typename F::iterator_type save = f.f.first;
 69            while (right.parse(f.f.first, f.f.last, f.f.context, f.f.skipper, unused)
 70              && !f (left))
 71            {
 72                save = f.f.first;
 73            }
 74
 75            f.f.first = save;
 76            return true;
 77        }
 78
 79        template <typename Iterator, typename Context
 80          , typename Skipper, typename Attribute>
 81        bool parse(Iterator& first, Iterator const& last
 82          , Context& context, Skipper const& skipper
 83          , Attribute& attr) const
 84        {
 85            typedef detail::fail_function<Iterator, Context, Skipper>
 86                fail_function;
 87
 88            // ensure the attribute is actually a container type
 89            traits::make_container(attr);
 90
 91            Iterator iter = first;
 92            fail_function f(iter, last, context, skipper);
 93            if (!parse_container(detail::make_pass_container(f, attr)))
 94                return false;
 95
 96            first = f.first;
 97            return true;
 98        }
 99
100        template <typename Context>
101        info what(Context& context) const
102        {
103            return info("list",
104                std::make_pair(left.what(context), right.what(context)));
105        }
106
107        Left left;
108        Right right;
109    };
110
111    ///////////////////////////////////////////////////////////////////////////
112    // Parser generators: make_xxx function (objects)
113    ///////////////////////////////////////////////////////////////////////////
114    template <typename Elements, typename Modifiers>
115    struct make_composite<proto::tag::modulus, Elements, Modifiers>
116      : make_binary_composite<Elements, list>
117    {};
118}}}
119
120namespace boost { namespace spirit { namespace traits
121{
122    ///////////////////////////////////////////////////////////////////////////
123    template <typename Left, typename Right>
124    struct has_semantic_action<qi::list<Left, Right> >
125      : binary_has_semantic_action<Left, Right> {};
126
127    ///////////////////////////////////////////////////////////////////////////
128    template <typename Left, typename Right, typename Attribute
129      , typename Context, typename Iterator>
130    struct handles_container<qi::list<Left, Right>, Attribute, Context
131          , Iterator> 
132      : mpl::true_ {};
133}}}
134
135#endif