~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/regex/v3/regex.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Copyright (c) 1998-2002
 
4
 * Dr John Maddock
 
5
 *
 
6
 * Permission to use, copy, modify, distribute and sell this software
 
7
 * and its documentation for any purpose is hereby granted without fee,
 
8
 * provided that the above copyright notice appear in all copies and
 
9
 * that both that copyright notice and this permission notice appear
 
10
 * in supporting documentation.  Dr John Maddock makes no representations
 
11
 * about the suitability of this software for any purpose.
 
12
 * It is provided "as is" without express or implied warranty.
 
13
 *
 
14
 */
 
15
 
 
16
 /*
 
17
  *   LOCATION:    see http://www.boost.org for most recent version.
 
18
  *   FILE         regex.cpp
 
19
  *   VERSION      see <boost/version.hpp>
 
20
  *   DESCRIPTION: Declares boost::reg_expression<> and associated
 
21
  *                functions and classes. This header is the main
 
22
  *                entry point for the template regex code.
 
23
  */
 
24
 
 
25
 
 
26
/* start with C compatibility API */
 
27
 
 
28
#ifndef BOOST_RE_REGEX_HPP_INCLUDED
 
29
#define BOOST_RE_REGEX_HPP_INCLUDED
 
30
 
 
31
#ifndef BOOST_RE_CREGEX_HPP
 
32
#include <boost/cregex.hpp>
 
33
#endif
 
34
 
 
35
#ifdef __cplusplus
 
36
 
 
37
// what follows is all C++ don't include in C builds!!
 
38
 
 
39
#ifdef BOOST_REGEX_DEBUG
 
40
# include <iosfwd>
 
41
#endif
 
42
 
 
43
#include <new>
 
44
#include <cstring>
 
45
#ifndef BOOST_REGEX_CONFIG_HPP
 
46
#include <boost/regex/config.hpp>
 
47
#endif
 
48
#ifndef BOOST_REGEX_FWD_HPP
 
49
#include <boost/regex_fwd.hpp>
 
50
#endif
 
51
#ifndef BOOST_REGEX_STACK_HPP
 
52
#include <boost/regex/v3/regex_stack.hpp>
 
53
#endif
 
54
#ifndef BOOST_REGEX_RAW_BUFFER_HPP
 
55
#include <boost/regex/v3/regex_raw_buffer.hpp>
 
56
#endif
 
57
#ifndef BOOST_REGEX_KMP_HPP
 
58
#include <boost/regex/v3/regex_kmp.hpp>
 
59
#endif
 
60
#ifndef BOOST_RE_PAT_EXCEPT_HPP
 
61
#include <boost/regex/pattern_except.hpp>
 
62
#endif
 
63
#ifndef BOOST_REGEX_TRAITS_HPP
 
64
#include <boost/regex/regex_traits.hpp>
 
65
#endif
 
66
#include <boost/type_traits/remove_cv.hpp>
 
67
#include <boost/scoped_array.hpp>
 
