[29] | 1 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 2 | /// \file sub_match.hpp |
---|
| 3 | /// Contains the definition of the class template sub_match\<\> |
---|
| 4 | /// and associated helper functions |
---|
| 5 | // |
---|
| 6 | // Copyright 2004 Eric Niebler. Distributed under the Boost |
---|
| 7 | // Software License, Version 1.0. (See accompanying file |
---|
| 8 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
---|
| 9 | |
---|
| 10 | #ifndef BOOST_XPRESSIVE_SUB_MATCH_HPP_EAN_10_04_2005 |
---|
| 11 | #define BOOST_XPRESSIVE_SUB_MATCH_HPP_EAN_10_04_2005 |
---|
| 12 | |
---|
| 13 | // MS compatible compilers support #pragma once |
---|
| 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
---|
| 15 | # pragma once |
---|
| 16 | #endif |
---|
| 17 | |
---|
| 18 | #include <iosfwd> |
---|
| 19 | #include <string> |
---|
| 20 | #include <utility> |
---|
| 21 | #include <iterator> |
---|
| 22 | #include <algorithm> |
---|
| 23 | #include <boost/iterator/iterator_traits.hpp> |
---|
| 24 | |
---|
| 25 | //{{AFX_DOC_COMMENT |
---|
| 26 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 27 | // This is a hack to get Doxygen to show the inheritance relation between |
---|
| 28 | // sub_match<T> and std::pair<T,T>. |
---|
| 29 | #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED |
---|
| 30 | /// INTERNAL ONLY |
---|
| 31 | namespace std |
---|
| 32 | { |
---|
| 33 | /// INTERNAL ONLY |
---|
| 34 | template<typename, typename> struct pair {}; |
---|
| 35 | } |
---|
| 36 | #endif |
---|
| 37 | //}}AFX_DOC_COMMENT |
---|
| 38 | |
---|
| 39 | namespace boost { namespace xpressive |
---|
| 40 | { |
---|
| 41 | |
---|
| 42 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 43 | // sub_match |
---|
| 44 | // |
---|
| 45 | /// \brief Class template sub_match denotes the sequence of characters matched by a particular marked sub-expression. |
---|
| 46 | /// |
---|
| 47 | /// When the marked sub-expression denoted by an object of type sub_match\<\> participated in a |
---|
| 48 | /// regular expression match then member matched evaluates to true, and members first and second |
---|
| 49 | /// denote the range of characters [first,second) which formed that match. Otherwise matched is false, |
---|
| 50 | /// and members first and second contained undefined values. |
---|
| 51 | /// |
---|
| 52 | /// If an object of type sub_match\<\> represents sub-expression 0 - that is to say the whole match - |
---|
| 53 | /// then member matched is always true, unless a partial match was obtained as a result of the flag |
---|
| 54 | /// match_partial being passed to a regular expression algorithm, in which case member matched is |
---|
| 55 | /// false, and members first and second represent the character range that formed the partial match. |
---|
| 56 | template<typename BidiIter> |
---|
| 57 | struct sub_match |
---|
| 58 | : std::pair<BidiIter, BidiIter> |
---|
| 59 | { |
---|
| 60 | private: |
---|
| 61 | struct dummy { int i_; }; |
---|
| 62 | typedef int dummy::*bool_type; |
---|
| 63 | |
---|
| 64 | public: |
---|
| 65 | typedef typename iterator_value<BidiIter>::type value_type; |
---|
| 66 | typedef typename iterator_difference<BidiIter>::type difference_type; |
---|
| 67 | typedef std::basic_string<value_type> string_type; |
---|
| 68 | typedef BidiIter iterator; |
---|
| 69 | |
---|
| 70 | explicit sub_match(BidiIter first = BidiIter(), BidiIter second = BidiIter(), bool matched_ = false) |
---|
| 71 | : std::pair<BidiIter, BidiIter>(first, second) |
---|
| 72 | , matched(matched_) |
---|
| 73 | { |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | string_type str() const |
---|
| 77 | { |
---|
| 78 | return this->matched ? string_type(this->first, this->second) : string_type(); |
---|
| 79 | } |
---|
| 80 | |
---|
| 81 | operator string_type() const |
---|
| 82 | { |
---|
| 83 | return this->matched ? string_type(this->first, this->second) : string_type(); |
---|
| 84 | } |
---|
| 85 | |
---|
| 86 | difference_type length() const |
---|
| 87 | { |
---|
| 88 | return this->matched ? std::distance(this->first, this->second) : 0; |
---|
| 89 | } |
---|
| 90 | |
---|
| 91 | operator bool_type() const |
---|
| 92 | { |
---|
| 93 | return this->matched ? &dummy::i_ : 0; |
---|
| 94 | } |
---|
| 95 | |
---|
| 96 | bool operator !() const |
---|
| 97 | { |
---|
| 98 | return !this->matched; |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | /// \brief Performs a lexicographic string comparison |
---|
| 102 | /// \param str the string against which to compare |
---|
| 103 | /// \return the results of (*this).str().compare(str) |
---|
| 104 | int compare(string_type const &str) const |
---|
| 105 | { |
---|
| 106 | return this->str().compare(str); |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | /// \overload |
---|
| 110 | int compare(sub_match const &sub) const |
---|
| 111 | { |
---|
| 112 | return this->str().compare(sub.str()); |
---|
| 113 | } |
---|
| 114 | |
---|
| 115 | /// \overload |
---|
| 116 | int compare(value_type const *ptr) const |
---|
| 117 | { |
---|
| 118 | return this->str().compare(ptr); |
---|
| 119 | } |
---|
| 120 | |
---|
| 121 | /// \brief true if this sub-match participated in the full match. |
---|
| 122 | bool matched; |
---|
| 123 | }; |
---|
| 124 | |
---|
| 125 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 126 | /// \brief insertion operator for sending sub-matches to ostreams |
---|
| 127 | /// \param sout output stream. |
---|
| 128 | /// \param sub sub_match object to be written to the stream. |
---|
| 129 | /// \return sout \<\< sub.str() |
---|
| 130 | template<typename BidiIter, typename Char, typename Traits> |
---|
| 131 | inline std::basic_ostream<Char, Traits> &operator << |
---|
| 132 | ( |
---|
| 133 | std::basic_ostream<Char, Traits> &sout |
---|
| 134 | , sub_match<BidiIter> const &sub |
---|
| 135 | ) |
---|
| 136 | { |
---|
| 137 | typedef typename iterator_value<BidiIter>::type char_type; |
---|
| 138 | if(sub.matched) |
---|
| 139 | { |
---|
| 140 | std::ostream_iterator<char_type, Char, Traits> iout(sout); |
---|
| 141 | std::copy(sub.first, sub.second, iout); |
---|
| 142 | } |
---|
| 143 | return sout; |
---|
| 144 | } |
---|
| 145 | |
---|
| 146 | |
---|
| 147 | // BUGBUG make these more efficient |
---|
| 148 | |
---|
| 149 | template<typename BidiIter> |
---|
| 150 | bool operator == (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 151 | { |
---|
| 152 | return lhs.compare(rhs) == 0; |
---|
| 153 | } |
---|
| 154 | |
---|
| 155 | template<typename BidiIter> |
---|
| 156 | bool operator != (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 157 | { |
---|
| 158 | return lhs.compare(rhs) != 0; |
---|
| 159 | } |
---|
| 160 | |
---|
| 161 | template<typename BidiIter> |
---|
| 162 | bool operator < (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 163 | { |
---|
| 164 | return lhs.compare(rhs) < 0; |
---|
| 165 | } |
---|
| 166 | |
---|
| 167 | template<typename BidiIter> |
---|
| 168 | bool operator <= (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 169 | { |
---|
| 170 | return lhs.compare(rhs) <= 0; |
---|
| 171 | } |
---|
| 172 | |
---|
| 173 | template<typename BidiIter> |
---|
| 174 | bool operator >= (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 175 | { |
---|
| 176 | return lhs.compare(rhs)>= 0; |
---|
| 177 | } |
---|
| 178 | |
---|
| 179 | template<typename BidiIter> |
---|
| 180 | bool operator> (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 181 | { |
---|
| 182 | return lhs.compare(rhs)> 0; |
---|
| 183 | } |
---|
| 184 | |
---|
| 185 | template<typename BidiIter> |
---|
| 186 | bool operator == (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs) |
---|
| 187 | { |
---|
| 188 | return lhs == rhs.str(); |
---|
| 189 | } |
---|
| 190 | |
---|
| 191 | template<typename BidiIter> |
---|
| 192 | bool operator != (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs) |
---|
| 193 | { |
---|
| 194 | return lhs != rhs.str(); |
---|
| 195 | } |
---|
| 196 | |
---|
| 197 | template<typename BidiIter> |
---|
| 198 | bool operator < (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs) |
---|
| 199 | { |
---|
| 200 | return lhs < rhs.str(); |
---|
| 201 | } |
---|
| 202 | |
---|
| 203 | template<typename BidiIter> |
---|
| 204 | bool operator> (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs) |
---|
| 205 | { |
---|
| 206 | return lhs> rhs.str(); |
---|
| 207 | } |
---|
| 208 | |
---|
| 209 | template<typename BidiIter> |
---|
| 210 | bool operator >= (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs) |
---|
| 211 | { |
---|
| 212 | return lhs >= rhs.str(); |
---|
| 213 | } |
---|
| 214 | |
---|
| 215 | template<typename BidiIter> |
---|
| 216 | bool operator <= (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs) |
---|
| 217 | { |
---|
| 218 | return lhs <= rhs.str(); |
---|
| 219 | } |
---|
| 220 | |
---|
| 221 | template<typename BidiIter> |
---|
| 222 | bool operator == (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs) |
---|
| 223 | { |
---|
| 224 | return lhs.str() == rhs; |
---|
| 225 | } |
---|
| 226 | |
---|
| 227 | template<typename BidiIter> |
---|
| 228 | bool operator != (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs) |
---|
| 229 | { |
---|
| 230 | return lhs.str() != rhs; |
---|
| 231 | } |
---|
| 232 | |
---|
| 233 | template<typename BidiIter> |
---|
| 234 | bool operator < (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs) |
---|
| 235 | { |
---|
| 236 | return lhs.str() < rhs; |
---|
| 237 | } |
---|
| 238 | |
---|
| 239 | template<typename BidiIter> |
---|
| 240 | bool operator> (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs) |
---|
| 241 | { |
---|
| 242 | return lhs.str()> rhs; |
---|
| 243 | } |
---|
| 244 | |
---|
| 245 | template<typename BidiIter> |
---|
| 246 | bool operator >= (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs) |
---|
| 247 | { |
---|
| 248 | return lhs.str()>= rhs; |
---|
| 249 | } |
---|
| 250 | |
---|
| 251 | template<typename BidiIter> |
---|
| 252 | bool operator <= (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs) |
---|
| 253 | { |
---|
| 254 | return lhs.str() <= rhs; |
---|
| 255 | } |
---|
| 256 | |
---|
| 257 | template<typename BidiIter> |
---|
| 258 | bool operator == (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 259 | { |
---|
| 260 | return lhs == rhs.str(); |
---|
| 261 | } |
---|
| 262 | |
---|
| 263 | template<typename BidiIter> |
---|
| 264 | bool operator != (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 265 | { |
---|
| 266 | return lhs != rhs.str(); |
---|
| 267 | } |
---|
| 268 | |
---|
| 269 | template<typename BidiIter> |
---|
| 270 | bool operator < (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 271 | { |
---|
| 272 | return lhs < rhs.str(); |
---|
| 273 | } |
---|
| 274 | |
---|
| 275 | template<typename BidiIter> |
---|
| 276 | bool operator> (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 277 | { |
---|
| 278 | return lhs> rhs.str(); |
---|
| 279 | } |
---|
| 280 | |
---|
| 281 | template<typename BidiIter> |
---|
| 282 | bool operator >= (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 283 | { |
---|
| 284 | return lhs >= rhs.str(); |
---|
| 285 | } |
---|
| 286 | |
---|
| 287 | template<typename BidiIter> |
---|
| 288 | bool operator <= (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs) |
---|
| 289 | { |
---|
| 290 | return lhs <= rhs.str(); |
---|
| 291 | } |
---|
| 292 | |
---|
| 293 | template<typename BidiIter> |
---|
| 294 | bool operator == (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs) |
---|
| 295 | { |
---|
| 296 | return lhs.str() == rhs; |
---|
| 297 | } |
---|
| 298 | |
---|
| 299 | template<typename BidiIter> |
---|
| 300 | bool operator != (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs) |
---|
| 301 | { |
---|
| 302 | return lhs.str() != rhs; |
---|
| 303 | } |
---|
| 304 | |
---|
| 305 | template<typename BidiIter> |
---|
| 306 | bool operator < (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs) |
---|
| 307 | { |
---|
| 308 | return lhs.str() < rhs; |
---|
| 309 | } |
---|
| 310 | |
---|
| 311 | template<typename BidiIter> |
---|
| 312 | bool operator> (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs) |
---|
| 313 | { |
---|
| 314 | return lhs.str()> rhs; |
---|
| 315 | } |
---|
| 316 | |
---|
| 317 | template<typename BidiIter> |
---|
| 318 | bool operator >= (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs) |
---|
| 319 | { |
---|
| 320 | return lhs.str()>= rhs; |
---|
| 321 | } |
---|
| 322 | |
---|
| 323 | template<typename BidiIter> |
---|
| 324 | bool operator <= (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs) |
---|
| 325 | { |
---|
| 326 | return lhs.str() <= rhs; |
---|
| 327 | } |
---|
| 328 | |
---|
| 329 | }} // namespace boost::xpressive |
---|
| 330 | |
---|
| 331 | #endif |
---|