3 * Copyright (c) 1998-2002
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
13 * LOCATION: see http://www.boost.org for most recent version.
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Declares template class sub_match.
19 #ifndef BOOST_REGEX_V4_SUB_MATCH_HPP
20 #define BOOST_REGEX_V4_SUB_MATCH_HPP
24 #pragma warning(disable: 4103)
26 #ifdef BOOST_HAS_ABI_HEADERS
27 # include BOOST_ABI_PREFIX
35 template <class BidiIterator>
36 struct sub_match : public std::pair<BidiIterator, BidiIterator>
38 typedef typename re_detail::regex_iterator_traits<BidiIterator>::value_type value_type;
39 #if defined(BOOST_NO_STD_ITERATOR_TRAITS) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
40 typedef std::ptrdiff_t difference_type;
42 typedef typename re_detail::regex_iterator_traits<BidiIterator>::difference_type difference_type;
44 typedef BidiIterator iterator_type;
45 typedef BidiIterator iterator;
46 typedef BidiIterator const_iterator;
50 sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}
51 sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}
52 #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
53 && !BOOST_WORKAROUND(BOOST_MSVC, < 1310)\
54 && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)\
55 && !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
56 template <class T, class A>
57 operator std::basic_string<value_type, T, A> ()const
59 return std::basic_string<value_type, T, A>(this->first, this->second);
62 operator std::basic_string<value_type> ()const
67 difference_type BOOST_REGEX_CALL length()const
69 difference_type n = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
72 std::basic_string<value_type> str()const
74 std::basic_string<value_type> result;
75 std::size_t len = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
77 BidiIterator i = this->first;
78 while(i != this->second)
85 int compare(const sub_match& s)const
87 if(matched != s.matched)
88 return static_cast<int>(matched) - static_cast<int>(s.matched);
89 return str().compare(s.str());
91 int compare(const std::basic_string<value_type>& s)const
93 return str().compare(s);
95 int compare(const value_type* p)const
97 return str().compare(p);
100 bool operator==(const sub_match& that)const
101 { return compare(that) == 0; }
102 bool BOOST_REGEX_CALL operator !=(const sub_match& that)const
103 { return compare(that) != 0; }
104 bool operator<(const sub_match& that)const
105 { return compare(that) < 0; }
106 bool operator>(const sub_match& that)const
107 { return compare(that) > 0; }
108 bool operator<=(const sub_match& that)const
109 { return compare(that) <= 0; }
110 bool operator>=(const sub_match& that)const
111 { return compare(that) >= 0; }
113 #ifdef BOOST_REGEX_MATCH_EXTRA
114 typedef std::vector<sub_match<BidiIterator> > capture_sequence_type;
116 const capture_sequence_type& captures()const
119 m_captures.reset(new capture_sequence_type());
123 // Private implementation API: DO NOT USE!
125 capture_sequence_type& get_captures()const
128 m_captures.reset(new capture_sequence_type());
133 mutable boost::scoped_ptr<capture_sequence_type> m_captures;
137 sub_match(const sub_match& that, bool
138 #ifdef BOOST_REGEX_MATCH_EXTRA
143 : std::pair<BidiIterator, BidiIterator>(that),
144 matched(that.matched)
146 #ifdef BOOST_REGEX_MATCH_EXTRA
149 m_captures.reset(new capture_sequence_type(*(that.m_captures)));
152 sub_match& operator=(const sub_match& that)
154 this->first = that.first;
155 this->second = that.second;
156 matched = that.matched;
157 #ifdef BOOST_REGEX_MATCH_EXTRA
159 get_captures() = *(that.m_captures);
165 #ifdef BOOST_OLD_REGEX_H
167 // the following are deprecated, do not use!!
170 operator unsigned int()const;
171 operator short()const
173 return (short)(int)(*this);
175 operator unsigned short()const
177 return (unsigned short)(unsigned int)(*this);
182 typedef sub_match<const char*> csub_match;
183 typedef sub_match<std::string::const_iterator> ssub_match;
184 #ifndef BOOST_NO_WREGEX
185 typedef sub_match<const wchar_t*> wcsub_match;
186 typedef sub_match<std::wstring::const_iterator> wssub_match;
189 // comparison to std::basic_string<> part 1:
190 template <class RandomAccessIterator, class traits, class Allocator>
191 inline bool operator == (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
192 const sub_match<RandomAccessIterator>& m)
193 { return s.compare(m.str()) == 0; }
194 template <class RandomAccessIterator, class traits, class Allocator>
195 inline bool operator != (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
196 const sub_match<RandomAccessIterator>& m)
197 { return s.compare(m.str()) != 0; }
198 template <class RandomAccessIterator, class traits, class Allocator>
199 inline bool operator < (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
200 const sub_match<RandomAccessIterator>& m)
201 { return s.compare(m.str()) < 0; }
202 template <class RandomAccessIterator, class traits, class Allocator>
203 inline bool operator <= (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
204 const sub_match<RandomAccessIterator>& m)
205 { return s.compare(m.str()) <= 0; }
206 template <class RandomAccessIterator, class traits, class Allocator>
207 inline bool operator >= (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
208 const sub_match<RandomAccessIterator>& m)
209 { return s.compare(m.str()) >= 0; }
210 template <class RandomAccessIterator, class traits, class Allocator>
211 inline bool operator > (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
212 const sub_match<RandomAccessIterator>& m)
213 { return s.compare(m.str()) > 0; }
214 // comparison to std::basic_string<> part 2:
215 template <class RandomAccessIterator, class traits, class Allocator>
216 inline bool operator == (const sub_match<RandomAccessIterator>& m,
217 const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
218 { return m.str().compare(s) == 0; }
219 template <class RandomAccessIterator, class traits, class Allocator>
220 inline bool operator != (const sub_match<RandomAccessIterator>& m,
221 const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
222 { return m.str().compare(s) != 0; }
223 template <class RandomAccessIterator, class traits, class Allocator>
224 inline bool operator < (const sub_match<RandomAccessIterator>& m,
225 const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
226 { return m.str().compare(s) < 0; }
227 template <class RandomAccessIterator, class traits, class Allocator>
228 inline bool operator > (const sub_match<RandomAccessIterator>& m,
229 const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
230 { return m.str().compare(s) > 0; }
231 template <class RandomAccessIterator, class traits, class Allocator>
232 inline bool operator <= (const sub_match<RandomAccessIterator>& m,
233 const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
234 { return m.str().compare(s) <= 0; }
235 template <class RandomAccessIterator, class traits, class Allocator>
236 inline bool operator >= (const sub_match<RandomAccessIterator>& m,
237 const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
238 { return m.str().compare(s) >= 0; }
239 // comparison to const charT* part 1:
240 template <class RandomAccessIterator>
241 inline bool operator == (const sub_match<RandomAccessIterator>& m,
242 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
243 { return m.str().compare(s) == 0; }
244 template <class RandomAccessIterator>
245 inline bool operator != (const sub_match<RandomAccessIterator>& m,
246 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
247 { return m.str().compare(s) != 0; }
248 template <class RandomAccessIterator>
249 inline bool operator > (const sub_match<RandomAccessIterator>& m,
250 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
251 { return m.str().compare(s) > 0; }
252 template <class RandomAccessIterator>
253 inline bool operator < (const sub_match<RandomAccessIterator>& m,
254 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
255 { return m.str().compare(s) < 0; }
256 template <class RandomAccessIterator>
257 inline bool operator >= (const sub_match<RandomAccessIterator>& m,
258 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
259 { return m.str().compare(s) >= 0; }
260 template <class RandomAccessIterator>
261 inline bool operator <= (const sub_match<RandomAccessIterator>& m,
262 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
263 { return m.str().compare(s) <= 0; }
264 // comparison to const charT* part 2:
265 template <class RandomAccessIterator>
266 inline bool operator == (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
267 const sub_match<RandomAccessIterator>& m)
268 { return m.str().compare(s) == 0; }
269 template <class RandomAccessIterator>
270 inline bool operator != (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
271 const sub_match<RandomAccessIterator>& m)
272 { return m.str().compare(s) != 0; }
273 template <class RandomAccessIterator>
274 inline bool operator < (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
275 const sub_match<RandomAccessIterator>& m)
276 { return m.str().compare(s) > 0; }
277 template <class RandomAccessIterator>
278 inline bool operator > (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
279 const sub_match<RandomAccessIterator>& m)
280 { return m.str().compare(s) < 0; }
281 template <class RandomAccessIterator>
282 inline bool operator <= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
283 const sub_match<RandomAccessIterator>& m)
284 { return m.str().compare(s) >= 0; }
285 template <class RandomAccessIterator>
286 inline bool operator >= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
287 const sub_match<RandomAccessIterator>& m)
288 { return m.str().compare(s) <= 0; }
290 // comparison to const charT& part 1:
291 template <class RandomAccessIterator>
292 inline bool operator == (const sub_match<RandomAccessIterator>& m,
293 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
294 { return m.str().compare(0, m.length(), &s, 1) == 0; }
295 template <class RandomAccessIterator>
296 inline bool operator != (const sub_match<RandomAccessIterator>& m,
297 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
298 { return m.str().compare(0, m.length(), &s, 1) != 0; }
299 template <class RandomAccessIterator>
300 inline bool operator > (const sub_match<RandomAccessIterator>& m,
301 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
302 { return m.str().compare(0, m.length(), &s, 1) > 0; }
303 template <class RandomAccessIterator>
304 inline bool operator < (const sub_match<RandomAccessIterator>& m,
305 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
306 { return m.str().compare(0, m.length(), &s, 1) < 0; }
307 template <class RandomAccessIterator>
308 inline bool operator >= (const sub_match<RandomAccessIterator>& m,
309 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
310 { return m.str().compare(0, m.length(), &s, 1) >= 0; }
311 template <class RandomAccessIterator>
312 inline bool operator <= (const sub_match<RandomAccessIterator>& m,
313 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
314 { return m.str().compare(0, m.length(), &s, 1) <= 0; }
315 // comparison to const charT* part 2:
316 template <class RandomAccessIterator>
317 inline bool operator == (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
318 const sub_match<RandomAccessIterator>& m)
319 { return m.str().compare(0, m.length(), &s, 1) == 0; }
320 template <class RandomAccessIterator>
321 inline bool operator != (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
322 const sub_match<RandomAccessIterator>& m)
323 { return m.str().compare(0, m.length(), &s, 1) != 0; }
324 template <class RandomAccessIterator>
325 inline bool operator < (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
326 const sub_match<RandomAccessIterator>& m)
327 { return m.str().compare(0, m.length(), &s, 1) > 0; }
328 template <class RandomAccessIterator>
329 inline bool operator > (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
330 const sub_match<RandomAccessIterator>& m)
331 { return m.str().compare(0, m.length(), &s, 1) < 0; }
332 template <class RandomAccessIterator>
333 inline bool operator <= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
334 const sub_match<RandomAccessIterator>& m)
335 { return m.str().compare(0, m.length(), &s, 1) >= 0; }
336 template <class RandomAccessIterator>
337 inline bool operator >= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
338 const sub_match<RandomAccessIterator>& m)
339 { return m.str().compare(0, m.length(), &s, 1) <= 0; }
341 // addition operators:
342 template <class RandomAccessIterator, class traits, class Allocator>
343 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>
344 operator + (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
345 const sub_match<RandomAccessIterator>& m)
347 std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
348 result.reserve(s.size() + m.length() + 1);
349 return result.append(s).append(m.first, m.second);
351 template <class RandomAccessIterator, class traits, class Allocator>
352 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>
353 operator + (const sub_match<RandomAccessIterator>& m,
354 const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
356 std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
357 result.reserve(s.size() + m.length() + 1);
358 return result.append(m.first, m.second).append(s);
360 #if !(defined(__GNUC__) && defined(BOOST_NO_STD_LOCALE))
361 template <class RandomAccessIterator>
362 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
363 operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
364 const sub_match<RandomAccessIterator>& m)
366 std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
367 result.reserve(std::char_traits<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
368 return result.append(s).append(m.first, m.second);
370 template <class RandomAccessIterator>
371 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
372 operator + (const sub_match<RandomAccessIterator>& m,
373 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const * s)
375 std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
376 result.reserve(std::char_traits<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
377 return result.append(m.first, m.second).append(s);
380 // worwaround versions:
381 template <class RandomAccessIterator>
382 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
383 operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
384 const sub_match<RandomAccessIterator>& m)
388 template <class RandomAccessIterator>
389 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
390 operator + (const sub_match<RandomAccessIterator>& m,
391 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const * s)
396 template <class RandomAccessIterator>
397 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
398 operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
399 const sub_match<RandomAccessIterator>& m)
401 std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
402 result.reserve(m.length() + 2);
403 return result.append(1, s).append(m.first, m.second);
405 template <class RandomAccessIterator>
406 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
407 operator + (const sub_match<RandomAccessIterator>& m,
408 typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
410 std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
411 result.reserve(m.length() + 2);
412 return result.append(m.first, m.second).append(1, s);
414 template <class RandomAccessIterator>
415 inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
416 operator + (const sub_match<RandomAccessIterator>& m1,
417 const sub_match<RandomAccessIterator>& m2)
419 std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
420 result.reserve(m1.length() + m2.length() + 1);
421 return result.append(m1.first, m1.second).append(m2.first, m2.second);
423 #ifndef BOOST_NO_STD_LOCALE
424 template <class charT, class traits, class RandomAccessIterator>
425 std::basic_ostream<charT, traits>&
426 operator << (std::basic_ostream<charT, traits>& os,
427 const sub_match<RandomAccessIterator>& s)
429 return (os << s.str());
432 template <class RandomAccessIterator>
433 std::ostream& operator << (std::ostream& os,
434 const sub_match<RandomAccessIterator>& s)
436 return (os << s.str());
440 #ifdef BOOST_OLD_REGEX_H
442 template <class BidiIterator, class charT>
443 int do_toi(BidiIterator i, BidiIterator j, char c, int radix)
447 int result = std::strtol(s.c_str(), &p, radix);
448 if(*p)raise_regex_exception("Bad sub-expression");
454 template <class I, class charT>
455 int do_toi(I& i, I j, charT c)
458 while((i != j) && (isdigit(*i)))
460 result = result*10 + (*i - '0');
468 template <class BidiIterator>
469 sub_match<BidiIterator>::operator int()const
471 BidiIterator i = first;
472 BidiIterator j = second;
473 if(i == j)raise_regex_exception("Bad sub-expression");
475 if((i != j) && (*i == '-'))
480 neg *= re_detail::do_toi(i, j, *i);
481 if(i != j)raise_regex_exception("Bad sub-expression");
484 template <class BidiIterator>
485 sub_match<BidiIterator>::operator unsigned int()const
487 BidiIterator i = first;
488 BidiIterator j = second;
490 raise_regex_exception("Bad sub-expression");
491 return re_detail::do_toi(i, j, *first);
498 #pragma warning(push)
499 #pragma warning(disable: 4103)
501 #ifdef BOOST_HAS_ABI_HEADERS
502 # include BOOST_ABI_SUFFIX