68
 
 
69
 
 
70
namespace boost{
 
71
 
 
72
#ifdef __BORLANDC__
 
73
   #pragma option push -a8 -b -Vx -Ve -pc -w-8027
 
74
#endif
 
75
 
 
76
namespace re_detail{
 
77
 
 
78
struct re_set_long;
 
79
struct re_syntax_base;
 
80
 
 
81
} // namespace re_detail
 
82
 
 
83
namespace deprecated{
 
84
//
 
85
// class char_regex_traits_i
 
86
// provides case insensitive traits classes (deprecated):
 
87
template <class charT>
 
88
class char_regex_traits_i : public regex_traits<charT> {};
 
89
 
 
90
template<>
 
91
class char_regex_traits_i<char> : public regex_traits<char>
 
92
{
 
93
public:
 
94
   typedef char char_type;
 
95
   typedef unsigned char uchar_type;
 
96
   typedef unsigned int size_type;
 
97
   typedef regex_traits<char> base_type;
 
98
 
 
99
   char BOOST_REGEX_CALL translate(char c, bool)const
 
100
   {
 
101
      return static_cast<const regex_traits<char>*>(this)->translate(c, true);
 
102
   }
 
103
};
 
104
 
 
105
#ifndef BOOST_NO_WREGEX
 
106
template<>
 
107
class char_regex_traits_i<wchar_t> : public regex_traits<wchar_t>
 
108
{
 
109
public:
 
110
   typedef wchar_t char_type;
 
111
   typedef unsigned short uchar_type;
 
112
   typedef unsigned int size_type;
 
113
   typedef regex_traits<wchar_t> base_type;
 
114
 
 
115
   wchar_t BOOST_REGEX_CALL translate(wchar_t c, bool)const
 
116
   {
 
117
      return static_cast<const regex_traits<wchar_t>*>(this)->translate(c, true);
 
118
   }
 
119
   boost::uint_fast32_t BOOST_REGEX_CALL lookup_classname(const wchar_t* first, const wchar_t* last)const
 
120
   {
 
121
      boost::uint_fast32_t result = static_cast<const regex_traits<wchar_t>*>(this)->lookup_classname(first, last);
 
122
      if((result & base_type::char_class_upper) == base_type::char_class_upper)
 
123
         result |= base_type::char_class_alpha;
 
124
      return result;
 
125
   }
 
126
};
 
127
#endif
 
128
} // namespace deprecated
 
129
 
 
130
 
 
131
namespace re_detail{
 
132
 
 
133
enum mask_type
 
134
{
 
135
   mask_take = 1,
 
136
   mask_skip = 2,
 
137
   mask_any = mask_skip | mask_take,
 
138
   mask_all = mask_any
 
139
};
 
140
 
 
141
struct _narrow_type{};
 
142
struct _wide_type{};
 
143
 
 
144
template <class charT>
 
145
class is_byte;
 
146
 
 
147
template<>
 
148
class is_byte<char>
 
149
{
 
150
public:
 
151
   typedef _narrow_type width_type;
 
152
};
 
153
 
 
154
template<>
 
155
class is_byte<unsigned char>
 
156
{
 
157
public:
 
158
   typedef _narrow_type width_type;
 
159
};
 
160
 
 
161
template<>
 
162
class is_byte<signed char>
 
163
{
 
164
public:
 
165
   typedef _narrow_type width_type;
 
166
};
 
167
 
 
168
template <class charT>
 
169
class is_byte
 
170
{
 
171
public:
 
172
   typedef _wide_type width_type;
 
173
};
 
174
 
 
175
 
 
176
//
 
177
// compiled structures
 
178
//
 
179
// the following defs describe the format of the compiled string
 
180
//
 
181
 
 
182
//
 
183
// enum syntax_element_type
 
184
// describes the type of a record
 
185
enum syntax_element_type
 
186
{
 
187
   syntax_element_startmark = 0,
 
188
   syntax_element_endmark = syntax_element_startmark + 1,
 
189
   syntax_element_literal = syntax_element_endmark + 1,
 
190
   syntax_element_start_line = syntax_element_literal + 1,
 
191
   syntax_element_end_line = syntax_element_start_line + 1,
 
192
   syntax_element_wild = syntax_element_end_line + 1,
 
193
   syntax_element_match = syntax_element_wild + 1,
 
194
   syntax_element_word_boundary = syntax_element_match + 1,
 
195
   syntax_element_within_word = syntax_element_word_boundary + 1,
 
196
   syntax_element_word_start = syntax_element_within_word + 1,
 
197
   syntax_element_word_end = syntax_element_word_start + 1,
 
198
   syntax_element_buffer_start = syntax_element_word_end + 1,
 
199
   syntax_element_buffer_end = syntax_element_buffer_start + 1,
 
200
   syntax_element_backref = syntax_element_buffer_end + 1,
 
201
   syntax_element_long_set = syntax_element_backref + 1,
 
202
   syntax_element_set = syntax_element_long_set + 1,
 
203
   syntax_element_jump = syntax_element_set + 1,
 
204
   syntax_element_alt = syntax_element_jump + 1,
 
205
   syntax_element_rep = syntax_element_alt + 1,
 
206
   syntax_element_combining = syntax_element_rep + 1,
 
207
   syntax_element_soft_buffer_end = syntax_element_combining + 1,
 
208
   syntax_element_restart_continue = syntax_element_soft_buffer_end + 1
 
209
};
 
210
 
 
211
#ifdef BOOST_REGEX_DEBUG
 
212
// dwa 09/26/00 - This is needed to suppress warnings about an ambiguous conversion
 
213
std::ostream& operator<<(std::ostream&, syntax_element_type);
 
214
#endif
 
215
 
 
216
union offset_type
 
217
{
 
218
   re_syntax_base* p;
 
219
   std::size_t i;
 
220
};
 
221
 
 
222
//
 
223
// struct re_syntax_base
 
224
// base class for all syntax types:
 
225
struct re_syntax_base
 
226
{
 
227
   syntax_element_type type;
 
228
   offset_type next;
 
229
   unsigned int can_be_null;
 
230
};
 
231
 
 
232
//
 
233
// struct re_brace
 
234
// marks start or end of (...)
 
235
struct re_brace : public re_syntax_base
 
236
{
 
237
   int index;
 
238
};
 
239
 
 
240
//
 
241
// struct re_literal
 
242
// marks a literal string and
 
243
// is followed by an array of charT[length]:
 
244
struct re_literal : public re_syntax_base
 
245
{
 
246
   unsigned int length;
 
247
};
 
248
 
 
249
//
 
250
// struct re_long_set
 
251
// provides data for sets [...] containing
 
252
// wide characters
 
253
struct re_set_long : public re_syntax_base
 
254
{
 
255
   unsigned int csingles, cranges, cequivalents;
 
256
   boost::uint_fast32_t cclasses;
 
257
   bool isnot;
 
258
};
 
259
 
 
260
//
 
261
// struct re_set
 
262
// provides a map of bools for sets containing
 
263
// narrow, single byte characters.
 
264
struct re_set : public re_syntax_base
 
265
{
 
266
   unsigned char _map[256];
 
267
};
 
268
 
 
269
//
 
270
// struct re_jump
 
271
// provides alternative next destination
 
272
struct re_jump : public re_syntax_base
 
273
{
 
274
   offset_type alt;
 
275
   unsigned char _map[256];
 
276
};
 
277
 
 
278
//
 
279
// struct re_repeat
 
280
// provides repeat expressions
 
281
struct re_repeat : public re_jump
 
282
{
 
283
   unsigned min, max;
 
284
   int id;
 
285
   bool leading;
 
286
   bool greedy;
 
287
   bool singleton;
 
288
};
 
289
 
 
290
 
 
291
//
 
292
// enum re_jump_size_type
 
293
// provides compiled size of re_jump
 
294
// allowing for trailing alignment
 
295
// provide this so we know how many
 
296
// bytes to insert
 
297
enum re_jump_size_type
 
298
{
 
299
   re_jump_size = (sizeof(re_jump) + padding_mask) & ~(padding_mask),
 
300
   re_repeater_size = (sizeof(re_repeat) + padding_mask) & ~(padding_mask)
 
301
};
 
302
 
 
303
} // namespace re_detail
 
304
 
 
305
//
 
306
// class basic_regex
 
307
// handles error codes and flags
 
308
 
 
309
class BOOST_REGEX_DECL regbase
 
310
{
 
311
public:
 
312
   enum flag_type_
 
313
   {
 
314
      escape_in_lists = 1,                     // '\' special inside [...]
 
315
      char_classes = escape_in_lists << 1,     // [[:CLASS:]] allowed
 
316
      intervals = char_classes << 1,           // {x,y} allowed
 
317
      limited_ops = intervals << 1,            // all of + ? and | are normal characters
 
318
      newline_alt = limited_ops << 1,          // \n is the same as |
 
319
      bk_plus_qm = newline_alt << 1,           // uses \+ and \?
 
320
      bk_braces = bk_plus_qm << 1,             // uses \{ and \}
 
321
      bk_parens = bk_braces << 1,              // uses \( and \)
 
322
      bk_refs = bk_parens << 1,                // \d allowed
 
323
      bk_vbar = bk_refs << 1,                  // uses \|
 
324
 
 
325
      use_except = bk_vbar << 1,               // exception on error
 
326
      failbit = use_except << 1,               // error flag
 
327
      literal = failbit << 1,                  // all characters are literals
 
328
      icase = literal << 1,                    // characters are matched regardless of case
 
329
      nocollate = icase << 1,                  // don't use locale specific collation
 
330
 
 
331
      basic = char_classes | intervals | limited_ops | bk_braces | bk_parens | bk_refs,
 
332
      extended = char_classes | intervals | bk_refs,
 
333
      normal = escape_in_lists | char_classes | intervals | bk_refs | nocollate,
 
334
      emacs = bk_braces | bk_parens | bk_refs | bk_vbar,
 
335
      awk = extended | escape_in_lists,
 
336
      grep = basic | newline_alt,
 
337
      egrep = extended | newline_alt,
 
338
      sed = basic,
 
339
      perl = normal
 
340
   };
 
341
   typedef unsigned int flag_type;
 
342
 
 
343
   enum restart_info
 
344
   {
 
345
      restart_any = 0,
 
346
      restart_word = 1,
 
347
      restart_line = 2,
 
348
      restart_buf = 3,
 
349
      restart_continue = 4,
 
350
      restart_lit = 5,
 
351
      restart_fixed_lit = 6
 
352
   };
 
353
 
 
354
   flag_type BOOST_REGEX_CALL flags()const
 
355
   {
 
356
      return _flags;
 
357
   }
 
358
 
 
359
   regbase();
 
360
   regbase(const regbase& b);
 
361
protected:
 
362
   flag_type _flags;
 
363
};
 
364
 
 
365
//
 
366
// some forward declarations:
 
367
namespace re_detail{
 
368
template <class iterator, class Allocator>
 
369
class _priv_match_data;
 
370
 
 
371
#if defined(BOOST_NO_STD_ITERATOR_TRAITS) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 
372
 
 
373
template <class T>
 
374
struct regex_iterator_traits 
 
375
{
 
376
  typedef typename T::iterator_category iterator_category;
 
377
  typedef typename T::value_type        value_type;
 
378
#if !defined(BOOST_NO_STD_ITERATOR)
 
379
  typedef typename T::difference_type   difference_type;
 
380
  typedef typename T::pointer           pointer;
 
381
  typedef typename T::reference         reference;
 
382
#else
 
383
  typedef std::ptrdiff_t                difference_type;
 
384
  typedef value_type*                   pointer;
 
385
  typedef value_type&                   reference;
 
386
#endif
 
387
};
 
388
 
 
389
template <class T>
 
390
struct pointer_iterator_traits
 
391
{
 
392
   typedef std::ptrdiff_t difference_type;
 
393
   typedef T value_type;
 
394
   typedef T* pointer;
 
395
   typedef T& reference;
 
396
   typedef std::random_access_iterator_tag iterator_category;
 
397
};
 
398
template <class T>
 
399
struct const_pointer_iterator_traits
 
400
{
 
401
   typedef std::ptrdiff_t difference_type;
 
402
   typedef T value_type;
 
403
   typedef const T* pointer;
 
404
   typedef const T& reference;
 
405
   typedef std::random_access_iterator_tag iterator_category;
 
406
};
 
407
 
 
408
template<>
 
409
struct regex_iterator_traits<char*> : pointer_iterator_traits<char>{};
 
410
template<>
 
411
struct regex_iterator_traits<const char*> : const_pointer_iterator_traits<char>{};
 
412
template<>
 
413
struct regex_iterator_traits<wchar_t*> : pointer_iterator_traits<wchar_t>{};
 
414
template<>
 
415
struct regex_iterator_traits<const wchar_t*> : const_pointer_iterator_traits<wchar_t>{};
 
416
 
 
417
#if defined(__SGI_STL_PORT) && defined(__STL_DEBUG)
 
418
template<>
 
419
struct regex_iterator_traits<std::string::iterator> : pointer_iterator_traits<char>{};
 
420
template<>
 
421
struct regex_iterator_traits<std::string::const_iterator> : const_pointer_iterator_traits<char>{};
 
422
#ifndef BOOST_NO_STD_WSTRING
 
423
template<>
 
424
struct regex_iterator_traits<std::wstring::iterator> : pointer_iterator_traits<wchar_t>{};
 
425
template<>
 
426
struct regex_iterator_traits<std::wstring::const_iterator> : const_pointer_iterator_traits<wchar_t>{};
 
427
#endif // BOOST_NO_WSTRING
 
428
#endif // stport
 
429
 
 
430
#else
 
431
 
 
432
template <class T>
 
433
struct regex_iterator_traits : public std::iterator_traits<T> {};
 
434
 
 
435
#endif
 
436
 
 
437
template <class I>
 
438
struct def_alloc_param_traits
 
439
{
 
440
   typedef typename regex_iterator_traits<I>::value_type const_value_type;
 
441
   typedef typename remove_cv<const_value_type>::type type;
 
442
};
 
443
template <>
 
444
struct def_alloc_param_traits<const char*>
 
445
{
 
446
   typedef char type;
 
447
};
 
448
template <>
 
449
struct def_alloc_param_traits<const wchar_t*>
 
450
{
 
451
   typedef wchar_t type;
 
452
};
 
453
 
 
454
}
 
455
 
 
456
template <class iterator, class Allocator =
 
457
#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300))
 
458
BOOST_DEFAULT_ALLOCATOR(typename re_detail::def_alloc_param_traits<iterator>::type) >
 
459
#else
 
460
BOOST_DEFAULT_ALLOCATOR(re_detail::def_alloc_param_traits<iterator>::type) >
 
461
#endif
 
462
class match_results;
 
463
 
 
464
//
 
465
// class reg_expression
 
466
// represents the compiled
 
467
// regular expression:
 
468
//
 
469
 
 
470
#ifdef BOOST_MSVC
 
471
#pragma warning(push)
 
472
#pragma warning(disable : 4251 4231 4660)
 
473
#endif
 
474
 
 
475
#ifdef BOOST_REGEX_NO_FWD
 
476
template <class charT, class traits = regex_traits<charT>, class Allocator = BOOST_DEFAULT_ALLOCATOR(charT) >
 
477
#else
 
478
template <class charT, class traits, class Allocator >
 
479
#endif
 
480
class reg_expression : public regbase
 
481
{
 
482
public:
 
483
   typedef typename traits::size_type traits_size_type;
 
484
   typedef typename traits::uchar_type traits_uchar_type;
 
485
   typedef typename traits::string_type traits_string_type;
 
486
   // typedefs:
 
487
   typedef charT char_type;
 
488
   typedef traits traits_type;
 
489
 
 
490
   // locale_type
 
491
   // placeholder for actual locale type used by the
 
492
   // traits class to localise *this.
 
493
   typedef typename traits::locale_type locale_type;
 
494
   // value_type
 
495
   typedef charT value_type;
 
496
   // reference, const_reference
 
497
   typedef charT& reference;
 
498
   typedef const charT& const_reference;
 
499
   // iterator, const_iterator
 
500
   typedef const charT* const_iterator;
 
501
   typedef const_iterator iterator;
 
502
   // difference_type
 
503
   typedef typename Allocator::difference_type difference_type;
 
504
   // size_type
 
505
   typedef typename Allocator::size_type size_type;   
 
506
   // allocator_type
 
507
   typedef Allocator allocator_type;
 
508
   typedef Allocator alloc_type;
 
509
   // flag_type
 
510
   typedef regbase::flag_type flag_type;
 
511
   
 
512
public:
 
513
   explicit reg_expression(const Allocator& a = Allocator());
 
514
   explicit reg_expression(const charT* p, flag_type f = regbase::normal, const Allocator& a = Allocator());
 
515
   reg_expression(const charT* p1, const charT* p2, flag_type f = regbase::normal, const Allocator& a = Allocator());
 
516
   reg_expression(const charT* p, size_type len, flag_type f, const Allocator& a = Allocator());
 
517
   reg_expression(const reg_expression&);
 
518
   ~reg_expression();
 
519
   reg_expression& BOOST_REGEX_CALL operator=(const reg_expression&);
 
520
   reg_expression& BOOST_REGEX_CALL operator=(const charT* ptr)
 
521
   {
 
522
      set_expression(ptr, regbase::normal | regbase::use_except);
 
523
      return *this;
 
524
   }
 
525
 
 
526
   //
 
527
   // assign:
 
528
   reg_expression& assign(const reg_expression& that)
 
529
   { return *this = that; }
 
530
   reg_expression& assign(const charT* ptr, flag_type f = regbase::normal)
 
531
   {
 
532
      set_expression(ptr, f | regbase::use_except);
 
533
      return *this;
 
534
   }
 
535
 
 
536
   reg_expression& assign(const charT* first,
 
537
                          const charT* last,
 
538
                          flag_type f = regbase::normal)
 
539
   {
 
540
      set_expression(first, last, f | regbase::use_except);
 
541
      return *this;
 
542
   }
 
543
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !(defined(__IBMCPP__) && (__IBMCPP__ <= 502))
 
544
 
 
545
   template <class ST, class SA>
 
546
   unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regbase::normal)
 
547
   { return set_expression(p.data(), p.data() + p.size(), f); }
 
548
 
 
549
   template <class ST, class SA>
 
550
   explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regbase::normal, const Allocator& a = Allocator())
 
