~ubuntu-branches/ubuntu/breezy/aqsis/breezy

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Will Newton
  • Date: 2004-12-07 20:06:49 UTC
  • Revision ID: james.westby@ubuntu.com-20041207200649-fccswkrvp4oc8lmn
Tags: upstream-0.9.3
ImportĀ upstreamĀ versionĀ 0.9.3

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_match.hpp
 
19
  *   VERSION      see <boost/version.hpp>
 
20
  *   DESCRIPTION: Regular expression matching algorithms.
 
21
  *                Note this is an internal header file included
 
22
  *                by regex.hpp, do not include on its own.
 
23
  */
 
24
 
 
25
 
 
26
#ifndef BOOST_REGEX_MATCH_HPP
 
27
#define BOOST_REGEX_MATCH_HPP
 
28
 
 
29
#ifndef BOOST_REGEX_MAX_STATE_COUNT
 
30
#  define BOOST_REGEX_MAX_STATE_COUNT 100000000
 
31
#endif
 
32
 
 
33
#include <boost/limits.hpp>
 
34
 
 
35
 
 
36
namespace boost{
 
37
   namespace re_detail{
 
38
 
 
39
#ifdef __BORLANDC__
 
40
   #pragma option push -a8 -b -Vx -Ve -pc  -w-8026 -w-8027
 
41
#endif
 
42
 
 
43
//
 
44
// Unfortunately Rogue Waves standard library appears to have a bug
 
45
// in std::basic_string::compare that results in eroneous answers
 
46
// in some cases (tested with Borland C++ 5.1, Rogue Wave lib version
 
47
// 0x020101) the test case was:
 
48
// {39135,0} < {0xff,0}
 
49
// which succeeds when it should not.
 
50
//
 
51
#ifndef _RWSTD_VER
 
52
# define STR_COMP(s,p) s.compare(p)
 
53
#else
 
54
template <class C, class T, class A>
 
55
inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
 
56
{ return s.compare(p); }
 
57
inline int string_compare(const std::string& s, const char* p)
 
58
{ return std::strcmp(s.c_str(), p); }
 
59
# ifndef BOOST_NO_WREGEX
 
60
inline int string_compare(const std::wstring& s, const wchar_t* p)
 
61
{ return std::wcscmp(s.c_str(), p); }
 
62
# endif
 
63
# define STR_COMP(s,p) string_compare(s,p)
 
64
#endif
 
65
 
 
66
template<class charT>
 
67
inline const charT* re_skip_past_null(const charT* p)
 
68
{
 
69
  while (*p != 0) ++p;
 
70
  return ++p;
 
71
}
 
72
 
 
73
template <class iterator, class charT, class traits_type, class Allocator>
 
74
iterator BOOST_REGEX_CALL re_is_set_member(iterator next, 
 
75
                          iterator last, 
 
76
                          const re_set_long* set_, 
 
77
                          const reg_expression<charT, traits_type, Allocator>& e)
 
78
{   
 
79
   const charT* p = reinterpret_cast<const charT*>(set_+1);
 
80
   iterator ptr;
 
81
   unsigned int i;
 
82
   bool icase = e.flags() & regbase::icase;
 
83
 
 
84
   if(next == last) return next;
 
85
 
 
86
   typedef typename traits_type::string_type traits_string_type;
 
87
   const traits_type& traits_inst = e.get_traits();
 
88
   
 
89
   // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
 
90
   // referenced
 
91
   (void)traits_inst;
 
92
 
 
93
   // try and match a single character, could be a multi-character
 
94
   // collating element...
 
95
   for(i = 0; i < set_->csingles; ++i)
 
96
   {
 
97
      ptr = next;
 
98
      if(*p == 0)
 
99
      {
 
100
         // treat null string as special case:
 
101
         if(traits_inst.translate(*ptr, icase) != *p)
 
102
         {
 
103
            while(*p == 0)++p;
 
104
            continue;
 
105
         }
 
106
         return set_->isnot ? next : (ptr == next) ? ++next : ptr;
 
107
      }
 
108
      else
 
109
      {
 
110
         while(*p && (ptr != last))
 
111
         {
 
112
            if(traits_inst.translate(*ptr, icase) != *p)
 
113
               break;
 
114
            ++p;
 
115
            ++ptr;
 
116
         }
 
117
 
 
118
         if(*p == 0) // if null we've matched
 
119
            return set_->isnot ? next : (ptr == next) ? ++next : ptr;
 
120
 
 
121
         p = re_skip_past_null(p);     // skip null
 
122
      }
 
123
   }
 
124
 
 
125
   charT col = traits_inst.translate(*next, icase);
 
126
 
 
127
 
 
128
   if(set_->cranges || set_->cequivalents)
 
129
   {
 
130
      traits_string_type s2(1, col);
 
131
      traits_string_type s1;
 
132
      //
 
133
      // try and match a range, NB only a single character can match
 
134
      if(set_->cranges)
 
135
      {
 
136
         if(e.flags() & regbase::nocollate)
 
137
            s1 = s2;
 
138
         else
 
139
            traits_inst.transform(s1, s2);
 
140
         for(i = 0; i < set_->cranges; ++i)
 
141
         {
 
142
            if(STR_COMP(s1, p) <= 0)
 
143
            {
 
144
               while(*p)++p;
 
145
               ++p;
 
146
               if(STR_COMP(s1, p) >= 0)
 
147
                  return set_->isnot ? next : ++next;
 
148
            }
 
149
            else
 
150
            {
 
151
               // skip first string
 
152
               while(*p)++p;
 
153
               ++p;
 
154
            }
 
155
            // skip second string
 
156
            while(*p)++p;
 
157
            ++p;
 
158
         }
 
159
      }
 
160
      //
 
161
      // try and match an equivalence class, NB only a single character can match
 
162
      if(set_->cequivalents)
 
163
      {
 
164
         traits_inst.transform_primary(s1, s2);
 
165
         for(i = 0; i < set_->cequivalents; ++i)
 
166
         {
 
167
            if(STR_COMP(s1, p) == 0)
 
168
               return set_->isnot ? next : ++next;
 
169
            // skip string
 
170
            while(*p)++p;
 
171
            ++p;
 
172
         }
 
173
      }
 
174
   }
 
175
   if(traits_inst.is_class(col, set_->cclasses) == true)
 
176
      return set_->isnot ? next : ++next;
 
177
   return set_->isnot ? ++next : next;
 
178
}
 
179
 
 
180
template <class iterator, class Allocator>
 
181
class _priv_match_data
 
182
{
 
183
public:
 
184
   typedef typename boost::detail::rebind_allocator<int, Allocator>::type i_alloc;
 
185
   typedef typename boost::detail::rebind_allocator<iterator, Allocator>::type it_alloc;
 
186
   typedef typename regex_iterator_traits<iterator>::difference_type difference_type;
 
187
 
 
188
   match_results_base<iterator, Allocator> temp_match;
 
189
   // failure stacks:
 
190
   jstack<match_results_base<iterator, Allocator>, Allocator> matches;
 
191
   jstack<iterator, Allocator> prev_pos;
 
192
   jstack<const re_syntax_base*, Allocator> prev_record;
 
193
   jstack<int, Allocator> prev_acc;
 
194
   int* accumulators;
 
195
   unsigned int caccumulators;
 
196
   difference_type state_count;
 
197
   difference_type max_state_count;
 
198
   iterator* loop_starts;
 
199
 
 
200
   _priv_match_data(const match_results_base<iterator, Allocator>&, iterator, iterator, std::size_t);
 
201
   
 
202
   ~_priv_match_data()
 
203
   {
 
204
      m_free();
 
205
   }
 
206
   void m_free();
 
207
   void set_accumulator_size(unsigned int size);
 
208
   int* get_accumulators()
 
209
   {
 
210
      return accumulators;
 
211
   }
 
212
   iterator* get_loop_starts()
 
213
   {
 
214
      return loop_starts;
 
215
   }
 
216
   void estimate_max_state_count(iterator a, iterator b, std::size_t states, std::random_access_iterator_tag*)
 
217
   {
 
218
#ifndef BOOST_NO_STD_DISTANCE
 
219
      difference_type dist = std::distance(a,b);
 
220
#else
 
221
      difference_type dist = b - a;
 
222
#endif
 
223
      states *= states;
 
224
      difference_type lim = std::numeric_limits<difference_type>::max() - 1000 - states;
 
225
      if(dist > (difference_type)(lim / states))
 
226
         max_state_count = lim;
 
227
      else
 
228
         max_state_count = 1000 + states * dist;
 
229
   }
 
230
   void estimate_max_state_count(iterator a, iterator b, std::size_t states, void*)
 
231
   {
 
232
      // we don't know how long the sequence is:
 
233
      max_state_count = BOOST_REGEX_MAX_STATE_COUNT;
 
234
   }
 
235
};
 
236
 
 
237
template <class iterator, class Allocator>
 
238
_priv_match_data<iterator, Allocator>::_priv_match_data(const match_results_base<iterator, Allocator>& m, iterator a, iterator b, std::size_t states)
 
239
  : temp_match(m), matches(64, m.allocator()), prev_pos(64, m.allocator()), prev_record(64, m.allocator())
 
240
{
 
241
  typedef typename regex_iterator_traits<iterator>::iterator_category category;
 
242
  
 
243
  accumulators = 0;
 
244
  caccumulators = 0;
 
245
  loop_starts = 0;
 
246
  state_count = 0;
 
247
  estimate_max_state_count(a, b, states, static_cast<category*>(0));
 
248
}
 
249
 
 
250
template <class iterator, class Allocator>
 
251
void _priv_match_data<iterator, Allocator>::set_accumulator_size(unsigned int size)
 
252
{
 
253
   if(size > caccumulators)
 
254
   {
 
255
      m_free();
 
256
      caccumulators = size;
 
257
      accumulators = i_alloc(temp_match.allocator()).allocate(caccumulators);
 
258
      BOOST_REGEX_NOEH_ASSERT(accumulators)
 
259
      loop_starts = it_alloc(temp_match.allocator()).allocate(caccumulators);
 
260
      BOOST_REGEX_NOEH_ASSERT(loop_starts)
 
261
      for(unsigned i = 0; i < caccumulators; ++i)
 
262
         new (loop_starts + i) iterator();
 
263
   }
 
264
}
 
265
 
 
266
template <class iterator, class Allocator>
 
267
void _priv_match_data<iterator, Allocator>::m_free()
 
268
{
 
269
   if(caccumulators)
 
270
   {
 
271
      i_alloc temp1(temp_match.allocator());
 
272
      temp1.deallocate(accumulators, caccumulators);
 
273
      for(unsigned i = 0; i < caccumulators; ++i)
 
274
         ::boost::re_detail::pointer_destroy(loop_starts + i);
 
275
      it_alloc temp2(temp_match.allocator());
 
276
      temp2.deallocate(loop_starts, caccumulators);
 
277
   }
 
278
}
 
279
 
 
280
template <class charT, class traits, class Allocator>
 
281
struct access_t : public reg_expression<charT, traits, Allocator>
 
282
{
 
283
   typedef typename is_byte<charT>::width_type width_type;
 
284
   typedef reg_expression<charT, traits, Allocator> base_type;
 
285
   typedef charT char_type;
 
286
   typedef traits traits_type;
 
287
   typedef Allocator alloc_type;
 
288
 
 
289
   static int repeat_count(const base_type& b) 
 
290
   { return base_type::repeat_count(b); }
 
291
   static unsigned int restart_type(const base_type& b) 
 
292
   { return base_type::restart_type(b); }
 
293
   static const re_syntax_base* first(const base_type& b)
 
294
   { return base_type::first(b); }
 
295
   static const unsigned char* get_map(const base_type& b)
 
296
   { return base_type::get_map(b); }
 
297
   static std::size_t leading_length(const base_type& b)
 
298
   { return base_type::leading_length(b); }
 
299
   static const kmp_info<charT>* get_kmp(const base_type& b)
 
300
   { return base_type::get_kmp(b); }
 
301
   static bool can_start(char_type c, const unsigned char* _map, unsigned char mask)
 
302
   {
 
303
      return reg_expression<char_type, traits_type, alloc_type>::can_start(c, _map, mask, width_type());
 
304
   }
 
305
};
 
306
 
 
307
 
 
308
#if defined(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE)
 
309
//
 
310
// Ugly ugly hack,
 
311
// template don't merge if they contain switch statements so declare these
 
312
// templates in unnamed namespace (ie with internal linkage), each translation
 
313
// unit then gets its own local copy, it works seemlessly but bloats the app.
 
314
namespace{
 
315
#endif
 
316
 
 
317
template <class iterator, class Allocator, class charT, class traits, class Allocator2>
 
318
bool query_match_aux(iterator first, 
 
319
                     iterator last, 
 
320
                     match_results<iterator, Allocator>& m, 
 
321
                     const reg_expression<charT, traits, Allocator2>& e, 
 
322
                     unsigned flags,
 
323
                     _priv_match_data<iterator, Allocator>& pd,
 
324
                     iterator* restart)
 
325
{
 
326
   typedef access_t<charT, traits, Allocator2> access;
 
327
 
 
328
   if(e.flags() & regbase::failbit)
 
329
      return false;
 
330
 
 
331
   typedef typename traits::size_type traits_size_type;
 
332
   typedef typename traits::uchar_type traits_uchar_type;
 
333
   typedef typename is_byte<charT>::width_type width_type;
 
334
   typedef typename re_detail::regex_iterator_traits<iterator>::difference_type difference_type;
 
335
 
 
336
   // declare some local aliases to reduce pointer loads
 
337
   // good optimising compilers should make this unnecessary!!
 
338
   jstack<match_results_base<iterator, Allocator>, Allocator>& matches = pd.matches;
 
339
   jstack<iterator, Allocator>& prev_pos = pd.prev_pos;
 
340
   jstack<const re_syntax_base*, Allocator>& prev_record = pd.prev_record;
 
341
   jstack<int, Allocator>& prev_acc = pd.prev_acc;
 
342
   match_results_base<iterator, Allocator>& temp_match = pd.temp_match;
 
343
   temp_match.set_first(first);
 
344
   difference_type& state_count = pd.state_count;
 
345
 
 
346
   const re_syntax_base* ptr = access::first(e);
 
347
   bool match_found = false;
 
348
   bool have_partial_match = false;
 
349
   bool unwind_stack = false;
 
350
   bool need_push_match = (e.mark_count() > 1);
 
351
   int cur_acc = -1;    // no active accumulator
 
352
   pd.set_accumulator_size(access::repeat_count(e));
 
353
   int* accumulators = pd.get_accumulators();
 
354
   iterator* start_loop = pd.get_loop_starts();
 
355
   int k; // for loops
 
356
   bool icase = e.flags() & regbase::icase;
 
357
   *restart = first;
 
358
   iterator base = first;
 
359
   const traits& traits_inst = e.get_traits();
 
360
   // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
 
361
   // referenced
 
362
   (void)traits_inst;
 
363
 
 
364
   // prepare m for failure:
 
365
   /*
 
366
   if((flags & match_init) == 0)
 
367
   {
 
368
      m.init_fail(first, last);
 
369
   } */
 
370
 
 
371
   retry:
 
372
 
 
373
   while(first != last)
 
374
   {
 
375
      jm_assert(ptr);
 
376
      ++state_count;
 
377
      switch(ptr->type)
 
378
      {
 
379
      case syntax_element_match:
 
380
         match_jump:
 
381
         {
 
382
            // match found, save then fallback in case we missed a
 
383
            // longer one.
 
384
            if((flags & match_not_null) && (first == temp_match[0].first))
 
385
               goto failure;
 
386
            if((flags & match_all) && (first != last))
 
387
               goto failure;
 
388
            temp_match.set_second(first);
 
389
            m.maybe_assign(temp_match);
 
390
            match_found = true;
 
391
            if(((flags & match_any) && ((first == last) || !(flags & match_all))) || ((first == last) && (need_push_match == false)))
 
392
            {
 
393
               // either we don't care what we match or we've matched
 
394
               // the whole string and can't match anything longer.
 
395
               while(matches.empty() == false)
 
396
                  matches.pop();
 
397
               while(prev_pos.empty() == false)
 
398
                  prev_pos.pop();
 
399
               while(prev_record.empty() == false)
 
400
                  prev_record.pop();
 
401
               while(prev_acc.empty() == false)
 
402
                  prev_acc.pop();
 
403
               return true;
 
404
            }
 
405
         }
 
406
         goto failure;
 
407
      case syntax_element_startmark:
 
408
         start_mark_jump:
 
409
         if(static_cast<const re_brace*>(ptr)->index > 0)
 
410
         {
 
411
            temp_match.set_first(first, static_cast<const re_brace*>(ptr)->index);
 
412
         }
 
413
         else if(
 
414
            (static_cast<const re_brace*>(ptr)->index == -1)
 
415
            || (static_cast<const re_brace*>(ptr)->index == -2)
 
416
         )
 
417
         {
 
418
           matches.push(temp_match);
 
419
            for(k = 0; k <= cur_acc; ++k)
 
420
               prev_pos.push(start_loop[k]);
 
421
            prev_pos.push(first);
 
422
            prev_record.push(ptr);
 
423
            for(k = 0; k <= cur_acc; ++k)
 
424
               prev_acc.push(accumulators[k]);
 
425
            prev_acc.push(cur_acc);
 
426
            prev_acc.push(match_found);
 
427
            match_found = false;
 
428
            // skip next jump and fall through:
 
429
            ptr = ptr->next.p;
 
430
         }
 
431
         ptr = ptr->next.p;
 
432
         break;
 
433
      case syntax_element_endmark:
 
434
         end_mark_jump:
 
435
         if(static_cast<const re_brace*>(ptr)->index > 0)
 
436
         {
 
437
            temp_match.set_second(first, static_cast<const re_brace*>(ptr)->index);
 
438
         }
 
439
         else if(
 
440
            (static_cast<const re_brace*>(ptr)->index == -1)
 
441
            || (static_cast<const re_brace*>(ptr)->index == -2)
 
442
         )
 
443
         {
 
444
            match_found = true;
 
445
            unwind_stack = true;
 
446
            goto failure;
 
447
         }
 
448
         ptr = ptr->next.p;
 
449
         break;
 
450
      case syntax_element_literal:
 
451
      {
 
452
         unsigned int len = static_cast<const re_literal*>(ptr)->length;
 
453
         const charT* what = reinterpret_cast<const charT*>(static_cast<const re_literal*>(ptr) + 1);
 
454
         //
 
455
         // compare string with what we stored in
 
456
         // our records:
 
457
         for(unsigned int i = 0; i < len; ++i, ++first)
 
458
         {
 
459
            if((first == last) || (traits_inst.translate(*first, icase) != what[i]))
 
460
               goto failure;
 
461
         }
 
462
         ptr = ptr->next.p;
 
463
         break;
 
464
      }
 
465
      case syntax_element_start_line:
 
466
         outer_line_check:
 
467
         if(first == temp_match[0].first)
 
468
         {
 
469
            // we're at the start of the buffer
 
470
            if(flags & match_prev_avail)
 
471
            {
 
472
               inner_line_check:
 
473
               // check the previous value even though its before
 
474
               // the start of our "buffer".
 
475
               iterator t(first);
 
476
               --t;
 
477
               if(traits::is_separator(*t) && !((*t == '\r') && (*first == '\n')) )
 
478
               {
 
479
                  ptr = ptr->next.p;
 
480
                  continue;
 
481
               }
 
482
               goto failure;
 
483
            }
 
484
            if((flags & match_not_bol) == 0)
 
485
            {
 
486
               ptr = ptr->next.p;
 
487
               continue;
 
488
            }
 
489
            goto failure;
 
490
         }
 
491
         // we're in the middle of the string
 
492
         goto inner_line_check;
 
493
      case syntax_element_end_line:
 
494
         // we're not yet at the end so *first is always valid:
 
495
         if(traits::is_separator(*first))
 
496
         {
 
497
            if((first != base) || (flags & match_prev_avail))
 
498
            {
 
499
               // check that we're not in the middle of \r\n sequence
 
500
               iterator t(first);
 
501
               --t;
 
502
               if((*t == '\r') && (*first == '\n'))
 
503
               {
 
504
                  goto failure;
 
505
               }
 
506
            }
 
507
            ptr = ptr->next.p;
 
508
            continue;
 
509
         }
 
510
         goto failure;
 
511
      case syntax_element_wild:
 
512
         // anything except possibly NULL or \n:
 
513
         if(traits::is_separator(*first))
 
514
         {
 
515
            if(flags & match_not_dot_newline)
 
516
               goto failure;
 
517
            ptr = ptr->next.p;
 
518
            ++first;
 
519
            continue;
 
520
         }
 
521
         if(*first == charT(0))
 
522
         {
 
523
            if(flags & match_not_dot_null)
 
524
               goto failure;
 
525
            ptr = ptr->next.p;
 
526
            ++first;
 
527
            continue;
 
528
         }
 
529
         ptr = ptr->next.p;
 
530
         ++first;
 
531
         break;
 
532
      case syntax_element_word_boundary:
 
533
      {
 
534
         // prev and this character must be opposites:
 
535
#if defined(BOOST_REGEX_USE_C_LOCALE) && defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
 
536
         bool b = traits::is_class(*first, traits::char_class_word);
 
537
#else
 
538
         bool b = traits_inst.is_class(*first, traits::char_class_word);
 
539
#endif
 
540
         if((first == temp_match[0].first)  && ((flags & match_prev_avail) == 0))
 
541
         {
 
542
            if(flags & match_not_bow)
 
543
               b ^= true;
 
544
            else
 
545
               b ^= false;
 
546
         }
 
547
         else
 
548
         {
 
549
            --first;
 
550
            b ^= traits_inst.is_class(*first, traits::char_class_word);
 
551
            ++first;
 
552
         }
 
553
         if(b)
 
554
         {
 
555
            ptr = ptr->next.p;
 
556
            continue;
 
557
         }
 
558
         goto failure;
 
559
      }
 
560
      case syntax_element_within_word:
 
561
         // both prev and this character must be traits::char_class_word:
 
562
         if(traits_inst.is_class(*first, traits::char_class_word))
 
563
         {
 
564
            bool b;
 
565
            if((first == temp_match[0].first) && ((flags & match_prev_avail) == 0))
 
566
               b = false;
 
567
            else
 
568
            {
 
569
               --first;
 
570
               b = traits_inst.is_class(*first, traits::char_class_word);
 
571
               ++first;
 
572
            }
 
573
            if(b)
 
574
            {
 
575
               ptr = ptr->next.p;
 
576
               continue;
 
577
            }
 
578
         }
 
579
         goto failure;
 
580
      case syntax_element_word_start:
 
581
         if((first == temp_match[0].first) && ((flags & match_prev_avail) == 0))
 
582
         {
 
583
            // start of buffer:
 
584
            if(flags & match_not_bow)
 
585
               goto failure;
 
586
            if(traits_inst.is_class(*first, traits::char_class_word))
 
587
            {
 
588
               ptr = ptr->next.p;
 
589
               continue;
 
590
            }
 
591
            goto failure;
 
592
         }
 
593
         // otherwise inside buffer:
 
594
         if(traits_inst.is_class(*first, traits::char_class_word))
 
595
         {
 
596
            iterator t(first);
 
597
            --t;
 
598
            if(traits_inst.is_class(*t, traits::char_class_word) == false)
 
599
            {
 
600
               ptr = ptr->next.p;
 
601
               continue;
 
602
            }
 
603
         }
 
604
         goto failure;      // if we fall through to here then we've failed
 
605
      case syntax_element_word_end:
 
606
         if((first == temp_match[0].first) && ((flags & match_prev_avail) == 0))
 
607
            goto failure;  // start of buffer can't be end of word
 
608
 
 
609
         // otherwise inside buffer:
 
610
         if(traits_inst.is_class(*first, traits::char_class_word) == false)
 
611
         {
 
612
            iterator t(first);
 
613
            --t;
 
614
            if(traits_inst.is_class(*t, traits::char_class_word))
 
615
            {
 
616
               ptr = ptr->next.p;
 
617
               continue;
 
618
            }
 
619
         }
 
620
         goto failure;      // if we fall through to here then we've failed
 
621
      case syntax_element_buffer_start:
 
622
         if((first != temp_match[0].first) || (flags & match_not_bob))
 
623
            goto failure;
 
624
         // OK match:
 
625
         ptr = ptr->next.p;
 
626
         break;
 
627
      case syntax_element_buffer_end:
 
628
         if((first != last) || (flags & match_not_eob))
 
629
            goto failure;
 
630
         // OK match:
 
631
         ptr = ptr->next.p;
 
632
         break;
 
633
      case syntax_element_backref:
 
634
      {
 
635
         // compare with what we previously matched:
 
636
         iterator i = temp_match[static_cast<const re_brace*>(ptr)->index].first;
 
637
         iterator j = temp_match[static_cast<const re_brace*>(ptr)->index].second;
 
638
         while(i != j)
 
639
         {
 
640
            if((first == last) || (traits_inst.translate(*first, icase) != traits_inst.translate(*i, icase)))
 
641
               goto failure;
 
642
            ++i;
 
643
            ++first;
 
644
         }
 
645
         ptr = ptr->next.p;
 
646
         break;
 
647
      }
 
648
      case syntax_element_long_set:
 
649
      {
 
650
         // let the traits class do the work:
 
651
         iterator t = re_is_set_member(first, last, static_cast<const re_set_long*>(ptr), e);
 
652
         if(t != first)
 
653
         {
 
654
            ptr = ptr->next.p;
 
655
            first = t;
 
656
            continue;
 
657
         }
 
658
         goto failure;
 
659
      }
 
660
      case syntax_element_set:
 
661
         // lookup character in table:
 
662
         if(static_cast<const re_set*>(ptr)->_map[(traits_uchar_type)traits_inst.translate(*first, icase)])
 
663
         {
 
664
            ptr = ptr->next.p;
 
665
            ++first;
 
666
            continue;
 
667
         }
 
668
         goto failure;
 
669
      case syntax_element_jump:
 
670
         ptr = static_cast<const re_jump*>(ptr)->alt.p;
 
671
         continue;
 
672
      case syntax_element_alt:
 
673
      {
 
674
         // alt_jump:
 
675
         if(access::can_start(*first, static_cast<const re_jump*>(ptr)->_map, (unsigned char)mask_take))
 
676
         {
 
677
            // we can take the first alternative,
 
678
            // see if we need to push next alternative:
 
679
            if(access::can_start(*first, static_cast<const re_jump*>(ptr)->_map, mask_skip))
 
680
            {
 
681
               if(need_push_match)
 
682
                  matches.push(temp_match);
 
683
               for(k = 0; k <= cur_acc; ++k)
 
684
                  prev_pos.push(start_loop[k]);
 
685
               prev_pos.push(first);
 
686
               prev_record.push(ptr);
 
687
               for(k = 0; k <= cur_acc; ++k)
 
688
                  prev_acc.push(accumulators[k]);
 
689
               prev_acc.push(cur_acc);
 
690
            }
 
691
            ptr = ptr->next.p;
 
692
            continue;
 
693
         }
 
694
         if(access::can_start(*first, static_cast<const re_jump*>(ptr)->_map, mask_skip))
 
695
         {
 
696
            ptr = static_cast<const re_jump*>(ptr)->alt.p;
 
697
            continue;
 
698
         }
 
699
         goto failure;  // neither option is possible
 
700
      }
 
701
      case syntax_element_rep:
 
702
      {
 
703
         // repeater_jump:
 
704
         // if we're moving to a higher id (nested repeats etc)
 
705
         // zero out our accumualtors:
 
706
         if(cur_acc < static_cast<const re_repeat*>(ptr)->id)
 
707
         {
 
708
            cur_acc = static_cast<const re_repeat*>(ptr)->id;
 
709
            accumulators[cur_acc] = 0;
 
710
            start_loop[cur_acc] = first;
 
711
         }
 
712
 
 
713
         cur_acc = static_cast<const re_repeat*>(ptr)->id;
 
714
 
 
715
         if(static_cast<const re_repeat*>(ptr)->leading)
 
716
            *restart = first;
 
717
 
 
718
         //charT c = traits_inst.translate(*first);
 
719
 
 
720
         // first of all test for special case where this is last element,
 
721
         // if that is the case then repeat as many times as possible,
 
722
         // as long as the repeat is greedy:
 
723
 
 
724
         if((static_cast<const re_repeat*>(ptr)->alt.p->type == syntax_element_match)
 
725
            && (static_cast<const re_repeat*>(ptr)->greedy == true))
 
726
         {
 
727
            // see if we can take the repeat:
 
728
            if(((unsigned int)accumulators[cur_acc] < static_cast<const re_repeat*>(ptr)->max)
 
729
                  && access::can_start(*first, static_cast<const re_repeat*>(ptr)->_map, mask_take))
 
730
            {
 
731
               // push terminating match as fallback:
 
732
               if((unsigned int)accumulators[cur_acc] >= static_cast<const re_repeat*>(ptr)->min)
 
733
               {
 
734
                  if((prev_record.empty() == false) && (prev_record.peek() == static_cast<const re_repeat*>(ptr)->alt.p))
 
735
                  {
 
736
                     // we already have the required fallback
 
737
                     // don't add any more, just update this one:
 
738
                     if(need_push_match)
 
739
                        matches.peek() = temp_match;
 
740
                     prev_pos.peek() = first;
 
741
                  }
 
742
                  else
 
743
                  {
 
744
                     if(need_push_match)
 
745
                        matches.push(temp_match);
 
746
                     prev_pos.push(first);
 
747
                     prev_record.push(static_cast<const re_repeat*>(ptr)->alt.p);
 
748
                  }
 
749
               }
 
750
               // move to next item in list:
 
751
               if((first != start_loop[cur_acc]) || !accumulators[cur_acc])
 
752
               {
 
753
                  ++accumulators[cur_acc];
 
754
                  ptr = ptr->next.p;
 
755
                  start_loop[cur_acc] = first;
 
756
                  continue;
 
757
               }
 
758
               else if((unsigned int)accumulators[cur_acc] < static_cast<const re_repeat*>(ptr)->min)
 
759
               {
 
760
                  // the repeat was null, and we haven't gone round min times yet,
 
761
                  // since all subsequent repeats will be null as well, just update
 
762
                  // our repeat count and skip out.
 
763
                  accumulators[cur_acc] = static_cast<const re_repeat*>(ptr)->min;
 
764
                  ptr = static_cast<const re_repeat*>(ptr)->alt.p;
 
765
                  continue;
 
766
               }
 
767
               goto failure;
 
768
            }
 
769
            // see if we can skip the repeat:
 
770
            if(((unsigned int)accumulators[cur_acc] >= static_cast<const re_repeat*>(ptr)->min)
 
771
               && access::can_start(*first, static_cast<const re_repeat*>(ptr)->_map, mask_skip))
 
772
            {
 
773
               ptr = static_cast<const re_repeat*>(ptr)->alt.p;
 
774
               continue;
 
775
            }
 
776
            // otherwise fail:
 
777
            goto failure;
 
778
         }
 
779
 
 
780
         // OK if we get to here then the repeat is either non-terminal or non-greedy,
 
781
         // see if we can skip the repeat:
 
782
         if(((unsigned int)accumulators[cur_acc] >= static_cast<const re_repeat*>(ptr)->min)
 
783
            && access::can_start(*first, static_cast<const re_repeat*>(ptr)->_map, mask_skip))
 
784
         {
 
785
            // see if we can push failure info:
 
786
            if(((unsigned int)accumulators[cur_acc] < static_cast<const re_repeat*>(ptr)->max)
 
787
               && access::can_start(*first, static_cast<const re_repeat*>(ptr)->_map, mask_take))
 
788
            {
 
789
               // check to see if the last loop matched a NULL string
 
790
               // if so then we really don't want to loop again:
 
791
               if(((unsigned int)accumulators[cur_acc] == static_cast<const re_repeat*>(ptr)->min)
 
792
                  || (first != start_loop[cur_acc]))
 
793
               {
 
794
                  if(need_push_match)
 
795
                     matches.push(temp_match);
 
796
                  prev_pos.push(first);
 
797
                  prev_record.push(ptr);
 
798
                  for(k = 0; k <= cur_acc; ++k)
 
799
                     prev_acc.push(accumulators[k]);
 
800
                  // for non-greedy repeats save whether we have a match already:
 
801
                  if(static_cast<const re_repeat*>(ptr)->greedy == false)
 
802
                  {
 
803
                     prev_acc.push(match_found);
 
804
                     match_found = false;
 
805
                  }
 
806
               }
 
807
            }
 
808
            ptr = static_cast<const re_repeat*>(ptr)->alt.p;
 
809
            continue;
 
810
         }
 
811
 
 
812
         // otherwise see if we can take the repeat:
 
813
         if(((unsigned int)accumulators[cur_acc] < static_cast<const re_repeat*>(ptr)->max)
 
814
               && access::can_start(*first, static_cast<const re_repeat*>(ptr)->_map, mask_take) &&
 
815
               ((first != start_loop[cur_acc]) || !accumulators[cur_acc]))
 
816
         {
 
817
            // move to next item in list:
 
818
            ++accumulators[cur_acc];
 
819
            ptr = ptr->next.p;
 
820
            start_loop[cur_acc] = first;
 
821
            continue;
 
822
         }
 
823
         else if((first == start_loop[cur_acc]) && accumulators[cur_acc] && ((unsigned int)accumulators[cur_acc] < static_cast<const re_repeat*>(ptr)->min))
 
824
         {
 
825
            // the repeat was null, and we haven't gone round min times yet,
 
826
            // since all subsequent repeats will be null as well, just update
 
827
            // our repeat count and skip out.
 
828
            accumulators[cur_acc] = static_cast<const re_repeat*>(ptr)->min;
 
829
            ptr = static_cast<const re_repeat*>(ptr)->alt.p;
 
830
            continue;
 
831
         }
 
832
 
 
833
         // if we get here then neither option is allowed so fail:
 
834
         goto failure;
 
835
 
 
836
      }
 
837
      case syntax_element_combining:
 
838
         if(traits_inst.is_combining(traits_inst.translate(*first, icase)))
 
839
            goto failure;
 
840
         ++first;
 
841
         while((first != last) && traits_inst.is_combining(traits_inst.translate(*first, icase)))++first;
 
842
         ptr = ptr->next.p;
 
843
         continue;
 
844
      case syntax_element_soft_buffer_end:
 
845
         {
 
846
            if(flags & match_not_eob)
 
847
               goto failure;
 
848
            iterator p(first);
 
849
            while((p != last) && traits_inst.is_separator(traits_inst.translate(*p, icase)))++p;
 
850
            if(p != last)
 
851
               goto failure;
 
852
            ptr = ptr->next.p;
 
853
            continue;
 
854
         }
 
855
      case syntax_element_restart_continue:
 
856
         if(first != temp_match[-1].first)
 
857
            goto failure;
 
858
         ptr = ptr->next.p;
 
859
         continue;
 
860
      default:
 
861
         jm_assert(0); // should never get to here!!
 
862
         return false;
 
863
      }
 
864
   }
 
865
 
 
866
   //
 
867
   // if we get to here then we've run out of characters to match against,
 
868
   // we could however still have non-character regex items left
 
869
   if((ptr->can_be_null == 0) && ((flags & match_partial) == 0))
 
870
      goto failure;
 
871
   while(true)
 
872
   {
 
873
      jm_assert(ptr);
 
874
      ++state_count;
 
875
      switch(ptr->type)
 
876
      {
 
877
      case syntax_element_match:
 
878
         goto match_jump;
 
879
      case syntax_element_startmark:
 
880
         goto start_mark_jump;
 
881
      case syntax_element_endmark:
 
882
         goto end_mark_jump;
 
883
      case syntax_element_start_line:
 
884
         goto outer_line_check;
 
885
      case syntax_element_end_line:
 
886
         // we're at the end so *first is never valid:
 
887
         if((flags & match_not_eol) == 0)
 
888
         {
 
889
            ptr = ptr->next.p;
 
890
            continue;
 
891
         }
 
892
         goto failure;
 
893
      case syntax_element_word_boundary:
 
894
      case syntax_element_word_end:
 
895
         if(((flags & match_not_eow) == 0) && (first != temp_match[0].first))
 
896
         {
 
897
            iterator t(first);
 
898
            --t;
 
899
            if(traits_inst.is_class(*t, traits::char_class_word))
 
900
            {
 
901
               ptr = ptr->next.p;
 
902
               continue;
 
903
            }
 
904
         }
 
905
         goto failure;
 
906
      case syntax_element_buffer_end:
 
907
      case syntax_element_soft_buffer_end:
 
908
         if(flags & match_not_eob)
 
909
            goto failure;
 
910
         // OK match:
 
911
         ptr = ptr->next.p;
 
912
         break;
 
913
      case syntax_element_jump:
 
914
         ptr = static_cast<const re_jump*>(ptr)->alt.p;
 
915
         continue;
 
916
      case syntax_element_alt:
 
917
         if(ptr->can_be_null & mask_take)
 
918
         {
 
919
            // we can test the first alternative,
 
920
            // see if we need to push next alternative:
 
921
            if(ptr->can_be_null & mask_skip)
 
922
            {
 
923
               if(need_push_match)
 
924
                  matches.push(temp_match);
 
925
               for(k = 0; k <= cur_acc; ++k)
 
926
                  prev_pos.push(start_loop[k]);
 
927
               prev_pos.push(first);
 
928
               prev_record.push(ptr);
 
929
               for(k = 0; k <= cur_acc; ++k)
 
930
                  prev_acc.push(accumulators[k]);
 
931
               prev_acc.push(cur_acc);
 
932
            }
 
933
            ptr = ptr->next.p;
 
934
            continue;
 
935
         }
 
936
         if(ptr->can_be_null & mask_skip)
 
937
         {
 
938
            ptr = static_cast<const re_jump*>(ptr)->alt.p;
 
939
            continue;
 
940
         }
 
941
         goto failure;  // neither option is possible
 
942
      case syntax_element_rep:
 
943
         // if we're moving to a higher id (nested repeats etc)
 
944
         // zero out our accumualtors:
 
945
         if(cur_acc < static_cast<const re_repeat*>(ptr)->id)
 
946
         {
 
947
            cur_acc = static_cast<const re_repeat*>(ptr)->id;
 
948
            accumulators[cur_acc] = 0;
 
949
            start_loop[cur_acc] = first;
 
950
         }
 
951
 
 
952
         cur_acc = static_cast<const re_repeat*>(ptr)->id;
 
953
 
 
954
         // see if we can skip the repeat:
 
955
         if(((unsigned int)accumulators[cur_acc] >= static_cast<const re_repeat*>(ptr)->min)
 
956
            && ((ptr->can_be_null & mask_skip) || (flags & match_partial)))
 
957
         {
 
958
            // don't push failure info, there's no point:
 
959
            ptr = static_cast<const re_repeat*>(ptr)->alt.p;
 
960
            continue;
 
961
         }
 
962
 
 
963
         // otherwise see if we can take the repeat:
 
964
         if(((unsigned int)accumulators[cur_acc] < static_cast<const re_repeat*>(ptr)->max)
 
965
               && (((ptr->can_be_null & (mask_take | mask_skip)) == (mask_take | mask_skip))) || (flags & match_partial))
 
966
         {
 
967
            // move to next item in list:
 
968
            ++accumulators[cur_acc];
 
969
            ptr = ptr->next.p;
 
970
            start_loop[cur_acc] = first;
 
971
            continue;
 
972
         }
 
973
 
 
974
         // if we get here then neither option is allowed so fail:
 
975
         goto failure;
 
976
      case syntax_element_restart_continue:
 
977
         if(first != temp_match[-1].first)
 
978
            goto failure;
 
979
         ptr = ptr->next.p;
 
980
         continue;
 
981
      case syntax_element_backref:
 
982
         if(temp_match[static_cast<const re_brace*>(ptr)->index].first
 
983
               != temp_match[static_cast<const re_brace*>(ptr)->index].second)
 
984
               goto failure;
 
985
         ptr = ptr->next.p;
 
986
         continue;
 
987
      default:
 
988
         goto failure;
 
989
      }
 
990
   }
 
991
 
 
992
   failure:
 
993
 
 
994
   //
 
995
   // check to see if we've been searching too many states:
 
996
   //
 
997
   if(state_count >= pd.max_state_count)
 
998
   {
 
999
#ifndef BOOST_NO_EXCEPTIONS
 
1000
      throw std::runtime_error("Max regex search depth exceeded.");
 
1001
#else
 
1002
      while(matches.empty() == false)
 
1003
         matches.pop();
 
1004
      while(prev_pos.empty() == false)
 
1005
         prev_pos.pop();
 
1006
      while(prev_record.empty() == false)
 
1007
         prev_record.pop();
 
1008
      while(prev_acc.empty() == false)
 
1009
         prev_acc.pop();
 
1010
      return false;
 
1011
#endif
 
1012
   }
 
1013
 
 
1014
   //
 
1015
   // check for possible partial match:
 
1016
   //
 
1017
   if((flags & match_partial)
 
1018
      && !match_found          // no full match already
 
1019
      && (base != first)       // some charcters have been consumed
 
1020
      && (first == last))      // end of input has been reached
 
1021
   {
 
1022
      have_partial_match = true;
 
1023
      temp_match.set_second(first, 0, false);
 
1024
      m.maybe_assign(temp_match);
 
1025
   }
 
1026
 
 
1027
   if(prev_record.empty() == false)
 
1028
   {
 
1029
      ptr = prev_record.peek();
 
1030
      switch(ptr->type)
 
1031
      {
 
1032
      case syntax_element_alt:
 
1033
         // get next alternative:
 
1034
         ptr = static_cast<const re_jump*>(ptr)->alt.p;
 
1035
         if(need_push_match)
 
1036
            matches.pop(temp_match);
 
1037
         prev_acc.pop(cur_acc);
 
1038
         for(k = cur_acc; k >= 0; --k)
 
1039
            prev_acc.pop(accumulators[k]);
 
1040
         prev_pos.pop(first);
 
1041
         for(k = cur_acc; k >= 0; --k)
 
1042
            prev_pos.pop(start_loop[k]);
 
1043
         prev_record.pop();
 
1044
         if(unwind_stack) goto failure; // unwinding forward assert
 
1045
         goto retry;
 
1046
      case syntax_element_rep:
 
1047
      {
 
1048
         // we're doing least number of repeats first,
 
1049
         // increment count and repeat again:
 
1050
         bool saved_matched = match_found;
 
1051
         if(need_push_match)
 
1052
            matches.pop(temp_match);
 
1053
         prev_pos.pop(first);
 
1054
         cur_acc = static_cast<const re_repeat*>(ptr)->id;
 
1055
         if(static_cast<const re_repeat*>(ptr)->greedy == false)
 
1056
         {
 
1057
            saved_matched = prev_acc.peek();
 
1058
            prev_acc.pop();
 
1059
         }
 
1060
         for(k = cur_acc; k >= 0; --k)
 
1061
            prev_acc.pop(accumulators[k]);
 
1062
         prev_record.pop();
 
1063
         if(unwind_stack) goto failure; // unwinding forward assert
 
1064
         if((unsigned int)++accumulators[cur_acc] > static_cast<const re_repeat*>(ptr)->max)
 
1065
            goto failure;  // repetions exhausted.
 
1066
         //
 
1067
         // if the repeat is non-greedy, and we found a match then fail again:
 
1068
         if((static_cast<const re_repeat*>(ptr)->greedy == false) && (match_found == true))
 
1069
         {
 
1070
            goto failure;
 
1071
         }
 
1072
         else if (match_found == false)
 
1073
            match_found = saved_matched;
 
1074
         ptr = ptr->next.p;
 
1075
         start_loop[cur_acc] = first;
 
1076
         goto retry;
 
1077
      }
 
1078
      case syntax_element_startmark:
 
1079
      {
 
1080
         bool saved_matched = match_found;
 
1081
         matches.pop(temp_match);
 
1082
         match_found = prev_acc.peek();
 
1083
         prev_acc.pop();
 
1084
         prev_acc.pop(cur_acc);
 
1085
         for(k = cur_acc; k >= 0; --k)
 
1086
            prev_acc.pop(accumulators[k]);
 
1087
         prev_pos.pop(first);
 
1088
         for(k = cur_acc; k >= 0; --k)
 
1089
            prev_pos.pop(start_loop[k]);
 
1090
         prev_record.pop();
 
1091
         unwind_stack = false;
 
1092
         if(static_cast<const re_brace*>(ptr)->index == -1)
 
1093
         {
 
1094
            if (saved_matched == false)
 
1095
               goto failure;
 
1096
            ptr = static_cast<const re_jump*>(ptr->next.p)->alt.p->next.p;
 
1097
            goto retry;
 
1098
         }
 
1099
         if(static_cast<const re_brace*>(ptr)->index == -2)
 
1100
         {
 
1101
            if (saved_matched == true)
 
1102
               goto failure;
 
1103
            ptr = static_cast<const re_jump*>(ptr->next.p)->alt.p->next.p;
 
1104
            goto retry;
 
1105
         }
 
1106
         else goto failure;
 
1107
      }
 
1108
      case syntax_element_match:
 
1109
         if(need_push_match)
 
1110
            matches.pop(temp_match);
 
1111
         prev_pos.pop(first);
 
1112
         prev_record.pop();
 
1113
         if(unwind_stack) goto failure; // unwinding forward assert
 
1114
         goto retry;
 
1115
     default:
 
1116
         jm_assert(0);
 
1117
         // mustn't get here!!
 
1118
      }
 
1119
   }
 
1120
 
 
1121
   if(match_found || have_partial_match)
 
1122
   {
 
1123
      pd.state_count = 0;
 
1124
      return true;
 
1125
   }
 
1126
 
 
1127
   // if we get to here then everything has failed
 
1128
   // and no match was found:
 
1129
   return false;
 
1130
}
 
1131
#if defined(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE)
 
1132
} // namespace
 
1133
#endif
 
1134
 
 
1135
 
 
1136
template <class iterator>
 
1137
void _skip_and_inc(unsigned int& clines, iterator& last_line, iterator& first, const iterator last)
 
1138
{
 
1139
   while(first != last)
 
1140
   {
 
1141
      if(*first == '\n')
 
1142
      {
 
1143
         last_line = ++first;
 
1144
         ++clines;
 
1145
      }
 
1146
      else
 
1147
         ++first;
 
1148
   }
 
1149
}
 
1150
 
 
1151
template <class iterator>
 
1152
void _skip_and_dec(unsigned int& clines, iterator& last_line, iterator& first, iterator base, std::size_t len)
 
1153
{
 
1154
   bool need_line = false;
 
1155
   for(std::size_t i = 0; i < len; ++i)
 
1156
   {
 
1157
      --first;
 
1158
      if(*first == '\n')
 
1159
      {
 
1160
         need_line = true;
 
1161
         --clines;
 
1162
      }
 
1163
   }
 
1164
 
 
1165
   if(need_line)
 
1166
   {
 
1167
      last_line = first;
 
1168
 
 
1169
      if(last_line != base)
 
1170
         --last_line;
 
1171
      else
 
1172
         return;
 
1173
 
 
1174
      while((last_line != base) && (*last_line != '\n'))
 
1175
         --last_line;
 
1176
      if(*last_line == '\n')
 
1177
         ++last_line;
 
1178
   }
 
1179
}
 
1180
 
 
1181
template <class iterator>
 
1182
inline void _inc_one(unsigned int& clines, iterator& last_line, iterator& first)
 
1183
{
 
1184
   if(*first == '\n')
 
1185
   {
 
1186
      last_line = ++first;
 
1187
      ++clines;
 
1188
   }
 
1189
   else
 
1190
      ++first;
 
1191
}
 
1192
 
 
1193
template <class iterator, class Allocator>
 
1194
struct grep_search_predicate
 
1195
{
 
1196
   match_results<iterator, Allocator>* pm;
 
1197
   grep_search_predicate(match_results<iterator, Allocator>* p) : pm(p) {}
 
1198
   bool operator()(const match_results<iterator, Allocator>& m) 
 
1199
   {
 
1200
      *pm = static_cast<const match_results_base<iterator, Allocator>&>(m);
 
1201
      return false;
 
1202
   }
 
1203
};
 
1204
 
 
1205
#if !defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
 
1206
 
 
1207
template <class iterator, class Allocator>
 
1208
inline const match_results_base<iterator, Allocator>& grep_out_type(const grep_search_predicate<iterator, Allocator>& o, const Allocator&)
 
1209
{
 
1210
   return *(o.pm);
 
1211
}
 
1212
 
 
1213
#endif
 
1214
 
 
1215
template <class T, class Allocator>
 
1216
inline const Allocator& grep_out_type(const T&, const Allocator& a)
 
1217
{
 
1218
   return a;
 
1219
}
 
1220
 
 
1221
#if defined(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE)
 
1222
//
 
1223
// Ugly ugly hack,
 
1224
// template don't merge if they contain switch statements so declare these
 
1225
// templates in unnamed namespace (ie with internal linkage), each translation
 
1226
// unit then gets its own local copy, it works seemlessly but bloats the app.
 
1227
namespace{
 
1228
#endif
 
1229
 
 
1230
//
 
1231
// reg_grep2:
 
1232
// find all non-overlapping matches within the sequence first last:
 
1233
//
 
1234
template <class Predicate, class I, class charT, class traits, class A, class A2>
 
1235
unsigned int reg_grep2(Predicate foo, I first, I last, const reg_expression<charT, traits, A>& e, unsigned flags, A2 a)
 
1236
{
 
1237
   typedef access_t<charT, traits, A> access;
 
1238
 
 
1239
   if(e.flags() & regbase::failbit)
 
1240
      return 0;
 
1241
 
 
1242
   typedef typename traits::size_type traits_size_type;
 
1243
   typedef typename traits::uchar_type traits_uchar_type;
 
1244
   typedef typename is_byte<charT>::width_type width_type;
 
1245
 
 
1246
   match_results<I, A2> m(grep_out_type(foo, a));
 
1247
   I restart;
 
1248
   m.set_size(e.mark_count(), first, last);
 
1249
   m.set_line(1, first);
 
1250
   m.set_base(first);
 
1251
 
 
1252
   unsigned int clines = 1;
 
1253
   unsigned int cmatches = 0;
 
1254
   I last_line = first;
 
1255
   I next_base;
 
1256
   I base = first;
 
1257
   bool need_init;
 
1258
   bool leading_match = false;
 
1259
   const traits& traits_inst = e.get_traits();
 
1260
   // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
 
1261
   // referenced
 
1262
   (void)traits_inst;
 
1263
 
 
1264
   flags |= match_init;
 
1265
 
 
1266
   _priv_match_data<I, A2> pd(m, first, last, e.size());
 
1267
 
 
1268
   const unsigned char* _map = access::get_map(e);
 
1269
   unsigned int type;
 
1270
 
 
1271
   if(first == last)
 
1272
   {
 
1273
      // special case, only test if can_be_null,
 
1274
      // don't dereference any pointers!!
 
1275
      if(access::first(e)->can_be_null)
 
1276
      {
 
1277
         if(query_match_aux(first, last, m, e, flags, pd, &restart))
 
1278
         {
 
1279
            foo(m);
 
1280
            ++cmatches;
 
1281
         }
 
1282
      }
 
1283
      return cmatches;
 
1284
   }
 
1285
 
 
1286
   // try one time whatever:
 
1287
   if( access::can_start(*first, _map, (unsigned char)mask_any) )
 
1288
   {
 
1289
      if(query_match_aux(first, last, m, e, flags, pd, &restart))
 
1290
      {
 
1291
         ++cmatches;
 
1292
         leading_match = true;
 
1293
         if(foo(m) == false)
 
1294
            return cmatches;
 
1295
         if(m[0].second == last)
 
1296
            return cmatches;
 
1297
         // update to end of what matched
 
1298
         // trying to match again with match_not_null set if this 
 
1299
         // is a null match...
 
1300
         need_init = true;
 
1301
         if(first == m[0].second)
 
1302
         {
 
1303
            next_base = m[0].second;
 
1304
            pd.temp_match.init_fail(next_base, last);
 
1305
            m.init_fail(next_base, last);
 
1306
            if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
 
1307
            {
 
1308
               ++cmatches;
 
1309
               if(foo(m) == false)
 
1310
                  return cmatches;
 
1311
            }
 
1312
            else
 
1313
            {
 
1314
               need_init = false;
 
1315
               leading_match = false;
 
1316
               for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
 
1317
                   {} // dwa 10/20/2000 - warning suppression for MWCW
 
1318
               if(restart != last)
 
1319
                  ++restart;
 
1320
               _skip_and_inc(clines, last_line, first, restart);
 
1321
            }
 
1322
         }
 
1323
         if(need_init)
 
1324
         {
 
1325
            _skip_and_inc(clines, last_line, first, m[0].second);
 
1326
            next_base = m[0].second;
 
1327
            pd.temp_match.init_fail(next_base, last);
 
1328
            m.init_fail(next_base, last);
 
1329
         }
 
1330
      }
 
1331
      else
 
1332
      {
 
1333
         for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
 
1334
             {} // dwa 10/20/2000 - warning suppression for MWCW
 
1335
         if(restart != last)
 
1336
            ++restart;
 
1337
         _skip_and_inc(clines, last_line, first, restart);
 
1338
      }
 
1339
   }
 
1340
   else
 
1341
      _inc_one(clines, last_line, first); 
 
1342
   flags |= match_prev_avail | match_not_bob;
 
1343
 
 
1344
   
 
1345
   // depending on what the first record is we may be able to
 
1346
   // optimise the search:
 
1347
   type = (flags & match_continuous) ? 
 
1348
      static_cast<unsigned int>(regbase::restart_continue) 
 
1349
         : static_cast<unsigned int>(access::restart_type(e));
 
1350
 
 
1351
   if(type == regbase::restart_buf)
 
1352
      return cmatches;
 
1353
 
 
1354
   switch(type)
 
1355
   {
 
1356
   case regbase::restart_lit: 
 
1357
   case regbase::restart_fixed_lit:
 
1358
   {
 
1359
      const kmp_info<charT>* info = access::get_kmp(e);
 
1360
      int len = info->len;
 
1361
      const charT* x = info->pstr;
 
1362
      int j = 0; 
 
1363
      bool icase = e.flags() & regbase::icase;
 
1364
      while (first != last) 
 
1365
      {
 
1366
         while((j > -1) && (x[j] != traits_inst.translate(*first, icase))) 
 
1367
            j = info->kmp_next[j];
 
1368
         _inc_one(clines, last_line, first);
 
1369
         ++j;
 
1370
         if(j >= len) 
 
1371
         {
 
1372
            if(type == regbase::restart_fixed_lit)
 
1373
            {
 
1374
               _skip_and_dec(clines, last_line, first, base, j);
 
1375
               restart = first;
 
1376
               std::advance(restart, len);
 
1377
               m.set_first(first);
 
1378
               m.set_second(restart);
 
1379
               m.set_line(clines, last_line);
 
1380
               ++cmatches;
 
1381
               if(foo(m) == false)
 
1382
                  return cmatches;
 
1383
               if(m[0].second == last)
 
1384
                  return cmatches;
 
1385
               _skip_and_inc(clines, last_line, first, restart);
 
1386
               next_base = m[0].second;
 
1387
               pd.temp_match.init_fail(next_base, last);
 
1388
               m.init_fail(next_base, last);
 
1389
               j = 0;
 
1390
            }
 
1391
            else
 
1392
            {
 
1393
               restart = first;
 
1394
               _skip_and_dec(clines, last_line, first, base, j);
 
1395
               if(query_match_aux(first, last, m, e, flags, pd, &restart))
 
1396
               {
 
1397
 
 
1398
                  m.set_line(clines, last_line);
 
1399
                  ++cmatches;
 
1400
                  if(foo(m) == false)
 
1401
                     return cmatches;
 
1402
                  if(m[0].second == last)
 
1403
                     return cmatches;
 
1404
                  // update to end of what matched
 
1405
                 _skip_and_inc(clines, last_line, first, m[0].second);
 
1406
                  next_base = m[0].second;
 
1407
                  pd.temp_match.init_fail(next_base, last);
 
1408
                  m.init_fail(next_base, last);
 
1409
                  j = 0;
 
1410
               }
 
1411
               else
 
1412
               {
 
1413
                  for(int k = 0; (restart != first) && (k < j); ++k, --restart)
 
1414
                      {} // dwa 10/20/2000 - warning suppression for MWCW
 
1415
                  if(restart != last)
 
1416
                     ++restart;
 
1417
                  _skip_and_inc(clines, last_line, first, restart);
 
1418
                  j = 0;  //we could do better than this...
 
1419
               }
 
1420
            }
 
1421
         }
 
1422
      }
 
1423
      break;
 
1424
   }
 
1425
   case regbase::restart_any:
 
1426
   {
 
1427
      while(first != last)
 
1428
      {
 
1429
         if( access::can_start(*first, _map, (unsigned char)mask_any) )
 
1430
         {
 
1431
            if(query_match_aux(first, last, m, e, flags, pd, &restart))
 
1432
            {
 
1433
 
 
1434
               m.set_line(clines, last_line);
 
1435
               ++cmatches;
 
1436
               if(foo(m) == false)
 
1437
                  return cmatches;
 
1438
               if(m[0].second == last)
 
1439
                  return cmatches;
 
1440
               // update to end of what matched
 
1441
               // trying to match again with match_not_null set if this 
 
1442
               // is a null match...
 
1443
               need_init = true;
 
1444
               if(first == m[0].second)
 
1445
               {
 
1446
                  next_base = m[0].second;
 
1447
                  pd.temp_match.init_fail(next_base, last);
 
1448
                  m.init_fail(next_base, last);
 
1449
                  if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
 
1450
                  {
 
1451
                     m.set_line(clines, last_line);
 
1452
                     ++cmatches;
 
1453
                     if(foo(m) == false)
 
1454
                        return cmatches;
 
1455
                  }
 
1456
                  else
 
1457
                  {
 
1458
                     need_init = false;
 
1459
                     for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
 
1460
                         {} // dwa 10/20/2000 - warning suppression for MWCW
 
1461
                     if(restart != last)
 
1462
                        ++restart;
 
1463
                     _skip_and_inc(clines, last_line, first, restart);
 
1464
                  }
 
1465
               }
 
1466
               if(need_init)
 
1467
               {
 
1468
                 _skip_and_inc(clines, last_line, first, m[0].second);
 
1469
                  next_base = m[0].second;
 
1470
                  pd.temp_match.init_fail(next_base, last);
 
1471
                  m.init_fail(next_base, last);
 
1472
               }
 
1473
               continue;
 
1474
            }
 
1475
            else
 
1476
            {
 
1477
               for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
 
1478
                   {} // dwa 10/20/2000 - warning suppression for MWCW
 
1479
               if(restart != last)
 
1480
                  ++restart;
 
1481
               _skip_and_inc(clines, last_line, first, restart);
 
1482
            }
 
1483
         }
 
1484
         else
 
1485
            _inc_one(clines, last_line, first);
 
1486
      }
 
1487
   }
 
1488
   break;
 
1489
   case regbase::restart_word:
 
1490
   {
 
1491
      // do search optimised for word starts:
 
1492
      while(first != last)
 
1493
      {
 
1494
         --first;
 
1495
         if(*first == '\n')
 
1496
            --clines;
 
1497
         // skip the word characters:
 
1498
         while((first != last) && traits_inst.is_class(*first, traits::char_class_word))
 
1499
            ++first;
 
1500
         // now skip the white space:
 
1501
         while((first != last) && (traits_inst.is_class(*first, traits::char_class_word) == false))
 
1502
         {
 
1503
         #ifdef __GNUC__
 
1504
            //
 
1505
            // hack to work around gcc optimisation bug
 
1506
            // just expand the contents of _inc_one here:
 
1507
            if(*first == '\n')
 
1508
            {
 
1509
               last_line = ++first;
 
1510
               ++clines;
 
1511
            }
 
1512
            else
 
1513
               ++first;
 
1514
         #else         
 
1515
            _inc_one(clines, last_line, first); 
 
1516
         #endif
 
1517
         }
 
1518
         if(first == last)
 
1519
            break;
 
1520
 
 
1521
         if( access::can_start(*first, _map, (unsigned char)mask_any) )
 
1522
         {
 
1523
            if(query_match_aux(first, last, m, e, flags, pd, &restart))
 
1524
            {
 
1525
               m.set_line(clines, last_line);
 
1526
               ++cmatches;
 
1527
               if(foo(m) == false)
 
1528
                  return cmatches;
 
1529
               if(m[0].second == last)
 
1530
                  return cmatches;
 
1531
               // update to end of what matched
 
1532
               // trying to match again with match_not_null set if this
 
1533
               // is a null match...
 
1534
               need_init = true;
 
1535
               if(first == m[0].second)
 
1536
               {
 
1537
                  next_base = m[0].second;
 
1538
                  pd.temp_match.init_fail(next_base, last);
 
1539
                  m.init_fail(next_base, last);
 
1540
                  if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
 
1541
                  {
 
1542
                     m.set_line(clines, last_line);
 
1543
                     ++cmatches;
 
1544
                     if(foo(m) == false)
 
1545
                        return cmatches;
 
1546
                  }
 
1547
                  else
 
1548
                  {
 
1549
                     need_init = false;
 
1550
                     for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
 
1551
                         {} // dwa 10/20/2000 - warning suppression for MWCW
 
1552
                     if(restart != last)
 
1553
                        ++restart;
 
1554
                     _skip_and_inc(clines, last_line, first, restart);
 
1555
                  }
 
1556
               }
 
1557
               if(need_init)
 
1558
               {
 
1559
                  _skip_and_inc(clines, last_line, first, m[0].second);
 
1560
                  next_base = m[0].second;
 
1561
                  pd.temp_match.init_fail(next_base, last);
 
1562
                  m.init_fail(next_base, last);
 
1563
               }
 
1564
            }
 
1565
            else
 
1566
            {
 
1567
               for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
 
1568
                   {} // dwa 10/20/2000 - warning suppression for MWCW
 
1569
               if(restart != last)
 
1570
                  ++restart;
 
1571
               _skip_and_inc(clines, last_line, first, restart);
 
1572
            }
 
1573
         }
 
1574
         else
 
1575
            _inc_one(clines, last_line, first);
 
1576
      }
 
1577
   }
 
1578
   break;
 
1579
   case regbase::restart_line:
 
1580
   {
 
1581
      // do search optimised for line starts:
 
1582
      while(first != last)
 
1583
      {
 
1584
         // find first charcter after a line break:
 
1585
         --first;
 
1586
         if(*first == '\n')
 
1587
            --clines;
 
1588
         while((first != last) && (*first != '\n'))
 
1589
            ++first;
 
1590
         if(first == last)
 
1591
            break;
 
1592
         ++first;
 
1593
         if(first == last)
 
1594
            break;
 
1595
 
 
1596
         ++clines;
 
1597
         last_line = first;
 
1598
 
 
1599
         if( access::can_start(*first, _map, (unsigned char)mask_any) )
 
1600
         {
 
1601
            if(query_match_aux(first, last, m, e, flags, pd, &restart))
 
1602
            {
 
1603
               m.set_line(clines, last_line);
 
1604
               ++cmatches;
 
1605
               if(foo(m) == false)
 
1606
                  return cmatches;
 
1607
               if(m[0].second == last)
 
1608
                  return cmatches;
 
1609
               // update to end of what matched
 
1610
               // trying to match again with match_not_null set if this
 
1611
               // is a null match...
 
1612
               need_init = true;
 
1613
               if(first == m[0].second)
 
1614
               {
 
1615
                  next_base = m[0].second;
 
1616
                  pd.temp_match.init_fail(next_base, last);
 
1617
                  m.init_fail(next_base, last);
 
1618
                  if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
 
1619
                  {
 
1620
                     m.set_line(clines, last_line);
 
1621
                     ++cmatches;
 
1622
                     if(foo(m) == false)
 
1623
                        return cmatches;
 
1624
                  }
 
1625
                  else
 
1626
                  {
 
1627
                     need_init = false;
 
1628
                     for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
 
1629
                         {} // dwa 10/20/2000 - warning suppression for MWCW
 
1630
                     if(restart != last)
 
1631
                        ++restart;
 
1632
                     _skip_and_inc(clines, last_line, first, restart);
 
1633
                  }
 
1634
               }
 
1635
               if(need_init)
 
1636
               {
 
1637
                  _skip_and_inc(clines, last_line, first, m[0].second);
 
1638
                  next_base = m[0].second;
 
1639
                  pd.temp_match.init_fail(next_base, last);
 
1640
                  m.init_fail(next_base, last);
 
1641
               }
 
1642
            }
 
1643
            else
 
1644
            {
 
1645
               for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
 
1646
                   {} // dwa 10/20/2000 - warning suppression for MWCW
 
1647
               if(restart != last)
 
1648
                  ++restart;
 
1649
               _skip_and_inc(clines, last_line, first, restart);
 
1650
            }
 
1651
         }
 
1652
         else
 
1653
            _inc_one(clines, last_line, first);
 
1654
      }
 
1655
   }
 
1656
   break;
 
1657
   case regbase::restart_continue:
 
1658
   {
 
1659
      if(!leading_match)
 
1660
         return cmatches;
 
1661
      while(first != last)
 
1662
      {
 
1663
         if( access::can_start(*first, _map, (unsigned char)mask_any) )
 
1664
         {
 
1665
            if(query_match_aux(first, last, m, e, flags, pd, &restart))
 
1666
            {
 
1667
               m.set_line(clines, last_line);
 
1668
               ++cmatches;
 
1669
               if(foo(m) == false)
 
1670
                  return cmatches;
 
1671
               if(m[0].second == last)
 
1672
                  return cmatches;
 
1673
               // update to end of what matched
 
1674
               // trying to match again with match_not_null set if this
 
1675
               // is a null match...
 
1676
               if(first == m[0].second)
 
1677
               {
 
1678
                  next_base = m[0].second;
 
1679
                  pd.temp_match.init_fail(next_base, last);
 
1680
                  m.init_fail(next_base, last);
 
1681
                  if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
 
1682
                  {
 
1683
                     m.set_line(clines, last_line);
 
1684
                     ++cmatches;
 
1685
                     if(foo(m) == false)
 
1686
                        return cmatches;
 
1687
                  }
 
1688
                  else
 
1689
                     return cmatches;  // can't continue from null match
 
1690
               }
 
1691
               _skip_and_inc(clines, last_line, first, m[0].second);
 
1692
               next_base = m[0].second;
 
1693
               pd.temp_match.init_fail(next_base, last);
 
1694
               m.init_fail(next_base, last);
 
1695
               continue;
 
1696
            }
 
1697
         }
 
1698
         return cmatches;
 
1699
      }
 
1700
   }
 
1701
   break;
 
1702
   }
 
1703
 
 
1704
 
 
1705
   // finally check trailing null string:
 
1706
   if(access::first(e)->can_be_null)
 
1707
   {
 
1708
      if(query_match_aux(first, last, m, e, flags, pd, &restart))
 
1709
      {
 
1710
         m.set_line(clines, last_line);
 
1711
         ++cmatches;
 
1712
         if(foo(m) == false)
 
1713
            return cmatches;
 
1714
      }
 
1715
   }
 
1716
 
 
1717
   return cmatches;
 
1718
}
 
1719
#if defined(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE)
 
1720
} // namespace {anon}
 
1721
#endif
 
1722
 
 
1723
} // namespace re_detail
 
1724
 
 
1725
//
 
1726
// proc regex_match
 
1727
// returns true if the specified regular expression matches
 
1728
// the whole of the input.  Fills in what matched in m.
 
1729
//
 
1730
template <class iterator, class Allocator, class charT, class traits, class Allocator2>
 
1731
bool regex_match(iterator first, iterator last, match_results<iterator, Allocator>& m, const reg_expression<charT, traits, Allocator2>& e, unsigned flags = match_default)
 
1732
{
 
1733
   // prepare m for failure:
 
1734
   if((flags & match_init) == 0)
 
1735
   {
 
1736
      m.set_size(e.mark_count(), first, last);
 
1737
      m.set_base(first);
 
1738
      m.set_line(1, first);
 
1739
   }
 
1740
   flags |= match_all; // must match all of input.
 
1741
   re_detail::_priv_match_data<iterator, Allocator> pd(m, first, last, e.size());
 
1742
   iterator restart;
 
1743
   bool result = re_detail::query_match_aux(first, last, m, e, flags, pd, &restart);
 
1744
   return result;
 
1745
}
 
1746
template <class iterator, class charT, class traits, class Allocator2>
 
1747
bool regex_match(iterator first, iterator last, const reg_expression<charT, traits, Allocator2>& e, unsigned flags = match_default)
 
1748
{
 
1749
   match_results<iterator> m;
 
1750
   return regex_match(first, last, m, e, flags);
 
1751
}
 
1752
//
 
1753
// query_match convenience interfaces:
 
1754
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
 
1755
//
 
1756
// this isn't really a partial specialisation, but template function
 
1757
// overloading - if the compiler doesn't support partial specialisation
 
1758
// then it really won't support this either:
 
1759
template <class charT, class Allocator, class traits, class Allocator2>
 
1760
inline bool regex_match(const charT* str, 
 
1761
                        match_results<const charT*, Allocator>& m, 
 
1762
                        const reg_expression<charT, traits, Allocator2>& e, 
 
1763
                        unsigned flags = match_default)
 
1764
{
 
1765
   return regex_match(str, str + traits::length(str), m, e, flags);
 
1766
}
 
1767
 
 
1768
template <class ST, class SA, class Allocator, class charT, class traits, class Allocator2>
 
1769
inline bool regex_match(const std::basic_string<charT, ST, SA>& s, 
 
1770
                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, 
 
1771
                 const reg_expression<charT, traits, Allocator2>& e, 
 
1772
                 unsigned flags = match_default)
 
1773
{
 
1774
   return regex_match(s.begin(), s.end(), m, e, flags);
 
1775
}
 
1776
template <class charT, class traits, class Allocator2>
 
1777
inline bool regex_match(const charT* str, 
 
1778
                        const reg_expression<charT, traits, Allocator2>& e, 
 
1779
                        unsigned flags = match_default)
 
1780
{
 
1781
   match_results<const charT*> m;
 
1782
   return regex_match(str, str + traits::length(str), m, e, flags);
 
1783
}
 
1784
 
 
1785
template <class ST, class SA, class charT, class traits, class Allocator2>
 
1786
inline bool regex_match(const std::basic_string<charT, ST, SA>& s, 
 
1787
                 const reg_expression<charT, traits, Allocator2>& e, 
 
1788
                 unsigned flags = match_default)
 
1789
{
 
1790
   typedef typename std::basic_string<charT, ST, SA>::const_iterator iterator;
 
1791
   match_results<iterator> m;
 
1792
   return regex_match(s.begin(), s.end(), m, e, flags);
 
1793
}
 
1794
#else  // partial ordering
 
1795
inline bool regex_match(const char* str, 
 
1796
                        cmatch& m, 
 
1797
                        const regex& e, 
 
1798
                        unsigned flags = match_default)
 
1799
{
 
1800
   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
 
1801
}
 
1802
inline bool regex_match(const char* str, 
 
1803
                        const regex& e, 
 
1804
                        unsigned flags = match_default)
 
1805
{
 
1806
   match_results<const char*> m;
 
1807
   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
 
1808
}
 
1809
#ifndef BOOST_NO_WREGEX
 
1810
inline bool regex_match(const wchar_t* str, 
 
1811
                        wcmatch& m, 
 
1812
                        const wregex& e, 
 
1813
                        unsigned flags = match_default)
 
1814
{
 
1815
   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
 
1816
}
 
1817
inline bool regex_match(const wchar_t* str, 
 
1818
                        const wregex& e, 
 
1819
                        unsigned flags = match_default)
 
1820
{
 
1821
   match_results<const wchar_t*> m;
 
1822
   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
 
1823
}
 
1824
#endif
 
1825
inline bool regex_match(const std::string& s, 
 
1826
                        match_results<std::string::const_iterator, regex::allocator_type>& m,
 
1827
                        const regex& e, 
 
1828
                        unsigned flags = match_default)
 
1829
{
 
1830
   return regex_match(s.begin(), s.end(), m, e, flags);
 
1831
}
 
1832
inline bool regex_match(const std::string& s, 
 
1833
                        const regex& e, 
 
1834
                        unsigned flags = match_default)
 
1835
{
 
1836
   match_results<std::string::const_iterator, regex::allocator_type> m;
 
1837
   return regex_match(s.begin(), s.end(), m, e, flags);
 
1838
}
 
1839
#if !defined(BOOST_NO_WREGEX)
 
1840
inline bool regex_match(const std::basic_string<wchar_t>& s, 
 
1841
                        match_results<std::basic_string<wchar_t>::const_iterator, wregex::allocator_type>& m,
 
1842
                        const wregex& e, 
 
1843
                        unsigned flags = match_default)
 
1844
{
 
1845
   return regex_match(s.begin(), s.end(), m, e, flags);
 
1846
}
 
1847
inline bool regex_match(const std::basic_string<wchar_t>& s, 
 
1848
                        const wregex& e, 
 
1849
                        unsigned flags = match_default)
 
1850
{
 
1851
   match_results<std::basic_string<wchar_t>::const_iterator, wregex::allocator_type> m;
 
1852
   return regex_match(s.begin(), s.end(), m, e, flags);
 
1853
}
 
1854
#endif
 
1855
 
 
1856
#endif
 
1857
 
 
1858
template <class iterator, class Allocator, class charT, class traits, class Allocator2>
 
1859
bool regex_search(iterator first, iterator last, match_results<iterator, Allocator>& m, const reg_expression<charT, traits, Allocator2>& e, unsigned flags = match_default)
 
1860
{
 
1861
   if(e.flags() & regbase::failbit)
 
1862
      return false;
 
1863
 
 
1864
   typedef typename traits::size_type traits_size_type;
 
1865
   typedef typename traits::uchar_type traits_uchar_type;
 
1866
 
 
1867
   return re_detail::reg_grep2(re_detail::grep_search_predicate<iterator, Allocator>(&m), first, last, e, flags, m.allocator());
 
1868
}
 
1869
 
 
1870
//
 
1871
// regex_search convenience interfaces:
 
1872
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
 
1873
//
 
1874
// this isn't really a partial specialisation, but template function
 
1875
// overloading - if the compiler doesn't support partial specialisation
 
1876
// then it really won't support this either:
 
1877
template <class charT, class Allocator, class traits, class Allocator2>
 
1878
inline bool regex_search(const charT* str, 
 
1879
                        match_results<const charT*, Allocator>& m, 
 
1880
                        const reg_expression<charT, traits, Allocator2>& e, 
 
1881
                        unsigned flags = match_default)
 
1882
{
 
1883
   return regex_search(str, str + traits::length(str), m, e, flags);
 
1884
}
 
1885
 
 
1886
template <class ST, class SA, class Allocator, class charT, class traits, class Allocator2>
 
1887
inline bool regex_search(const std::basic_string<charT, ST, SA>& s, 
 
1888
                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, 
 
1889
                 const reg_expression<charT, traits, Allocator2>& e, 
 
1890
                 unsigned flags = match_default)
 
1891
{
 
1892
   return regex_search(s.begin(), s.end(), m, e, flags);
 
1893
}
 
1894
#else  // partial specialisation
 
1895
inline bool regex_search(const char* str, 
 
1896
                        cmatch& m, 
 
1897
                        const regex& e, 
 
1898
                        unsigned flags = match_default)
 
1899
{
 
1900
   return regex_search(str, str + regex::traits_type::length(str), m, e, flags);
 
1901
}
 
1902
#ifndef BOOST_NO_WREGEX
 
1903
inline bool regex_search(const wchar_t* str, 
 
1904
                        wcmatch& m, 
 
1905
                        const wregex& e, 
 
1906
                        unsigned flags = match_default)
 
1907
{
 
1908
   return regex_search(str, str + wregex::traits_type::length(str), m, e, flags);
 
1909
}
 
1910
#endif
 
1911
inline bool regex_search(const std::string& s, 
 
1912
                        match_results<std::string::const_iterator, regex::allocator_type>& m,
 
1913
                        const regex& e, 
 
1914
                        unsigned flags = match_default)
 
1915
{
 
1916
   return regex_search(s.begin(), s.end(), m, e, flags);
 
1917
}
 
1918
#if !defined(BOOST_NO_WREGEX)
 
1919
inline bool regex_search(const std::basic_string<wchar_t>& s, 
 
1920
                        match_results<std::basic_string<wchar_t>::const_iterator, wregex::allocator_type>& m,
 
1921
                        const wregex& e, 
 
1922
                        unsigned flags = match_default)
 
1923
{
 
1924
   return regex_search(s.begin(), s.end(), m, e, flags);
 
1925
}
 
1926
#endif
 
1927
 
 
1928
#endif
 
1929
 
 
1930
 
 
1931
//
 
1932
// regex_grep:
 
1933
// find all non-overlapping matches within the sequence first last:
 
1934
//
 
1935
template <class Predicate, class iterator, class charT, class traits, class Allocator>
 
1936
inline unsigned int regex_grep(Predicate foo, iterator first, iterator last, const reg_expression<charT, traits, Allocator>& e, unsigned flags = match_default)
 
1937
{
 
1938
   return re_detail::reg_grep2(foo, first, last, e, flags, e.allocator());
 
1939
}
 
1940
 
 
1941
//
 
1942
// regex_grep convenience interfaces:
 
1943
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
 
1944
//
 
1945
// this isn't really a partial specialisation, but template function
 
1946
// overloading - if the compiler doesn't support partial specialisation
 
1947
// then it really won't support this either:
 
1948
template <class Predicate, class charT, class Allocator, class traits>
 
1949
inline unsigned int regex_grep(Predicate foo, const charT* str, 
 
1950
                        const reg_expression<charT, traits, Allocator>& e, 
 
1951
                        unsigned flags = match_default)
 
1952
{
 
1953
   return regex_grep(foo, str, str + traits::length(str), e, flags);
 
1954
}
 
1955
 
 
1956
template <class Predicate, class ST, class SA, class Allocator, class charT, class traits>
 
1957
inline unsigned int regex_grep(Predicate foo, const std::basic_string<charT, ST, SA>& s, 
 
1958
                 const reg_expression<charT, traits, Allocator>& e, 
 
1959
                 unsigned flags = match_default)
 
1960
{
 
1961
   return regex_grep(foo, s.begin(), s.end(), e, flags);
 
1962
}
 
1963
#else  // partial specialisation
 
1964
inline unsigned int regex_grep(bool (*foo)(const cmatch&), const char* str, 
 
1965
                        const regex& e, 
 
1966
                        unsigned flags = match_default)
 
1967
{
 
1968
   return regex_grep(foo, str, str + regex::traits_type::length(str), e, flags);
 
1969
}
 
1970
#ifndef BOOST_NO_WREGEX
 
1971
inline unsigned int regex_grep(bool (*foo)(const wcmatch&), const wchar_t* str, 
 
1972
                        const wregex& e, 
 
1973
                        unsigned flags = match_default)
 
1974
{
 
1975
   return regex_grep(foo, str, str + wregex::traits_type::length(str), e, flags);
 
1976
}
 
1977
#endif
 
1978
inline unsigned int regex_grep(bool (*foo)(const match_results<std::string::const_iterator, regex::allocator_type>&), const std::string& s,
 
1979
                        const regex& e, 
 
1980
                        unsigned flags = match_default)
 
1981
{
 
1982
   return regex_grep(foo, s.begin(), s.end(), e, flags);
 
1983
}
 
1984
#if !defined(BOOST_NO_WREGEX)
 
1985
inline unsigned int regex_grep(bool (*foo)(const match_results<std::basic_string<wchar_t>::const_iterator, wregex::allocator_type>&), 
 
1986
                     const std::basic_string<wchar_t>& s, 
 
1987
                        const wregex& e, 
 
1988
                        unsigned flags = match_default)
 
1989
{
 
1990
   return regex_grep(foo, s.begin(), s.end(), e, flags);
 
1991
}
 
1992
#endif
 
1993
 
 
1994
#endif
 
1995
 
 
1996
 
 
1997
#ifdef __BORLANDC__
 
1998
  #pragma option pop
 
1999
#endif
 
2000
 
 
2001
} // namespace boost
 
2002
 
 
2003
#endif   // BOOST_REGEX_MATCH_HPP
 
2004
 
 
2005
 
 
2006
 
 
2007
 
 
2008
 
 
2009
 
 
2010
 
 
2011
 
 
2012
 
 
2013
 
 
2014
 
 
2015
 
 
2016
 
 
2017
 
 
2018
 
 
2019
 
 
2020