• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 1998-2003 Joel de Guzman
3     http://spirit.sourceforge.net/
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(BOOST_SPIRIT_MATCH_HPP)
9 #define BOOST_SPIRIT_MATCH_HPP
10 
11 #include <boost/spirit/home/classic/namespace.hpp>
12 #include <boost/spirit/home/classic/core/config.hpp>
13 #include <boost/spirit/home/classic/core/nil.hpp>
14 #include <boost/call_traits.hpp>
15 #include <boost/optional.hpp>
16 #include <boost/spirit/home/classic/core/assert.hpp>
17 #include <boost/spirit/home/classic/core/safe_bool.hpp>
18 #include <boost/spirit/home/classic/core/impl/match_attr_traits.ipp>
19 #include <boost/type_traits/add_const.hpp>
20 #include <boost/type_traits/add_reference.hpp>
21 #include <boost/type_traits/conditional.hpp>
22 #include <boost/type_traits/is_reference.hpp>
23 
24 namespace boost { namespace spirit {
25 
26 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
27 
28     ///////////////////////////////////////////////////////////////////////////
29     //
30     //  match class
31     //
32     //      The match holds the result of a parser. A match object evaluates
33     //      to true when a successful match is found, otherwise false. The
34     //      length of the match is the number of characters (or tokens) that
35     //      is successfully matched. This can be queried through its length()
36     //      member function. A negative value means that the match is
37     //      unsuccessful.
38     //
39     //      Each parser may have an associated attribute. This attribute is
40     //      also returned back to the client on a successful parse through
41     //      the match object. The match's value() member function returns the
42     //      match's attribute.
43     //
44     //      A match attribute is valid:
45     //
46     //          * on a successful match
47     //          * when its value is set through the value(val) member function
48     //          * if it is assigned or copied from a compatible match object
49     //            (e.g. match<double> from match<int>) with a valid attribute.
50     //
51     //      The match attribute is undefined:
52     //
53     //          * on an unsuccessful match
54     //          * when an attempt to copy or assign from another match object
55     //            with an incompatible attribute type (e.g. match<std::string>
56     //            from match<int>).
57     //
58     //      The member function has_valid_attribute() can be queried to know if
59     //      it is safe to get the match's attribute. The attribute may be set
60     //      through the member function value(v) where v is the new attribute
61     //      value.
62     //
63     ///////////////////////////////////////////////////////////////////////////
64     template <typename T = nil_t>
65     class match : public safe_bool<match<T> >
66     {
67         typedef typename
68             conditional<
69                 is_reference<T>::value
70               , T
71               , typename add_reference<
72                     typename add_const<T>::type
73                 >::type
74             >::type attr_ref_t;
75 
76     public:
77 
78         typedef typename boost::optional<T> optional_type;
79         typedef attr_ref_t ctor_param_t;
80         typedef attr_ref_t return_t;
81         typedef T attr_t;
82 
83                                 match();
84         explicit                match(std::size_t length);
85                                 match(std::size_t length, ctor_param_t val);
86 
87         bool                    operator!() const;
88         std::ptrdiff_t          length() const;
89         bool                    has_valid_attribute() const;
90         return_t                value() const;
91         void                    swap(match& other);
92 
93         template <typename T2>
match(match<T2> const & other)94         match(match<T2> const& other)
95         : len(other.length()), val()
96         {
97             impl::match_attr_traits<T>::copy(val, other);
98         }
99 
100         template <typename T2>
101         match&
operator =(match<T2> const & other)102         operator=(match<T2> const& other)
103         {
104             impl::match_attr_traits<T>::assign(val, other);
105             len = other.length();
106             return *this;
107         }
108 
109         template <typename MatchT>
110         void
concat(MatchT const & other)111         concat(MatchT const& other)
112         {
113             BOOST_SPIRIT_ASSERT(*this && other);
114             len += other.length();
115         }
116 
117         template <typename ValueT>
118         void
value(ValueT const & val_)119         value(ValueT const& val_)
120         {
121             impl::match_attr_traits<T>::set_value(val, val_, is_reference<T>());
122         }
123 
operator_bool() const124         bool operator_bool() const
125         {
126             return len >= 0;
127         }
128 
129     private:
130 
131         std::ptrdiff_t len;
132         optional_type val;
133     };
134 
135     ///////////////////////////////////////////////////////////////////////////
136     //
137     //  match class specialization for nil_t values
138     //
139     ///////////////////////////////////////////////////////////////////////////
140     template <>
141     class match<nil_t> : public safe_bool<match<nil_t> >
142     {
143     public:
144 
145         typedef nil_t attr_t;
146         typedef nil_t return_t;
147 
148                                 match();
149         explicit                match(std::size_t length);
150                                 match(std::size_t length, nil_t);
151 
152         bool                    operator!() const;
153         bool                    has_valid_attribute() const;
154         std::ptrdiff_t          length() const;
155         nil_t                   value() const;
156         void                    value(nil_t);
157         void                    swap(match& other);
158 
159         template <typename T>
match(match<T> const & other)160         match(match<T> const& other)
161         : len(other.length()) {}
162 
163         template <typename T>
164         match<>&
operator =(match<T> const & other)165         operator=(match<T> const& other)
166         {
167             len = other.length();
168             return *this;
169         }
170 
171         template <typename T>
172         void
concat(match<T> const & other)173         concat(match<T> const& other)
174         {
175             BOOST_SPIRIT_ASSERT(*this && other);
176             len += other.length();
177         }
178 
operator_bool() const179         bool operator_bool() const
180         {
181             return len >= 0;
182         }
183 
184     private:
185 
186         std::ptrdiff_t len;
187     };
188 
189 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
190 
191 }} // namespace BOOST_SPIRIT_CLASSIC_NS
192 
193 #endif
194 #include <boost/spirit/home/classic/core/impl/match.ipp>
195 
196