551
    : data(a), pkmp(0), error_code_(REG_EMPTY), _expression(0) { set_expression(p, f | regbase::use_except); }
 
552
 
 
553
   template <class I>
 
554
   reg_expression(I first, I last, flag_type f = regbase::normal, const Allocator& al = Allocator())
 
555
    : data(al), pkmp(0), error_code_(REG_EMPTY), _expression(0)
 
556
   {
 
557
      size_type len = last-first;
 
558
      scoped_array<charT> a(new charT[len]);
 
559
      std::copy(first, last, a.get());
 
560
      set_expression(a.get(), a.get() + len, f | regbase::use_except);
 
561
   }
 
562
 
 
563
   template <class ST, class SA>
 
564
   reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
 
565
   {
 
566
      set_expression(p.c_str(), p.c_str() + p.size(), regbase::normal | regbase::use_except);
 
567
      return *this;
 
568
   }
 
569
 
 
570
   template <class string_traits, class A>
 
571
   reg_expression& BOOST_REGEX_CALL assign(
 
572
       const std::basic_string<charT, string_traits, A>& s,
 
573
       flag_type f = regbase::normal)
 
574
   {
 
575
      set_expression(s.c_str(), s.c_str() + s.size(), f | regbase::use_except);
 
576
      return *this;
 
577
   }
 
578
 
 
579
   template <class fwd_iterator>
 
580
   reg_expression& BOOST_REGEX_CALL assign(fwd_iterator first,
 
581
                          fwd_iterator last,
 
582
                          flag_type f = regbase::normal)
 
583
   {
 
584
      size_type len = last-first;
 
585
      scoped_array<charT> a(new charT[len]);
 
586
      std::copy(first, last, a.get());
 
587
      set_expression(a.get(), a.get() + len, f | regbase::use_except);
 
588
      return *this;
 
589
   }
 
590
#else
 
591
   unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regbase::normal)
 
592
   { return set_expression(p.data(), p.data() + p.size(), f | regbase::use_except); }
 
593
 
 
594
   reg_expression(const std::basic_string<charT>& p, flag_type f = regbase::normal, const Allocator& a = Allocator())
 
595
    : data(a), pkmp(0) { set_expression(p, f | regbase::use_except); }
 
596
 
 
597
   reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
 
598
   {
 
599
      set_expression(p.c_str(), p.c_str() + p.size(), regbase::normal | regbase::use_except);
 
600
      return *this;
 
601
   }
 
602
 
 
603
   reg_expression& BOOST_REGEX_CALL assign(
 
604
       const std::basic_string<charT>& s,
 
605
       flag_type f = regbase::normal)
 
606
   {
 
607
      set_expression(s.c_str(), s.c_str() + s.size(), f | regbase::use_except);
 
608
      return *this;
 
609
   }
 
610
 
 
611
#endif
 
612
 
 
613
 
 
614
   //
 
615
   // allocator access:
 
616
   Allocator BOOST_REGEX_CALL get_allocator()const;
 
617
   //
 
618
   // locale:
 
619
   locale_type BOOST_REGEX_CALL imbue(locale_type l){ return traits_inst.imbue(l); }
 
620
   locale_type BOOST_REGEX_CALL getloc()const{ return traits_inst.getloc(); }
 
621
   //
 
622
   // flags:
 
623
   flag_type BOOST_REGEX_CALL getflags()const
 
624
   { return flags(); }
 
625
   //
 
626
   // str:
 
627
   std::basic_string<charT> BOOST_REGEX_CALL str()const
 
628
   {
 
629
      std::basic_string<charT> result;
 
630
      if(this->error_code() == 0)
 
631
         result = std::basic_string<charT>(_expression, _expression_len);
 
632
      return result;
 
633
   }
 
634
   //
 
635
   // begin, end:
 
636
   const_iterator BOOST_REGEX_CALL begin()const
 
637
   { return (this->error_code() ? 0 : _expression); }
 
638
   const_iterator BOOST_REGEX_CALL end()const
 
639
   { return (this->error_code() ? 0 : _expression + _expression_len); }
 
640
   //
 
641
   // swap:
 
642
   void BOOST_REGEX_CALL swap(reg_expression&)throw();
 
643
   //
 
644
   // size:
 
645
   size_type BOOST_REGEX_CALL size()const
 
646
   { return (this->error_code() ? 0 : _expression_len); }
 
647
   //
 
648
   // max_size:
 
649
   size_type BOOST_REGEX_CALL max_size()const
 
650
   { return UINT_MAX; }
 
651
   //
 
652
   // empty:
 
653
   bool BOOST_REGEX_CALL empty()const
 
654
   { return 0 != this->error_code(); }
 
