3
* Copyright (c) 1998-2002
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.
17
* LOCATION: see http://www.boost.org for most recent version.
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.
26
/* start with C compatibility API */
28
#ifndef BOOST_RE_REGEX_HPP_INCLUDED
29
#define BOOST_RE_REGEX_HPP_INCLUDED
31
#ifndef BOOST_RE_CREGEX_HPP
32
#include <boost/cregex.hpp>
37
// what follows is all C++ don't include in C builds!!
39
#ifdef BOOST_REGEX_DEBUG
45
#ifndef BOOST_REGEX_CONFIG_HPP
46
#include <boost/regex/config.hpp>
48
#ifndef BOOST_REGEX_FWD_HPP
49
#include <boost/regex_fwd.hpp>
51
#ifndef BOOST_REGEX_STACK_HPP
52
#include <boost/regex/v3/regex_stack.hpp>
54
#ifndef BOOST_REGEX_RAW_BUFFER_HPP
55
#include <boost/regex/v3/regex_raw_buffer.hpp>
57
#ifndef BOOST_REGEX_KMP_HPP
58
#include <boost/regex/v3/regex_kmp.hpp>
60
#ifndef BOOST_RE_PAT_EXCEPT_HPP
61
#include <boost/regex/pattern_except.hpp>
63
#ifndef BOOST_REGEX_TRAITS_HPP
64
#include <boost/regex/regex_traits.hpp>
66
#include <boost/type_traits/remove_cv.hpp>
67
#include <boost/scoped_array.hpp>
73
#pragma option push -a8 -b -Vx -Ve -pc -w-8027
79
struct re_syntax_base;
81
} // namespace re_detail
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> {};
91
class char_regex_traits_i<char> : public regex_traits<char>
94
typedef char char_type;
95
typedef unsigned char uchar_type;
96
typedef unsigned int size_type;
97
typedef regex_traits<char> base_type;
99
char BOOST_REGEX_CALL translate(char c, bool)const
101
return static_cast<const regex_traits<char>*>(this)->translate(c, true);
105
#ifndef BOOST_NO_WREGEX
107
class char_regex_traits_i<wchar_t> : public regex_traits<wchar_t>
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;
115
wchar_t BOOST_REGEX_CALL translate(wchar_t c, bool)const
117
return static_cast<const regex_traits<wchar_t>*>(this)->translate(c, true);
119
boost::uint_fast32_t BOOST_REGEX_CALL lookup_classname(const wchar_t* first, const wchar_t* last)const
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;
128
} // namespace deprecated
137
mask_any = mask_skip | mask_take,
141
struct _narrow_type{};
144
template <class charT>
151
typedef _narrow_type width_type;
155
class is_byte<unsigned char>
158
typedef _narrow_type width_type;
162
class is_byte<signed char>
165
typedef _narrow_type width_type;
168
template <class charT>
172
typedef _wide_type width_type;
177
// compiled structures
179
// the following defs describe the format of the compiled string
183
// enum syntax_element_type
184
// describes the type of a record
185
enum syntax_element_type
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
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);
223
// struct re_syntax_base
224
// base class for all syntax types:
225
struct re_syntax_base
227
syntax_element_type type;
229
unsigned int can_be_null;
234
// marks start or end of (...)
235
struct re_brace : public re_syntax_base
242
// marks a literal string and
243
// is followed by an array of charT[length]:
244
struct re_literal : public re_syntax_base
250
// struct re_long_set
251
// provides data for sets [...] containing
253
struct re_set_long : public re_syntax_base
255
unsigned int csingles, cranges, cequivalents;
256
boost::uint_fast32_t cclasses;
262
// provides a map of bools for sets containing
263
// narrow, single byte characters.
264
struct re_set : public re_syntax_base
266
unsigned char _map[256];
271
// provides alternative next destination
272
struct re_jump : public re_syntax_base
275
unsigned char _map[256];
280
// provides repeat expressions
281
struct re_repeat : public re_jump
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
297
enum re_jump_size_type
299
re_jump_size = (sizeof(re_jump) + padding_mask) & ~(padding_mask),
300
re_repeater_size = (sizeof(re_repeat) + padding_mask) & ~(padding_mask)
303
} // namespace re_detail
307
// handles error codes and flags
309
class BOOST_REGEX_DECL regbase
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 \|
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
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,
341
typedef unsigned int flag_type;
349
restart_continue = 4,
351
restart_fixed_lit = 6
354
flag_type BOOST_REGEX_CALL flags()const
360
regbase(const regbase& b);
366
// some forward declarations:
368
template <class iterator, class Allocator>
369
class _priv_match_data;
371
#if defined(BOOST_NO_STD_ITERATOR_TRAITS) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
374
struct regex_iterator_traits
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;
383
typedef std::ptrdiff_t difference_type;
384
typedef value_type* pointer;
385
typedef value_type& reference;
390
struct pointer_iterator_traits
392
typedef std::ptrdiff_t difference_type;
393
typedef T value_type;
395
typedef T& reference;
396
typedef std::random_access_iterator_tag iterator_category;
399
struct const_pointer_iterator_traits
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;
409
struct regex_iterator_traits<char*> : pointer_iterator_traits<char>{};
411
struct regex_iterator_traits<const char*> : const_pointer_iterator_traits<char>{};
413
struct regex_iterator_traits<wchar_t*> : pointer_iterator_traits<wchar_t>{};
415
struct regex_iterator_traits<const wchar_t*> : const_pointer_iterator_traits<wchar_t>{};
417
#if defined(__SGI_STL_PORT) && defined(__STL_DEBUG)
419
struct regex_iterator_traits<std::string::iterator> : pointer_iterator_traits<char>{};
421
struct regex_iterator_traits<std::string::const_iterator> : const_pointer_iterator_traits<char>{};
422
#ifndef BOOST_NO_STD_WSTRING
424
struct regex_iterator_traits<std::wstring::iterator> : pointer_iterator_traits<wchar_t>{};
426
struct regex_iterator_traits<std::wstring::const_iterator> : const_pointer_iterator_traits<wchar_t>{};
427
#endif // BOOST_NO_WSTRING
433
struct regex_iterator_traits : public std::iterator_traits<T> {};
438
struct def_alloc_param_traits
440
typedef typename regex_iterator_traits<I>::value_type const_value_type;
441
typedef typename remove_cv<const_value_type>::type type;
444
struct def_alloc_param_traits<const char*>
449
struct def_alloc_param_traits<const wchar_t*>
451
typedef wchar_t type;
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) >
460
BOOST_DEFAULT_ALLOCATOR(re_detail::def_alloc_param_traits<iterator>::type) >
465
// class reg_expression
466
// represents the compiled
467
// regular expression:
471
#pragma warning(push)
472
#pragma warning(disable : 4251 4231 4660)
475
#ifdef BOOST_REGEX_NO_FWD
476
template <class charT, class traits = regex_traits<charT>, class Allocator = BOOST_DEFAULT_ALLOCATOR(charT) >
478
template <class charT, class traits, class Allocator >
480
class reg_expression : public regbase
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;
487
typedef charT char_type;
488
typedef traits traits_type;
491
// placeholder for actual locale type used by the
492
// traits class to localise *this.
493
typedef typename traits::locale_type locale_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;
503
typedef typename Allocator::difference_type difference_type;
505
typedef typename Allocator::size_type size_type;
507
typedef Allocator allocator_type;
508
typedef Allocator alloc_type;
510
typedef regbase::flag_type flag_type;
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&);
519
reg_expression& BOOST_REGEX_CALL operator=(const reg_expression&);
520
reg_expression& BOOST_REGEX_CALL operator=(const charT* ptr)
522
set_expression(ptr, regbase::normal | regbase::use_except);
528
reg_expression& assign(const reg_expression& that)
529
{ return *this = that; }
530
reg_expression& assign(const charT* ptr, flag_type f = regbase::normal)
532
set_expression(ptr, f | regbase::use_except);
536
reg_expression& assign(const charT* first,
538
flag_type f = regbase::normal)
540
set_expression(first, last, f | regbase::use_except);
543
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !(defined(__IBMCPP__) && (__IBMCPP__ <= 502))
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); }
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); }
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)
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);
563
template <class ST, class SA>
564
reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
566
set_expression(p.c_str(), p.c_str() + p.size(), regbase::normal | regbase::use_except);
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)
575
set_expression(s.c_str(), s.c_str() + s.size(), f | regbase::use_except);
579
template <class fwd_iterator>
580
reg_expression& BOOST_REGEX_CALL assign(fwd_iterator first,
582
flag_type f = regbase::normal)
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);
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); }
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); }
597
reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
599
set_expression(p.c_str(), p.c_str() + p.size(), regbase::normal | regbase::use_except);
603
reg_expression& BOOST_REGEX_CALL assign(
604
const std::basic_string<charT>& s,
605
flag_type f = regbase::normal)
607
set_expression(s.c_str(), s.c_str() + s.size(), f | regbase::use_except);
616
Allocator BOOST_REGEX_CALL get_allocator()const;
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(); }
623
flag_type BOOST_REGEX_CALL getflags()const
627
std::basic_string<charT> BOOST_REGEX_CALL str()const
629
std::basic_string<charT> result;
630
if(this->error_code() == 0)
631
result = std::basic_string<charT>(_expression, _expression_len);
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); }
642
void BOOST_REGEX_CALL swap(reg_expression&)throw();
645
size_type BOOST_REGEX_CALL size()const
646
{ return (this->error_code() ? 0 : _expression_len); }
649
size_type BOOST_REGEX_CALL max_size()const
653
bool BOOST_REGEX_CALL empty()const
654
{ return 0 != this->error_code(); }
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;
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); }
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
675
traits_type traits_inst;
676
re_detail::raw_storage<Allocator> data;
677
unsigned _restart_type;
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_;
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);
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);
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)
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&);
728
#pragma warning (pop)
731
template <class charT, class traits, class Allocator>
732
inline void BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::swap(reg_expression& that)throw()
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);
744
// class match_results and match_results_base
745
// handles what matched where
747
template <class iterator>
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;
754
typedef typename re_detail::regex_iterator_traits<iterator>::difference_type difference_type;
756
typedef iterator iterator_type;
762
operator std::basic_string<value_type> ()const
764
std::basic_string<value_type> result;
765
std::size_t len = boost::re_detail::distance((iterator)first, (iterator)second);
770
result.append(1, *i);
775
#ifdef BOOST_OLD_REGEX_H
777
// the following are deprecated, do not use!!
780
operator unsigned int()const;
781
operator short()const
783
return (short)(int)(*this);
785
operator unsigned short()const
787
return (unsigned short)(unsigned int)(*this);
790
sub_match() { matched = false; }
791
sub_match(iterator i) : first(i), second(i), matched(false) {}
793
bool operator==(const sub_match& that)const
795
return (first == that.first) && (second == that.second) && (matched == that.matched);
797
bool BOOST_REGEX_CALL operator !=(const sub_match& that)const
798
{ return !(*this == that); }
800
difference_type BOOST_REGEX_CALL length()const
802
difference_type n = boost::re_detail::distance((iterator)first, (iterator)second);
807
#ifdef BOOST_OLD_REGEX_H
809
template <class iterator, class charT>
810
int do_toi(iterator i, iterator j, char c, int radix)
814
int result = std::strtol(s.c_str(), &p, radix);
815
#ifndef BOOST_NO_EXCEPTIONS
816
if(*p)throw bad_pattern("Bad sub-expression");
818
BOOST_REGEX_NOEH_ASSERT(0 == *p)
824
template <class I, class charT>
825
int do_toi(I& i, I j, charT c)
828
while((i != j) && (isdigit(*i)))
830
result = result*10 + (*i - '0');
838
template <class iterator>
839
sub_match<iterator>::operator int()const
843
#ifndef BOOST_NO_EXCEPTIONS
844
if(i == j)throw bad_pattern("Bad sub-expression");
846
BOOST_REGEX_NOEH_ASSERT(i != j)
848
if((i != j) && (*i == '-'))
853
neg *= re_detail::do_toi(i, j, *i);
854
#ifndef BOOST_NO_EXCEPTIONS
855
if(i != j)throw bad_pattern("Bad sub-expression");
857
BOOST_REGEX_NOEH_ASSERT(i == j)
860
template <class iterator>
861
sub_match<iterator>::operator unsigned int()const
865
#ifndef BOOST_NO_EXCEPTIONS
867
throw bad_pattern("Bad sub-expression");
869
BOOST_REGEX_NOEH_ASSERT(i != j)
870
return re_detail::do_toi(i, j, *first);
876
template <class iterator, class Allocator = BOOST_DEFAULT_ALLOCATOR(typename def_alloc_param_traits<iterator>::type) >
877
class match_results_base
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;
887
typedef std::ptrdiff_t difference_type;
888
typedef typename re_detail::regex_iterator_traits<iterator>::value_type char_type;
890
typedef sub_match<iterator> value_type;
891
typedef iterator iterator_type;
894
typedef typename boost::detail::rebind_allocator<char, Allocator>::type c_alloc;
896
struct c_reference : public c_alloc
898
std::size_t cmatches;
900
sub_match<iterator> head, tail, null;
902
iterator line_pos, base;
903
c_reference(const Allocator& a)
904
: c_alloc(a), cmatches(0), count(0), lines(0) { }
906
bool operator==(const c_reference& that)const
908
return (cmatches == that.cmatches) &&
909
(count == that.count) &&
910
(head == that.head) &&
911
(tail == that.tail) &&
912
(lines == that.lines) &&
915
bool operator!=(const c_reference& that)const
916
{ return !(*this == that); }
921
void BOOST_REGEX_CALL cow();
923
// protected contructor for derived class...
924
match_results_base(bool){}
925
void BOOST_REGEX_CALL m_free();
929
match_results_base(const Allocator& a = Allocator());
931
match_results_base(const match_results_base& m)
937
match_results_base& BOOST_REGEX_CALL operator=(const match_results_base& m);
939
~match_results_base()
944
size_type BOOST_REGEX_CALL size()const
946
//return (*this)[0].matched ? ref->cmatches : 0;
947
return ref->cmatches;
950
const sub_match<iterator>& BOOST_REGEX_CALL operator[](int n) const
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;
957
Allocator BOOST_REGEX_CALL allocator()const;
959
difference_type BOOST_REGEX_CALL length(unsigned int sub = 0)const
961
jm_assert(ref->cmatches);
962
const sub_match<iterator>& m = (*this)[sub];
963
if(m.matched == false)
965
difference_type n = boost::re_detail::distance((iterator)m.first, (iterator)m.second);
969
std::basic_string<char_type> str(int i)const
971
return static_cast<std::basic_string<char_type> >((*this)[i]);
974
unsigned int BOOST_REGEX_CALL line()const
979
difference_type BOOST_REGEX_CALL position(unsigned int sub = 0)const
981
jm_assert(ref->cmatches);
982
const sub_match<iterator>& s = (*this)[sub];
983
if(s.matched == false)
985
difference_type n = boost::re_detail::distance((iterator)(ref->base), (iterator)(s.first));
989
iterator BOOST_REGEX_CALL line_start()const
991
return ref->line_pos;
994
void swap(match_results_base& that)
996
c_reference* t = that.ref;
1001
bool operator==(const match_results_base& that)const;
1002
bool operator<(const match_results_base& that)const
1003
{ return position() < that.position(); }
1005
friend class match_results<iterator, Allocator>;
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);
1012
void BOOST_REGEX_CALL set_first(iterator i);
1013
void BOOST_REGEX_CALL set_first(iterator i, std::size_t pos);
1015
void BOOST_REGEX_CALL set_second(iterator i)
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;
1024
void BOOST_REGEX_CALL set_second(iterator i, std::size_t pos, bool m = true)
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;
1031
ref->tail.first = i;
1032
ref->tail.matched = (ref->tail.first == ref->tail.second) ? false : true;
1036
void BOOST_REGEX_CALL set_line(unsigned int i, iterator pos)
1039
ref->line_pos = pos;
1042
void BOOST_REGEX_CALL set_base(iterator pos)
1048
template <class iterator, class Allocator>
1049
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_first(iterator i)
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;
1057
p1->matched = false;
1061
p1->matched = false;
1062
p1->first = ref->tail.second;
1063
p1->second = ref->tail.second;
1068
template <class iterator, class Allocator>
1069
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_first(iterator i, std::size_t pos)
1072
((sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>) * pos))->first = i;
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;
1080
p1->matched = false;
1084
p1->matched = false;
1085
p1->first = ref->tail.second;
1086
p1->second = ref->tail.second;
1093
template <class iterator, class Allocator>
1094
match_results_base<iterator, Allocator>::match_results_base(const Allocator& a)
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
1102
new (ref) c_reference(a);
1105
// construct the sub_match<iterator>:
1106
#ifndef BOOST_NO_EXCEPTIONS
1110
new ((sub_match<iterator>*)(ref+1)) sub_match<iterator>();
1111
#ifndef BOOST_NO_EXCEPTIONS
1115
::boost::re_detail::pointer_destroy(ref);
1121
c_alloc(a).deallocate((char*)(void*)ref, sizeof(sub_match<iterator>) + sizeof(c_reference));
1127
template <class iterator, class Allocator>
1128
Allocator BOOST_REGEX_CALL match_results_base<iterator, Allocator>::allocator()const
1130
return *((c_alloc*)ref);
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)
1146
template <class iterator, class Allocator>
1147
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::m_free()
1149
if(--(ref->count) == 0)
1152
sub_match<iterator>* p1, *p2;
1153
p1 = (sub_match<iterator>*)(ref+1);
1154
p2 = p1 + ref->cmatches;
1157
::boost::re_detail::pointer_destroy(p1);
1160
::boost::re_detail::pointer_destroy(ref);
1161
a.deallocate((char*)(void*)ref, sizeof(sub_match<iterator>) * ref->cmatches + sizeof(c_reference));
1165
template <class iterator, class Allocator>
1166
bool match_results_base<iterator, Allocator>::operator==(const match_results_base<iterator, Allocator>& that)const
1168
if(*ref != *(that.ref))
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);
1183
template <class iterator, class Allocator>
1184
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_size(size_type n)
1186
if(ref->cmatches != n)
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
1194
new (newref) c_reference(*ref);
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
1206
new (p1) sub_match<iterator>();
1210
#ifndef BOOST_NO_EXCEPTIONS
1214
p2 = (sub_match<iterator>*)(newref+1);
1217
::boost::re_detail::pointer_destroy(p2);
1220
::boost::re_detail::pointer_destroy(ref);
1225
#ifndef BOOST_NO_EXCEPTIONS
1229
ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * n + sizeof(c_reference));
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)
1239
if(ref->cmatches != n)
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
1246
new (newref) c_reference(*ref);
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
1257
new (p1) sub_match<iterator>(j);
1261
#ifndef BOOST_NO_EXCEPTIONS
1265
p2 = (sub_match<iterator>*)(newref+1);
1268
::boost::re_detail::pointer_destroy(p2);
1271
::boost::re_detail::pointer_destroy(ref);
1276
#ifndef BOOST_NO_EXCEPTIONS
1280
ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * n + sizeof(c_reference));
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;
1296
p1->matched = false;
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;
1307
template <class iterator, class Allocator>
1308
inline void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::init_fail(iterator i, iterator j)
1310
set_size(ref->cmatches, i, j);
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)
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;
1325
for(i = 0; i < ref->cmatches; ++i)
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;
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)))
1338
if((p1->matched == true) && (p2->matched == false))
1343
if(i == ref->cmatches)
1347
else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
1351
template <class iterator, class Allocator>
1352
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::cow()
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
1361
new (newref) c_reference(*ref);
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
1371
new (p1) sub_match<iterator>(*p3);
1375
#ifndef BOOST_NO_EXCEPTIONS
1379
p2 = (sub_match<iterator>*)(newref+1);
1382
::boost::re_detail::pointer_destroy(p2);
1385
::boost::re_detail::pointer_destroy(ref);
1391
#ifndef BOOST_NO_EXCEPTIONS
1395
ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * ref->cmatches + sizeof(c_reference));
1402
} // namespace re_detail
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
1410
template <class iterator, class Allocator>
1411
class match_results : public re_detail::match_results_base<iterator, Allocator>
1413
typedef re_detail::match_results_base<iterator, Allocator> base_type;
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;
1423
explicit match_results(const Allocator& a = Allocator())
1424
: re_detail::match_results_base<iterator, Allocator>(a){}
1426
match_results(const re_detail::match_results_base<iterator, Allocator>& m)
1427
: re_detail::match_results_base<iterator, Allocator>(m){}
1429
match_results& operator=(const re_detail::match_results_base<iterator, Allocator>& m)
1432
base_type::operator=(m);
1436
match_results(const match_results& m);
1437
match_results& operator=(const match_results& m);
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:
1444
size_type size()const
1445
{ return static_cast<const base_type*>(this)->size(); }
1447
const sub_match<iterator>& operator[](int n) const
1448
{ return (*static_cast<const base_type*>(this))[n]; }
1450
Allocator allocator()const
1451
{ return static_cast<const base_type*>(this)->allocator(); }
1453
difference_type length(int sub = 0)const
1454
{ return static_cast<const base_type*>(this)->length(sub); }
1456
difference_type position(unsigned int sub = 0)const
1457
{ return static_cast<const base_type*>(this)->position(sub); }
1459
unsigned int line()const
1460
{ return static_cast<const base_type*>(this)->line(); }
1462
iterator line_start()const
1463
{ return static_cast<const base_type*>(this)->line_start(); }
1465
std::basic_string<char_type> str(int sub = 0)const
1466
{ return static_cast<const base_type*>(this)->str(sub); }
1468
void swap(match_results& that)
1469
{ static_cast<base_type*>(this)->swap(that); }
1471
bool operator==(const match_results& that)const
1472
{ return static_cast<const base_type&>(*this) == static_cast<const base_type&>(that); }
1474
bool operator<(const match_results& that) const
1475
{ return position() < that.position(); }
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)
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
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
1500
new (p1) sub_match<iterator>(*p3);
1504
#ifndef BOOST_NO_EXCEPTIONS
1508
p2 = (sub_match<iterator>*)(this->ref+1);
1511
re_detail::pointer_destroy(p2);
1514
re_detail::pointer_destroy(this->ref);
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));
1526
template <class iterator, class Allocator>
1527
match_results<iterator, Allocator>& match_results<iterator, Allocator>::operator=(const match_results<iterator, Allocator>& m)
1529
match_results<iterator, Allocator> t(m);
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,
1538
const re_set_long* set_,
1539
const reg_expression<charT, traits_type, Allocator>& e);
1540
} // namepsace re_detail
1546
} // namespace boost
1548
#ifndef BOOST_REGEX_COMPILE_HPP
1549
#include <boost/regex/v3/regex_compile.hpp>
1553
// template instances:
1555
#define BOOST_REGEX_CHAR_T char
1556
#ifdef BOOST_REGEX_NARROW_INSTANTIATE
1557
# define BOOST_REGEX_INSTANTIATE
1559
#include <boost/regex/v3/instances.hpp>
1560
#undef BOOST_REGEX_CHAR_T
1561
#ifdef BOOST_REGEX_INSTANTIATE
1562
# undef BOOST_REGEX_INSTANTIATE
1565
#ifndef BOOST_NO_WREGEX
1566
#define BOOST_REGEX_CHAR_T wchar_t
1567
#ifdef BOOST_REGEX_WIDE_INSTANTIATE
1568
# define BOOST_REGEX_INSTANTIATE
1570
#include <boost/regex/v3/instances.hpp>
1571
#undef BOOST_REGEX_CHAR_T
1572
#ifdef BOOST_REGEX_INSTANTIATE
1573
# undef BOOST_REGEX_INSTANTIATE
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;
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;
1593
} // namespace boost
1594
#ifndef BOOST_REGEX_MATCH_HPP
1595
#include <boost/regex/v3/regex_match.hpp>
1597
#ifndef BOOST_REGEX_FORMAT_HPP
1598
#include <boost/regex/v3/regex_format.hpp>
1600
#ifndef BOOST_REGEX_SPLIT_HPP
1601
#include <boost/regex/v3/regex_split.hpp>
1604
#endif // __cplusplus