source: NonGTP/Boost/boost/spirit/dynamic/impl/select.ipp @ 857

Revision 857, 4.0 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Copyright (c) 2003 Hartmut Kaiser
3    http://spirit.sourceforge.net/
4
5    Use, modification and distribution is subject to the Boost Software
6    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7    http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9#ifndef BOOST_SPIRIT_SELECT_IPP
10#define BOOST_SPIRIT_SELECT_IPP
11
12#include <boost/spirit/core/parser.hpp>
13#include <boost/spirit/core/composite/composite.hpp>
14#include <boost/spirit/meta/as_parser.hpp>
15
16///////////////////////////////////////////////////////////////////////////////
17namespace boost { namespace spirit {
18
19///////////////////////////////////////////////////////////////////////////////
20namespace impl {
21
22///////////////////////////////////////////////////////////////////////////////
23template <typename ParserT>
24struct as_embedded_parser : public as_parser<ParserT>
25{
26    typedef typename as_parser<ParserT>::type::derived_t::embed_t type;
27};
28
29///////////////////////////////////////////////////////////////////////////////
30
31// no implementation here to catch unknown BehaviourT template arguments
32template <typename ResultT, typename BehaviourT>
33struct select_match_gen;
34
35// implementation for the select_default_no_fail behaviour
36template <typename ResultT>
37struct select_match_gen<ResultT, select_default_no_fail> {
38
39    template <typename ScannerT>
40    static ResultT
41    do_ (ScannerT const &scan)
42    {
43        return scan.create_match(0, -1, scan.first, scan.first);
44    }
45};
46
47// implementation for the select_default_fail behaviour
48template <typename ResultT>
49struct select_match_gen<ResultT, select_default_fail> {
50
51    template <typename ScannerT>
52    static ResultT
53    do_ (ScannerT const &scan)
54    {
55        return scan.no_match();
56    }
57};
58
59///////////////////////////////////////////////////////////////////////////////
60template <int N, typename ResultT, typename TupleT, typename BehaviourT>
61struct parse_tuple_element {
62
63    BOOST_STATIC_CONSTANT(int, index = (TupleT::length - N));
64   
65    template <typename ScannerT>
66    static ResultT
67    do_(TupleT const &t, ScannerT const &scan)
68    {
69        typedef typename phoenix::tuple_element<index, TupleT>::type parser_t;
70        typedef typename ScannerT::iterator_t                       iterator_t;
71        typedef typename parser_result<parser_t, ScannerT>::type    result_t;
72   
73    iterator_t save(scan.first);
74    result_t result(t[phoenix::tuple_index<index>()].parse(scan));
75
76        if (result) {
77            return scan.create_match(result.length(), TupleT::length - N,
78                save, scan.first);
79        }
80        scan.first = save;    // reset the input stream
81        return parse_tuple_element<N-1, ResultT, TupleT, BehaviourT>::
82            do_(t, scan);
83    }
84};
85
86template <typename ResultT, typename TupleT, typename BehaviourT>
87struct parse_tuple_element<1, ResultT, TupleT, BehaviourT> {
88
89    BOOST_STATIC_CONSTANT(int, index = (TupleT::length - 1));
90   
91    template <typename ScannerT>
92    static ResultT
93    do_(TupleT const &t, ScannerT const &scan)
94    {
95        typedef typename phoenix::tuple_element<index, TupleT>::type  parser_t;
96        typedef typename ScannerT::iterator_t                       iterator_t;
97        typedef typename parser_result<parser_t, ScannerT>::type    result_t;
98       
99    iterator_t save(scan.first);
100    result_t result(t[phoenix::tuple_index<index>()].parse(scan));
101
102        if (result) {
103            return scan.create_match(result.length(), TupleT::length - 1,
104                save, scan.first);
105        }
106        scan.first = save;    // reset the input stream
107        return select_match_gen<ResultT, BehaviourT>::do_(scan);
108    }
109};
110
111///////////////////////////////////////////////////////////////////////////////
112}   // namespace impl
113}}  // namespace boost::spirit
114
115#endif  // BOOST_SPIRIT_SELECT_IPP
Note: See TracBrowser for help on using the repository browser.