655
 
 
656
   unsigned BOOST_REGEX_CALL mark_count()const { return (this->error_code() ? 0 : marks); }
 
657
   bool BOOST_REGEX_CALL operator==(const reg_expression&)const;
 
658
   bool BOOST_REGEX_CALL operator<(const reg_expression&)const;
 
659
   //
 
660
   // The following are deprecated as public interfaces
 
661
   // but are available for compatibility with earlier versions.
 
662
   allocator_type BOOST_REGEX_CALL allocator()const;
 
663
   const charT* BOOST_REGEX_CALL expression()const { return (this->error_code() ? 0 : _expression); }
 
664
   unsigned int BOOST_REGEX_CALL set_expression(const charT* p, const charT* end, flag_type f = regbase::normal);
 
665
   unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regbase::normal) { return set_expression(p, p + traits_type::length(p), f); }
 
666
   //
 
667
   // this should be private but template friends don't work:
 
668
   const traits_type& get_traits()const { return traits_inst; }
 
669
   unsigned int BOOST_REGEX_CALL error_code()const
 
670
   {
 
671
      return error_code_;
 
672
   }
 
673
 
 
674
private:
 
675
   traits_type traits_inst;
 
676
   re_detail::raw_storage<Allocator> data;
 
677
   unsigned _restart_type;
 
678
   unsigned marks;
 
679
   int repeats;
 
680
   unsigned char* startmap;
 
681
   std::size_t _expression_len;
 
682
   std::size_t _leading_len;
 
683
   const charT* _leading_string;
 
684
   std::size_t _leading_string_len;
 
685
   re_detail::kmp_info<charT>* pkmp;
 
686
   unsigned error_code_;
 
687
   charT* _expression;
 
688
 
 
689
   void BOOST_REGEX_CALL compile_maps();
 
690
   void BOOST_REGEX_CALL compile_map(re_detail::re_syntax_base* node, unsigned char* _map, unsigned int* pnull, unsigned char mask, re_detail::re_syntax_base* terminal = 0)const;
 
691
   bool BOOST_REGEX_CALL probe_start(re_detail::re_syntax_base* node, charT c, re_detail::re_syntax_base* terminal)const;
 
692
   bool BOOST_REGEX_CALL probe_start_null(re_detail::re_syntax_base* node, re_detail::re_syntax_base* terminal)const;
 
693
   void BOOST_REGEX_CALL fixup_apply(re_detail::re_syntax_base* b, unsigned cbraces);
 
694
   void BOOST_REGEX_CALL move_offsets(re_detail::re_syntax_base* j, unsigned size);
 
695
   re_detail::re_syntax_base* BOOST_REGEX_CALL compile_set(const charT*& first, const charT* last);
 
696
   re_detail::re_syntax_base* BOOST_REGEX_CALL compile_set_aux(re_detail::jstack<traits_string_type, Allocator>& singles, re_detail::jstack<traits_string_type, Allocator>& ranges, re_detail::jstack<boost::uint_fast32_t, Allocator>& classes, re_detail::jstack<traits_string_type, Allocator>& equivalents, bool isnot, const re_detail::_narrow_type&);
 
697
   re_detail::re_syntax_base* BOOST_REGEX_CALL compile_set_aux(re_detail::jstack<traits_string_type, Allocator>& singles, re_detail::jstack<traits_string_type, Allocator>& ranges, re_detail::jstack<boost::uint_fast32_t, Allocator>& classes, re_detail::jstack<traits_string_type, Allocator>& equivalents, bool isnot, const re_detail::_wide_type&);
 
698
   re_detail::re_syntax_base* BOOST_REGEX_CALL compile_set_simple(re_detail::re_syntax_base* dat, unsigned long cls, bool isnot = false);
 
699
   unsigned int BOOST_REGEX_CALL parse_inner_set(const charT*& first, const charT* last);
 
700
 
 
701
   re_detail::re_syntax_base* BOOST_REGEX_CALL add_simple(re_detail::re_syntax_base* dat, re_detail::syntax_element_type type, unsigned int size = sizeof(re_detail::re_syntax_base));
 
702
   re_detail::re_syntax_base* BOOST_REGEX_CALL add_literal(re_detail::re_syntax_base* dat, charT c);
 
703
   charT BOOST_REGEX_CALL parse_escape(const charT*& first, const charT* last);
 
704
   void BOOST_REGEX_CALL parse_range(const charT*& first, const charT* last, unsigned& min, unsigned& max);
 
705
   bool BOOST_REGEX_CALL skip_space(const charT*& first, const charT* last);
 
706
   unsigned int BOOST_REGEX_CALL probe_restart(re_detail::re_syntax_base* dat);
 
707
   unsigned int BOOST_REGEX_CALL fixup_leading_rep(re_detail::re_syntax_base* dat, re_detail::re_syntax_base* end);
 
708
   void BOOST_REGEX_CALL fail(unsigned int err);
 
709
 
 
710
protected:
 
711
   static int BOOST_REGEX_CALL repeat_count(const reg_expression& e)
 
712
   { return e.repeats; }
 
713
   static unsigned int BOOST_REGEX_CALL restart_type(const reg_expression& e)
 
714
   { return e._restart_type; }
 
715
   static const re_detail::re_syntax_base* BOOST_REGEX_CALL first(const reg_expression& e)
 
716
   { return (const re_detail::re_syntax_base*)e.data.data(); }
 
717
   static const unsigned char* BOOST_REGEX_CALL get_map(const reg_expression& e)
 
718
   { return e.startmap; }
 
719
   static std::size_t BOOST_REGEX_CALL leading_length(const reg_expression& e)
 
720
   { return e._leading_len; }
 
721
   static const re_detail::kmp_info<charT>* get_kmp(const reg_expression& e)
 
722
   { return e.pkmp; }
 
723
   static bool BOOST_REGEX_CALL can_start(charT c, const unsigned char* _map, unsigned char mask, const re_detail::_wide_type&);
 
724
   static bool BOOST_REGEX_CALL can_start(charT c, const unsigned char* _map, unsigned char mask, const re_detail::_narrow_type&);
 
725
};
 
726
 
 
727
#ifdef BOOST_MSVC
 
728
#pragma warning (pop)
 
729
#endif
 
730
 
 
731
template <class charT, class traits, class Allocator>
 
732
inline void BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::swap(reg_expression& that)throw()
 
733
{
 
734
   // this is not as efficient as it should be,
 
735
   // however swapping traits classes is problematic
 
736
   // so just use 'brute force' method for now:
 
737
   reg_expression<charT, traits, Allocator> e(that);
 
738
   that = *this;
 
739
   *this = e;
 
740
}
 
741
 
 
742
 
 
743
//
 
744
// class match_results and match_results_base
 
745
// handles what matched where
 
746
 
 
747
template <class iterator>
 
748
struct sub_match
 
749
{
 
750
   typedef typename re_detail::regex_iterator_traits<iterator>::value_type       value_type;
 
751
#if defined(BOOST_NO_STD_ITERATOR_TRAITS) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 
752
   typedef std::ptrdiff_t  difference_type;
 
753
#else
 
754
   typedef typename re_detail::regex_iterator_traits<iterator>::difference_type       difference_type;
 
755
#endif
 
756
   typedef iterator                                                  iterator_type;
 
757
   
 
758
   iterator first;
 
759
   iterator second;
 
760
   bool matched;
 
761
 
 
762
   operator std::basic_string<value_type> ()const
 
763
   {
 
764
      std::basic_string<value_type> result;
 
765
      std::size_t len = boost::re_detail::distance((iterator)first, (iterator)second);
 
766
      result.reserve(len);
 
767
      iterator i = first;
 
768
      while(i != second)
 
769
      {
 
770
         result.append(1, *i);
 
771
         ++i;
 
772
      }
 
773
      return result;
 
774
   }
 
775
   #ifdef BOOST_OLD_REGEX_H
 
776
   //
 
777
   // the following are deprecated, do not use!!
 
778
   //
 
779
   operator int()const;
 
780
   operator unsigned int()const;
 
781
   operator short()const
 
782
   {
 
783
      return (short)(int)(*this);
 
784
   }
 
785
   operator unsigned short()const
 
786
   {
 
787
      return (unsigned short)(unsigned int)(*this);
 
788
   }
 
789
   #endif
 
790
   sub_match() { matched = false; }
 
791
   sub_match(iterator i) : first(i), second(i), matched(false) {}
 
792
 
 
793
   bool operator==(const sub_match& that)const
 
794
   {
 
795
      return (first == that.first) && (second == that.second) && (matched == that.matched);
 
796
   }
 
797
   bool BOOST_REGEX_CALL operator !=(const sub_match& that)const
 
798
   { return !(*this == that); }
 
799
 
 
800
   difference_type BOOST_REGEX_CALL length()const
 
801
   {
 
802
      difference_type n = boost::re_detail::distance((iterator)first, (iterator)second);
 
803
      return n;
 
804
   }
 
805
};
 
