Line data Source code
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 : // unsucessful. 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 0 : 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> 94 0 : match(match<T2> const& other) 95 0 : : len(other.length()), val() 96 : { 97 0 : impl::match_attr_traits<T>::copy(val, other); 98 : } 99 : 100 : template <typename T2> 101 : match& 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 111 : concat(MatchT const& other) 112 : { 113 : BOOST_SPIRIT_ASSERT(*this && other); 114 : len += other.length(); 115 : } 116 : 117 : template <typename ValueT> 118 : void 119 : value(ValueT const& val_) 120 : { 121 : impl::match_attr_traits<T>::set_value(val, val_, is_reference<T>()); 122 : } 123 : 124 0 : 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> 160 0 : match(match<T> const& other) 161 0 : : len(other.length()) {} 162 : 163 : template <typename T> 164 : match<>& 165 : operator=(match<T> const& other) 166 : { 167 : len = other.length(); 168 : return *this; 169 : } 170 : 171 : template <typename T> 172 : void 173 0 : concat(match<T> const& other) 174 : { 175 0 : BOOST_SPIRIT_ASSERT(*this && other); 176 0 : len += other.length(); 177 0 : } 178 : 179 0 : bool operator_bool() const 180 : { 181 0 : 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 :