806
 
 
807
#ifdef BOOST_OLD_REGEX_H
 
808
namespace re_detail{
 
809
template <class iterator, class charT>
 
810
int do_toi(iterator i, iterator j, char c, int radix)
 
811
{
 
812
   std::string s(i, j);
 
813
   char* p;
 
814
   int result = std::strtol(s.c_str(), &p, radix);
 
815
#ifndef BOOST_NO_EXCEPTIONS
 
816
   if(*p)throw bad_pattern("Bad sub-expression");
 
817
#endif
 
818
   BOOST_REGEX_NOEH_ASSERT(0 == *p)
 
819
   return result;
 
820
}
 
821
 
 
822
//
 
823
// helper:
 
824
template <class I, class charT>
 
825
int do_toi(I& i, I j, charT c)
 
826
{
 
827
   int result = 0;
 
828
   while((i != j) && (isdigit(*i)))
 
829
   {
 
830
      result = result*10 + (*i - '0');
 
831
      ++i;
 
832
   }
 
833
   return result;
 
834
}
 
835
}
 
836
 
 
837
 
 
838
template <class iterator>
 
839
sub_match<iterator>::operator int()const
 
840
{
 
841
   iterator i = first;
 
842
   iterator j = second;
 
843
#ifndef BOOST_NO_EXCEPTIONS
 
844
   if(i == j)throw bad_pattern("Bad sub-expression");
 
845
#endif
 
846
   BOOST_REGEX_NOEH_ASSERT(i != j)
 
847
   int neg = 1;
 
848
   if((i != j) && (*i == '-'))
 
849
   {
 
850
      neg = -1;
 
851
      ++i;
 
852
   }
 
853
   neg *= re_detail::do_toi(i, j, *i);
 
854
#ifndef BOOST_NO_EXCEPTIONS
 
855
   if(i != j)throw bad_pattern("Bad sub-expression");
 
856
#endif
 
857
   BOOST_REGEX_NOEH_ASSERT(i == j)
 
858
   return neg;
 
859
}
 
860
template <class iterator>
 
861
sub_match<iterator>::operator unsigned int()const
 
862
{
 
863
   iterator i = first;
 
864
   iterator j = second;
 
865
#ifndef BOOST_NO_EXCEPTIONS
 
866
   if(i == j)
 
867
      throw bad_pattern("Bad sub-expression");
 
868
#endif
 
869
   BOOST_REGEX_NOEH_ASSERT(i != j)
 
870
   return re_detail::do_toi(i, j, *first);
 
871
}
 
872
#endif
 
873
 
 
874
namespace re_detail{
 
875
 
 
876
template <class iterator, class Allocator = BOOST_DEFAULT_ALLOCATOR(typename def_alloc_param_traits<iterator>::type) >
 
877
class match_results_base
 
878
{
 
879
public:
 
880
   typedef Allocator                                                 alloc_type;
 
881
   typedef typename boost::detail::rebind_allocator<iterator, Allocator>::type  iterator_alloc;
 
882
   typedef typename iterator_alloc::size_type                        size_type;
 
883
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
 
884
   typedef typename std::iterator_traits<iterator>::difference_type  difference_type;
 
885
   typedef typename std::iterator_traits<iterator>::value_type       char_type;
 
886
#else
 
887
   typedef std::ptrdiff_t                                            difference_type;
 
888
   typedef typename re_detail::regex_iterator_traits<iterator>::value_type char_type;
 
889
#endif
 
890
   typedef sub_match<iterator>                                       value_type;
 
891
   typedef iterator                                                  iterator_type;
 
892
 
 
893
protected:
 
894
   typedef typename boost::detail::rebind_allocator<char, Allocator>::type c_alloc;
 
895
   
 
896
   struct c_reference : public c_alloc
 
897
   {
 
898
      std::size_t cmatches;
 
899
      unsigned count;
 
900
      sub_match<iterator> head, tail, null;
 
901
      unsigned int lines;
 
902
      iterator line_pos, base;
 
903
      c_reference(const Allocator& a)
 
904
         : c_alloc(a), cmatches(0), count(0), lines(0) {  }
 
905
 
 
906
      bool operator==(const c_reference& that)const
 
907
      {
 
908
         return (cmatches == that.cmatches) &&
 
909
                  (count == that.count) &&
 
910
                  (head == that.head) &&
 
911
                  (tail == that.tail) &&
 
912
                  (lines == that.lines) &&
 
913
                  (base == that.base);
 
914
      }
 
915
      bool operator!=(const c_reference& that)const
 
916
      { return !(*this == that); }
 
917
   };
 
918
 
 
919
   c_reference* ref;
 
920
 
 
921
   void BOOST_REGEX_CALL cow();
 
922
 
 
923
   // protected contructor for derived class...
 
924
   match_results_base(bool){}
 
925
   void BOOST_REGEX_CALL m_free();
 
926
 
 
927
public:
 
928
 
 
929
   match_results_base(const Allocator& a = Allocator());
 
930
 
 
931
   match_results_base(const match_results_base& m)
 
932
   {
 
933
      ref = m.ref;
 
934
      ++(ref->count);
 
935
   }
 
936
 
 
937
   match_results_base& BOOST_REGEX_CALL operator=(const match_results_base& m);
 
938
 
 
939
   ~match_results_base()
 
940
   {
 
941
      m_free();
 
942
   }
 
943
 
 
944
   size_type BOOST_REGEX_CALL size()const
 
945
   {
 
946
      //return (*this)[0].matched ? ref->cmatches : 0;
 
947
      return ref->cmatches;
 
948
   }
 
949
 
 
950
   const sub_match<iterator>& BOOST_REGEX_CALL operator[](int n) const
 
951
   {
 
952
      if((n >= 0) && ((unsigned int)n < ref->cmatches))
 
953
         return *(sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>)*n);
 
954
      return (n == -1) ? ref->head : (n == -2) ? ref->tail : ref->null;
 
955
   }
 
956
 
 
957
   Allocator BOOST_REGEX_CALL allocator()const;
 
958
 
 
959
   difference_type BOOST_REGEX_CALL length(unsigned int sub = 0)const
 
960
   {
 
961
      jm_assert(ref->cmatches);
 
962
      const sub_match<iterator>& m = (*this)[sub];
 
963
      if(m.matched == false)
 
964
         return 0;
 
965
      difference_type n = boost::re_detail::distance((iterator)m.first, (iterator)m.second);
 
966
      return n;
 
967
   }
 
968
 
 
969
   std::basic_string<char_type> str(int i)const
 
970
   {
 
971
      return static_cast<std::basic_string<char_type> >((*this)[i]);
 
972
   }
 
973
 
 
974
   unsigned int BOOST_REGEX_CALL line()const
 
975
   {
 
976
      return ref->lines;
 
977
   }
 
978
 
 
979
   difference_type BOOST_REGEX_CALL position(unsigned int sub = 0)const
 
980
   {
 
981
      jm_assert(ref->cmatches);
 
982
      const sub_match<iterator>& s = (*this)[sub];
 
983
      if(s.matched == false)
 
984
         return -1;
 
985
      difference_type n = boost::re_detail::distance((iterator)(ref->base), (iterator)(s.first));
 
986
      return n;
 
987
   }
 
988
 
 
989
   iterator BOOST_REGEX_CALL line_start()const
 
990
   {
 
991
      return ref->line_pos;
 
992
   }
 
993
 
 
994
   void swap(match_results_base& that)
 
995
   {
 
996
      c_reference* t = that.ref;
 
997
      that.ref = ref;
 
998
      ref = t;
 
999
   }
 
1000
 
 
1001
   bool operator==(const match_results_base& that)const;
 
1002
   bool operator<(const match_results_base& that)const
 
1003
   { return position() < that.position(); }
 
1004
 
 
1005
   friend class match_results<iterator, Allocator>;
 
1006
 
 
1007
   void BOOST_REGEX_CALL set_size(size_type n);
 
1008
   void BOOST_REGEX_CALL set_size(size_type n, iterator i, iterator j);
 
1009
   void BOOST_REGEX_CALL maybe_assign(const match_results_base& m);
 
1010
   void BOOST_REGEX_CALL init_fail(iterator i, iterator j);
 
1011
 
 
1012
   void BOOST_REGEX_CALL set_first(iterator i);
 
1013
   void BOOST_REGEX_CALL set_first(iterator i, std::size_t pos);
 
1014
 
 
1015
   void BOOST_REGEX_CALL set_second(iterator i)
 
1016
   {
 
1017
      cow();
 
1018
      ((sub_match<iterator>*)(ref+1))->second = i;
 
1019
      ((sub_match<iterator>*)(ref+1))->matched = true;
 
1020
      ref->tail.first = i;
 
1021
      ref->tail.matched = (ref->tail.first == ref->tail.second) ? false : true;
 
1022
   }
 
1023
 
 
1024
   void BOOST_REGEX_CALL set_second(iterator i, std::size_t pos, bool m = true)
 
1025
   {
 
1026
      cow();
 
1027
      ((sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>) * pos))->second = i;
 
1028
      ((sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>) * pos))->matched = m;
 
1029
      if(pos == 0)
 
1030
      {
 
1031
         ref->tail.first = i;
 
1032
         ref->tail.matched = (ref->tail.first == ref->tail.second) ? false : true;
 
1033
      }
 
1034
   }
 
1035
 
 
1036
   void BOOST_REGEX_CALL set_line(unsigned int i, iterator pos)
 
1037
   {
 
1038
      ref->lines = i;
 
1039
      ref->line_pos = pos;
 
1040
   }
 
1041
 
 
1042
   void BOOST_REGEX_CALL set_base(iterator pos)
 
1043
   {
 
1044
      ref->base = pos;
 
1045
   }
 
1046
};
 
1047
 
 
1048
template <class iterator, class Allocator>
 
1049
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_first(iterator i)
 
1050
{
 
1051
   cow();
 
1052
   ref->head.second = i;
 
1053
   ref->head.matched = (ref->head.first == ref->head.second) ? false : true;
 
1054
   sub_match<iterator>* p1 = (sub_match<iterator>*)(ref+1);
 
1055
   sub_match<iterator>* p2 = p1 + ref->cmatches;
 
1056
   p1->first = i;
 
1057
   p1->matched = false;
 
1058
   ++p1;
 
1059
   while(p1 != p2)
 
1060
   {
 
1061
      p1->matched = false;
 
1062
      p1->first = ref->tail.second;
 
1063
      p1->second = ref->tail.second;
 
1064
      ++p1;
 
1065
   }
 
1066
}
 
1067
 
 
1068
template <class iterator, class Allocator>
 
1069
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_first(iterator i, std::size_t pos)
 
1070
{
 
1071
   cow();
 
1072
   ((sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>) * pos))->first = i;
 
1073
   if(pos == 0)
 
1074
   {
 
1075
      ref->head.second = i;
 
1076
      ref->head.matched = (ref->head.first == ref->head.second) ? false : true;
 
1077
      sub_match<iterator>* p1 = (sub_match<iterator>*)(ref+1);
 
1078
      sub_match<iterator>* p2 = p1 + ref->cmatches;
 
1079
      p1->first = i;
 
1080
      p1->matched = false;
 
1081
      ++p1;
 
1082
      while(p1 != p2)
 
1083
      {
 
1084
         p1->matched = false;
 
1085
         p1->first = ref->tail.second;
 
1086
         p1->second = ref->tail.second;
 
1087
         ++p1;
 
1088
      }
 
1089
   }
 
1090
}
 
1091
 
 
1092
 
 
1093
template <class iterator, class Allocator>
 
1094
match_results_base<iterator, Allocator>::match_results_base(const Allocator& a)
 
1095
{
 
1096
   ref = (c_reference*)c_alloc(a).allocate(sizeof(sub_match<iterator>) + sizeof(c_reference));
 
1097
   BOOST_REGEX_NOEH_ASSERT(ref)
 
1098
#ifndef BOOST_NO_EXCEPTIONS
 
1099
   try
 
1100
   {
 
1101
#endif
 
1102
      new (ref) c_reference(a);
 
1103
      ref->cmatches = 1;
 
1104
      ref->count = 1;
 
1105
      // construct the sub_match<iterator>:
 
1106
#ifndef BOOST_NO_EXCEPTIONS
 
1107
      try
 
1108
      {
 
1109
#endif
 
1110
         new ((sub_match<iterator>*)(ref+1)) sub_match<iterator>();
 
1111
#ifndef BOOST_NO_EXCEPTIONS
 
1112
      }
 
1113
      catch(...)
 
1114
      {
 
1115
         ::boost::re_detail::pointer_destroy(ref);
 
1116
         throw;
 
1117
      }
 
1118
   }
 
1119
   catch(...)
 
1120
   {
 
1121
      c_alloc(a).deallocate((char*)(void*)ref, sizeof(sub_match<iterator>) + sizeof(c_reference));
 
1122
      throw;
 
1123
   }
 
1124
#endif
 
1125
}
 
1126
 
 
1127
template <class iterator, class Allocator>
 
1128
Allocator BOOST_REGEX_CALL match_results_base<iterator, Allocator>::allocator()const
 
1129
{
 
1130
  return *((c_alloc*)ref);
 
1131
}
 
1132
 
 
1133
template <class iterator, class Allocator>
 
1134
inline match_results_base<iterator, Allocator>& BOOST_REGEX_CALL match_results_base<iterator, Allocator>::operator=(const match_results_base<iterator, Allocator>& m)
 
1135
{
 
1136
   if(ref != m.ref)
 
1137
   {
 
1138
      m_free();
 
1139
      ref = m.ref;
 
1140
      ++(ref->count);
 
1141
   }
 
1142
   return *this;
 
1143
}
 
1144
 
 
1145
 
 
1146
template <class iterator, class Allocator>
 
1147
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::m_free()
 
1148
{
 
1149
   if(--(ref->count) == 0)
 
1150
   {
 
1151
      c_alloc a(*ref);
 
1152
      sub_match<iterator>* p1, *p2;
 
1153
      p1 = (sub_match<iterator>*)(ref+1);
 
1154
      p2 = p1 + ref->cmatches;
 
1155
      while(p1 != p2)
 
1156
      {
 
1157
         ::boost::re_detail::pointer_destroy(p1);
 
1158
         ++p1;
 
1159
      }
 
1160
      ::boost::re_detail::pointer_destroy(ref);
 
1161
      a.deallocate((char*)(void*)ref, sizeof(sub_match<iterator>) * ref->cmatches + sizeof(c_reference));
 
1162
   }
 
1163
}
 
1164
 
 
1165
template <class iterator, class Allocator>
 
1166
bool match_results_base<iterator, Allocator>::operator==(const match_results_base<iterator, Allocator>& that)const
 
1167
{
 
1168
   if(*ref != *(that.ref))
 
1169
      return false;
 
1170
   const sub_match<iterator>* p1 = (sub_match<iterator>*)(ref+1);
 
1171
   const sub_match<iterator>* p2 = p1 + ref->cmatches;
 
1172
   const sub_match<iterator>* p3 = (sub_match<iterator>*)(that.ref+1);
 
1173
   while(p1 != p2)
 
1174
   {
 
1175
      if(*p1 != *p3)
 
1176
         return false;
 
1177
      ++p1;
 
1178
      ++p3;
 
1179
   }
 
1180
   return true;
 
1181
}
 
1182
 
 
1183
template <class iterator, class Allocator>
 
1184
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_size(size_type n)
 
1185
{
 
1186
   if(ref->cmatches != n)
 
1187
   {
 
1188
      c_reference* newref = (c_reference*)ref->allocate(sizeof(sub_match<iterator>) * n + sizeof(c_reference));
 
1189
      BOOST_REGEX_NOEH_ASSERT(newref)
 
1190
#ifndef BOOST_NO_EXCEPTIONS
 
1191
      try
 
1192
      {
 
1193
#endif
 
1194
         new (newref) c_reference(*ref);
 
1195
         newref->count = 1;
 
1196
         newref->cmatches = n;
 
1197
         sub_match<iterator>* p1, *p2;
 
1198
         p1 = (sub_match<iterator>*)(newref+1);
 
1199
         p2 = p1 + newref->cmatches;
 
1200
#ifndef BOOST_NO_EXCEPTIONS
 
1201
         try
 
1202
         {
 
1203
#endif
 
1204
            while(p1 != p2)
 
1205
            {
 
1206
               new (p1) sub_match<iterator>();
 
1207
               ++p1;
 
1208
            }
 
1209
            m_free();
 
1210
#ifndef BOOST_NO_EXCEPTIONS
 
1211
         }
 
1212
         catch(...)
 
1213
         {
 
1214
            p2 = (sub_match<iterator>*)(newref+1);
 
1215
            while(p2 != p1)
 
1216
            {
 
1217
               ::boost::re_detail::pointer_destroy(p2);
 
1218
               ++p2;
 
1219
            }
 
1220
            ::boost::re_detail::pointer_destroy(ref);
 
1221
            throw;
 
1222
         }
 
1223
#endif
 
1224
         ref = newref;
 
1225
#ifndef BOOST_NO_EXCEPTIONS
 
1226
      }
 
1227
      catch(...)
 
1228
      {
 
1229
         ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * n + sizeof(c_reference));
 
1230
         throw;
 
1231
      }
 
1232
#endif
 
1233
   }
 
1234
}
 
1235
 
 
1236
template <class iterator, class Allocator>
 
1237
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_size(size_type n, iterator i, iterator j)
 
1238
{
 
1239
   if(ref->cmatches != n)
 
1240
   {
 
1241
      c_reference* newref = (c_reference*)ref->allocate(sizeof(sub_match<iterator>) * n + sizeof(c_reference));
 
1242
      BOOST_REGEX_NOEH_ASSERT(newref)
 
1243
#ifndef BOOST_NO_EXCEPTIONS
 
1244
      try{
 
1245
#endif
 
1246
         new (newref) c_reference(*ref);
 
1247
         newref->count = 1;
 
1248
         newref->cmatches = n;
 
1249
         sub_match<iterator>* p1 = (sub_match<iterator>*)(newref+1);
 
1250
         sub_match<iterator>* p2 = p1 + newref->cmatches;
 
1251
#ifndef BOOST_NO_EXCEPTIONS
 
1252
         try
 
1253
         {
 
1254
#endif
 
1255
            while(p1 != p2)
 
1256
            {
 
1257
               new (p1) sub_match<iterator>(j);
 
1258
               ++p1;
 
1259
            }
 
1260
            m_free();
 
1261
#ifndef BOOST_NO_EXCEPTIONS
 
1262
         }
 
1263
         catch(...)
 
1264
         { 
 
1265
            p2 = (sub_match<iterator>*)(newref+1);
 
1266
            while(p2 != p1)
 
1267
            {
 
1268
               ::boost::re_detail::pointer_destroy(p2);
 
1269
               ++p2;
 
1270
            }
 
1271
            ::boost::re_detail::pointer_destroy(ref);
 
1272
            throw; 
 
1273
         }
 
1274
#endif
 
1275
         ref = newref;
 
1276
#ifndef BOOST_NO_EXCEPTIONS
 
1277
      }
 
1278
      catch(...)
 
1279
      { 
 
1280
         ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * n + sizeof(c_reference)); 
 
1281
         throw; 
 
1282
      }
 
1283
#endif
 
1284
   }
 
1285
   else
 
1286
   {
 
1287
      cow();
 
1288
      // set iterators to be i, matched to false:
 
1289
      sub_match<iterator>* p1, *p2;
 
1290
      p1 = (sub_match<iterator>*)(ref+1);
 
1291
      p2 = p1 + ref->cmatches;
 
1292
      while(p1 != p2)
 
1293
      {
 
1294
         p1->first = j;
 
1295
         p1->second = j;
 
1296
         p1->matched = false;
 
1297
         ++p1;
 
1298
      }                                 
 
1299
   }
 
1300
   ref->head.first = i;
 
1301
   ref->tail.second = j;
 
1302
   ref->head.matched = ref->tail.matched = true;
 
1303
   ref->null.first = ref->null.second = j;
 
1304
   ref->null.matched = false;
 
1305
}
 
1306
 
 
1307
template <class iterator, class Allocator>
 
1308
inline void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::init_fail(iterator i, iterator j)
 
1309
{
 
1310
   set_size(ref->cmatches, i, j);
 
1311
}
 
1312
 
 
1313
template <class iterator, class Allocator>
 
1314
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::maybe_assign(const match_results_base<iterator, Allocator>& m)
 
1315
{
 
1316
   sub_match<iterator>* p1, *p2;
 
1317
   p1 = (sub_match<iterator>*)(ref+1);
 
1318
   p2 = (sub_match<iterator>*)(m.ref+1);
 
1319
   iterator base = (*this)[-1].first;
 
1320
   std::size_t len1 = 0;
 
1321
   std::size_t len2 = 0;
 
1322
   std::size_t base1 = 0;
 
1323
   std::size_t base2 = 0;
 
1324
   std::size_t i;
 
1325
   for(i = 0; i < ref->cmatches; ++i)
 
1326
   {
 
1327
      //
 
1328
      // leftmost takes priority over longest:
 
1329
      base1 = boost::re_detail::distance(base, p1->first);
 
1330
      base2 = boost::re_detail::distance(base, p2->first);
 
1331
      if(base1 < base2) return;
 
1332
      if(base2 < base1) break;
 
1333
 
 
1334
      len1 = boost::re_detail::distance(p1->first, p1->second);
 
1335
      len2 = boost::re_detail::distance(p2->first, p2->second);
 
1336
      if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
 
1337
         break;
 
1338
      if((p1->matched == true) && (p2->matched == false))
 
1339
         return;
 
1340
      ++p1;
 
1341
      ++p2;
 
1342
   }
 
1343
   if(i == ref->cmatches)
 
1344
      return;
 
1345
   if(base2 < base1)
 
1346
      *this = m;
 
1347
   else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
 
1348
      *this = m;
 
1349
}
 
1350
 
 
1351
template <class iterator, class Allocator>
 
1352
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::cow()
 
1353
{
 
1354
   if(ref->count > 1)
 
1355
   {
 
1356
      c_reference* newref = (c_reference*)ref->allocate(sizeof(sub_match<iterator>) * ref->cmatches + sizeof(c_reference));
 
1357
      BOOST_REGEX_NOEH_ASSERT(newref)
 
1358
#ifndef BOOST_NO_EXCEPTIONS
 
1359
      try{
 
1360
#endif
 
1361
         new (newref) c_reference(*ref);
 
1362
         newref->count = 1;
 
1363
         sub_match<iterator>* p1 = (sub_match<iterator>*)(newref+1);
 
1364
         sub_match<iterator>* p2 = p1 + newref->cmatches;
 
1365
         sub_match<iterator>* p3 = (sub_match<iterator>*)(ref+1);
 
1366
#ifndef BOOST_NO_EXCEPTIONS
 
1367
         try{
 
1368
#endif
 
1369
            while(p1 != p2)
 
1370
            {
 
1371
               new (p1) sub_match<iterator>(*p3);
 
1372
               ++p1;
 
1373
               ++p3;
 
1374
            }
 
1375
#ifndef BOOST_NO_EXCEPTIONS
 
1376
         }
 
1377
         catch(...)
 
1378
         { 
 
1379
            p2 = (sub_match<iterator>*)(newref+1);
 
1380
            while(p2 != p1)
 
1381
            {
 
1382
               ::boost::re_detail::pointer_destroy(p2);
 
1383
               ++p2;
 
1384
            }
 
1385
            ::boost::re_detail::pointer_destroy(ref);
 
1386
            throw; 
 
1387
         }
 
1388
#endif
 
1389
      --(ref->count);
 
1390
      ref = newref;
 
1391
#ifndef BOOST_NO_EXCEPTIONS
 
1392
      }
 
1393
      catch(...)
 
1394
      { 
 
1395
         ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * ref->cmatches + sizeof(c_reference)); 
 
1396
         throw; 
 
1397
      }
 
1398
#endif
 
1399
   }
 
1400
}
 
1401
 
 
1402
} // namespace re_detail
 
1403
 
 
1404
//
 
1405
// class match_results
 
1406
// encapsulates match_results_base, does a deep copy rather than
 
1407
// reference counting to ensure thread safety when copying
 
1408
// other match_results instances
 
1409
 
 
1410
template <class iterator, class Allocator>
 
1411
class match_results : public re_detail::match_results_base<iterator, Allocator>
 
1412
{
 
1413
   typedef re_detail::match_results_base<iterator, Allocator> base_type;
 
1414
public:
 
1415
 
 
1416
   typedef typename base_type::alloc_type          alloc_type;
 
1417
   typedef typename base_type::size_type           size_type;
 
1418
   typedef typename base_type::char_type           char_type;
 
1419
   typedef typename base_type::value_type          value_type;
 
1420
   typedef typename base_type::difference_type     difference_type;
 
1421
   typedef typename base_type::iterator_type       iterator_type;
 
1422
 
 
1423
   explicit match_results(const Allocator& a = Allocator())
 
1424
      : re_detail::match_results_base<iterator, Allocator>(a){}
 
1425
 
 
1426
   match_results(const re_detail::match_results_base<iterator, Allocator>& m)
 
1427
      : re_detail::match_results_base<iterator, Allocator>(m){}
 
1428
 
 
1429
   match_results& operator=(const re_detail::match_results_base<iterator, Allocator>& m)
 
1430
   {
 
1431
      // shallow copy
 
1432
      base_type::operator=(m);
 
1433
      return *this;
 
1434
   }
 
1435
 
 
1436
   match_results(const match_results& m);
 
1437
   match_results& operator=(const match_results& m);
 
1438
   //
 
1439
   // the following function definitions should *not* be required, except
 
1440
   // when this class is used as a template inside another template definition,
 
1441
   // in which members of the base class are not visible to the calling code.
 
1442
   // As a workaround we define simple forwarding functions:
 
1443
   //
 
1444
   size_type size()const
 
1445
   { return static_cast<const base_type*>(this)->size(); }
 
1446
 
 
1447
   const sub_match<iterator>& operator[](int n) const
 
1448
   { return (*static_cast<const base_type*>(this))[n]; }
 
1449
 
 
1450
   Allocator allocator()const
 
1451
   { return static_cast<const base_type*>(this)->allocator(); }
 
1452
 
 
1453
   difference_type length(int sub = 0)const
 
1454
   { return static_cast<const base_type*>(this)->length(sub); }
 
1455
 
 
1456
   difference_type position(unsigned int sub = 0)const
 
1457
   { return static_cast<const base_type*>(this)->position(sub); }
 
1458
 
 
1459
   unsigned int line()const
 
1460
   { return static_cast<const base_type*>(this)->line(); }
 
1461
 
 
1462
   iterator line_start()const
 
1463
   { return static_cast<const base_type*>(this)->line_start(); }
 
1464
 
 
1465
   std::basic_string<char_type> str(int sub = 0)const
 
1466
   { return static_cast<const base_type*>(this)->str(sub); }
 
1467
 
 
1468
   void swap(match_results& that)
 
1469
   { static_cast<base_type*>(this)->swap(that); }
 
1470
 
 
1471
   bool operator==(const match_results& that)const
 
1472
   { return static_cast<const base_type&>(*this) == static_cast<const base_type&>(that); }
 
1473
 
 
1474
   bool operator<(const match_results& that) const
 
1475
   { return position() < that.position(); }
 
1476
};
 
1477
 
 
1478
template <class iterator, class Allocator>
 
1479
match_results<iterator, Allocator>::match_results(const match_results<iterator, Allocator>& m)
 
1480
   : re_detail::match_results_base<iterator, Allocator>(false)
 
1481
{
 
1482
   this->ref =
 
1483
      reinterpret_cast<typename re_detail::match_results_base<iterator, Allocator>::c_reference *>
 
1484
         (m.ref->allocate(sizeof(sub_match<iterator>) * m.ref->cmatches +
 
1485
                          sizeof(typename re_detail::match_results_base<iterator, Allocator>::c_reference)));
 
1486
   BOOST_REGEX_NOEH_ASSERT(this->ref)                       
 
1487
#ifndef BOOST_NO_EXCEPTIONS
 
1488
   try{
 
1489
#endif
 
1490
      new (this->ref) typename re_detail::match_results_base<iterator, Allocator>::c_reference(*m.ref);
 
1491
      this->ref->count = 1;
 
1492
      sub_match<iterator>* p1 = (sub_match<iterator>*)(this->ref+1);
 
1493
      sub_match<iterator>* p2 = p1 + this->ref->cmatches;
 
1494
      sub_match<iterator>* p3 = (sub_match<iterator>*)(m.ref+1);
 
1495
#ifndef BOOST_NO_EXCEPTIONS
 
1496
      try{
 
1497
#endif
 
1498
         while(p1 != p2)
 
1499
         {
 
1500
            new (p1) sub_match<iterator>(*p3);
 
1501
            ++p1;
 
1502
            ++p3;
 
1503
         }
 
1504
#ifndef BOOST_NO_EXCEPTIONS
 
1505
      }
 
1506
      catch(...)
 
1507
      { 
 
1508
         p2 = (sub_match<iterator>*)(this->ref+1);
 
1509
         while(p2 != p1)
 
1510
         {
 
1511
            re_detail::pointer_destroy(p2);
 
1512
            ++p2;
 
1513
         }
 
1514
         re_detail::pointer_destroy(this->ref);
 
1515
         throw; 
 
1516
      }
 
1517
   }
 
1518
   catch(...)
 
1519
   { 
 
1520
      m.ref->deallocate((char*)(void*)this->ref, sizeof(sub_match<iterator>) * m.ref->cmatches + sizeof(typename re_detail::match_results_base<iterator, Allocator>::c_reference));
 
1521
      throw; 
 
1522
   }
 
1523
#endif
 
1524
}
 
1525
 
 
1526
template <class iterator, class Allocator>
 
1527
match_results<iterator, Allocator>& match_results<iterator, Allocator>::operator=(const match_results<iterator, Allocator>& m)
 
1528
{
 
1529
   match_results<iterator, Allocator> t(m);
 
1530
   this->swap(t);
 
1531
   return *this;
 
1532
}
 
1533
 
 
1534
namespace re_detail{
 
1535
template <class iterator, class charT, class traits_type, class Allocator>
 
1536
iterator BOOST_REGEX_CALL re_is_set_member(iterator next, 
 
1537
                          iterator last, 
 
1538
                          const re_set_long* set_, 
 
1539
                          const reg_expression<charT, traits_type, Allocator>& e);
 
1540
} // namepsace re_detail
 
1541
 
 
1542
#ifdef __BORLANDC__
 
1543
  #pragma option pop
 
1544
#endif
 
1545
 
 
1546
} // namespace boost
 
1547
 
 
1548
#ifndef BOOST_REGEX_COMPILE_HPP
 
1549
#include <boost/regex/v3/regex_compile.hpp>
 
1550
#endif
 
1551
 
 
1552
//
 
1553
// template instances:
 
1554
//
 
1555
#define BOOST_REGEX_CHAR_T char
 
1556
#ifdef BOOST_REGEX_NARROW_INSTANTIATE
 
1557
#  define BOOST_REGEX_INSTANTIATE
 
1558
#endif
 
1559
#include <boost/regex/v3/instances.hpp>
 
1560
#undef BOOST_REGEX_CHAR_T
 
1561
#ifdef BOOST_REGEX_INSTANTIATE
 
1562
#  undef BOOST_REGEX_INSTANTIATE
 
1563
#endif
 
1564
 
 
1565
#ifndef BOOST_NO_WREGEX
 
1566
#define BOOST_REGEX_CHAR_T wchar_t
 
1567
#ifdef BOOST_REGEX_WIDE_INSTANTIATE
 
1568
#  define BOOST_REGEX_INSTANTIATE
 
1569
#endif
 
1570
#include <boost/regex/v3/instances.hpp>
 
1571
#undef BOOST_REGEX_CHAR_T
 
1572
#ifdef BOOST_REGEX_INSTANTIATE
 
1573
#  undef BOOST_REGEX_INSTANTIATE
 
1574
#endif
 
1575
#endif
 
1576
 
 
1577
 
 
1578
namespace boost{
 
1579
#ifdef BOOST_REGEX_NO_FWD
 
1580
typedef reg_expression<char, regex_traits<char>, BOOST_DEFAULT_ALLOCATOR(char)> regex;
 
1581
#ifndef BOOST_NO_WREGEX
 
1582
typedef reg_expression<wchar_t, regex_traits<wchar_t>, BOOST_DEFAULT_ALLOCATOR(wchar_t)> wregex;
 
1583
#endif
 
1584
#endif
 
1585
 
 
1586
typedef match_results<const char*> cmatch;
 
1587
typedef match_results<std::string::const_iterator> smatch;
 
1588
#ifndef BOOST_NO_WREGEX
 
1589
typedef match_results<const wchar_t*> wcmatch;
 
1590
typedef match_results<std::wstring::const_iterator> wsmatch;
 
1591
#endif
 
1592
 
 
1593
} // namespace boost
 
1594
#ifndef BOOST_REGEX_MATCH_HPP
 
1595
#include <boost/regex/v3/regex_match.hpp>
 
1596
#endif
 
1597
#ifndef BOOST_REGEX_FORMAT_HPP
 
1598
#include <boost/regex/v3/regex_format.hpp>
 
1599
#endif
 
1600
#ifndef BOOST_REGEX_SPLIT_HPP
 
1601
#include <boost/regex/v3/regex_split.hpp>
 
1602
#endif
 
1603
 
 
1604
#endif  // __cplusplus
 
1605
 
 
1606
#endif  // include
 
1607
 
 
1608
 
 
1609
 
 
1610
 
 
1611
 
 
1612
 
 
1613
 
 
1614
 
 
1615
 
 
1616
 
 
1617
 
 
1618
 
 
1619
 
 
1620
 
 
1621
 
 
1622
 
 
1623
 
 
1624
 
 
1625
 
 
1626
 
 
1627
 
 
1628
 
 
1629
 
 
1630
 
 
1631
 
 
1632
 
 
1633
 
 
1634
 
 
1635
 
 
1636