1 /*
2  *
3  * Copyright (c) 1998-2004 John Maddock
4  * Copyright 2011 Garmin Ltd. or its subsidiaries
5  *
6  * Distributed under the Boost Software License, Version 1.0.
7  * (See accompanying file LICENSE_1_0.txt or copy at
8  * http://www.boost.org/LICENSE_1_0.txt)
9  *
10  */
11 
12  /*
13   *   LOCATION:    see http://www.boost.org/ for most recent version.
14   *   FILE         basic_regex.cpp
15   *   VERSION      see <boost/version.hpp>
16   *   DESCRIPTION: Declares template class basic_regex.
17   */
18 
19 #ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP
20 #define BOOST_REGEX_V4_BASIC_REGEX_HPP
21 
22 #include <boost/type_traits/is_same.hpp>
23 #include <boost/container_hash/hash.hpp>
24 
25 #ifdef BOOST_MSVC
26 #pragma warning(push)
27 #pragma warning(disable: 4103)
28 #endif
29 #ifdef BOOST_HAS_ABI_HEADERS
30 #  include BOOST_ABI_PREFIX
31 #endif
32 #ifdef BOOST_MSVC
33 #pragma warning(pop)
34 #endif
35 
36 namespace boost{
37 #ifdef BOOST_MSVC
38 #pragma warning(push)
39 #pragma warning(disable : 4251)
40 #if BOOST_MSVC < 1700
41 #     pragma warning(disable : 4231)
42 #endif
43 #if BOOST_MSVC < 1600
44 #pragma warning(disable : 4660)
45 #endif
46 #if BOOST_MSVC < 1910
47 #pragma warning(disable:4800)
48 #endif
49 #endif
50 
51 namespace BOOST_REGEX_DETAIL_NS{
52 
53 //
54 // forward declaration, we will need this one later:
55 //
56 template <class charT, class traits>
57 class basic_regex_parser;
58 
59 template <class I>
bubble_down_one(I first,I last)60 void bubble_down_one(I first, I last)
61 {
62    if(first != last)
63    {
64       I next = last - 1;
65       while((next != first) && (*next < *(next-1)))
66       {
67          (next-1)->swap(*next);
68          --next;
69       }
70    }
71 }
72 
73 static const int hash_value_mask = 1 << (std::numeric_limits<int>::digits - 1);
74 
75 template <class Iterator>
hash_value_from_capture_name(Iterator i,Iterator j)76 inline int hash_value_from_capture_name(Iterator i, Iterator j)
77 {
78    std::size_t r = boost::hash_range(i, j);
79    r %= ((std::numeric_limits<int>::max)());
80    return static_cast<int>(r) | hash_value_mask;
81 }
82 
83 class named_subexpressions
84 {
85 public:
86    struct name
87    {
88       template <class charT>
nameboost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name89       name(const charT* i, const charT* j, int idx)
90          : index(idx)
91       {
92          hash = hash_value_from_capture_name(i, j);
93       }
nameboost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name94       name(int h, int idx)
95          : index(idx), hash(h)
96       {
97       }
98       int index;
99       int hash;
operator <boost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name100       bool operator < (const name& other)const
101       {
102          return hash < other.hash;
103       }
operator ==boost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name104       bool operator == (const name& other)const
105       {
106          return hash == other.hash;
107       }
swapboost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name108       void swap(name& other)
109       {
110          std::swap(index, other.index);
111          std::swap(hash, other.hash);
112       }
113    };
114 
115    typedef std::vector<name>::const_iterator const_iterator;
116    typedef std::pair<const_iterator, const_iterator> range_type;
117 
named_subexpressions()118    named_subexpressions(){}
119 
120    template <class charT>
set_name(const charT * i,const charT * j,int index)121    void set_name(const charT* i, const charT* j, int index)
122    {
123       m_sub_names.push_back(name(i, j, index));
124       bubble_down_one(m_sub_names.begin(), m_sub_names.end());
125    }
126    template <class charT>
get_id(const charT * i,const charT * j) const127    int get_id(const charT* i, const charT* j)const
128    {
129       name t(i, j, 0);
130       typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
131       if((pos != m_sub_names.end()) && (*pos == t))
132       {
133          return pos->index;
134       }
135       return -1;
136    }
137    template <class charT>
equal_range(const charT * i,const charT * j) const138    range_type equal_range(const charT* i, const charT* j)const
139    {
140       name t(i, j, 0);
141       return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
142    }
get_id(int h) const143    int get_id(int h)const
144    {
145       name t(h, 0);
146       std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
147       if((pos != m_sub_names.end()) && (*pos == t))
148       {
149          return pos->index;
150       }
151       return -1;
152    }
equal_range(int h) const153    range_type equal_range(int h)const
154    {
155       name t(h, 0);
156       return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
157    }
158 private:
159    std::vector<name> m_sub_names;
160 };
161 
162 //
163 // class regex_data:
164 // represents the data we wish to expose to the matching algorithms.
165 //
166 template <class charT, class traits>
167 struct regex_data : public named_subexpressions
168 {
169    typedef regex_constants::syntax_option_type   flag_type;
170    typedef std::size_t                           size_type;
171 
regex_databoost::BOOST_REGEX_DETAIL_NS::regex_data172    regex_data(const ::boost::shared_ptr<
173       ::boost::regex_traits_wrapper<traits> >& t)
174       : m_ptraits(t), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),
175          m_mark_count(0), m_first_state(0), m_restart_type(0),
176 #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !(defined(BOOST_MSVC) && (BOOST_MSVC < 1900))
177          m_startmap{ 0 },
178 #endif
179          m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
regex_databoost::BOOST_REGEX_DETAIL_NS::regex_data180    regex_data()
181       : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),
182          m_mark_count(0), m_first_state(0), m_restart_type(0),
183 #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !(defined(BOOST_MSVC) && (BOOST_MSVC < 1900))
184       m_startmap{ 0 },
185 #endif
186          m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
187 
188    ::boost::shared_ptr<
189       ::boost::regex_traits_wrapper<traits>
190       >                        m_ptraits;                 // traits class instance
191    flag_type                   m_flags;                   // flags with which we were compiled
192    int                         m_status;                  // error code (0 implies OK).
193    const charT*                m_expression;              // the original expression
194    std::ptrdiff_t              m_expression_len;          // the length of the original expression
195    size_type                   m_mark_count;              // the number of marked sub-expressions
196    BOOST_REGEX_DETAIL_NS::re_syntax_base*  m_first_state;             // the first state of the machine
197    unsigned                    m_restart_type;            // search optimisation type
198    unsigned char               m_startmap[1 << CHAR_BIT]; // which characters can start a match
199    unsigned int                m_can_be_null;             // whether we can match a null string
200    BOOST_REGEX_DETAIL_NS::raw_storage      m_data;                    // the buffer in which our states are constructed
201    typename traits::char_class_type    m_word_mask;       // mask used to determine if a character is a word character
202    std::vector<
203       std::pair<
204       std::size_t, std::size_t> > m_subs;                 // Position of sub-expressions within the *string*.
205    bool                        m_has_recursions;          // whether we have recursive expressions;
206    bool                        m_disable_match_any;       // when set we need to disable the match_any flag as it causes different/buggy behaviour.
207 };
208 //
209 // class basic_regex_implementation
210 // pimpl implementation class for basic_regex.
211 //
212 template <class charT, class traits>
213 class basic_regex_implementation
214    : public regex_data<charT, traits>
215 {
216 public:
217    typedef regex_constants::syntax_option_type   flag_type;
218    typedef std::ptrdiff_t                        difference_type;
219    typedef std::size_t                           size_type;
220    typedef typename traits::locale_type          locale_type;
221    typedef const charT*                          const_iterator;
222 
basic_regex_implementation()223    basic_regex_implementation(){}
basic_regex_implementation(const::boost::shared_ptr<::boost::regex_traits_wrapper<traits>> & t)224    basic_regex_implementation(const ::boost::shared_ptr<
225       ::boost::regex_traits_wrapper<traits> >& t)
226       : regex_data<charT, traits>(t) {}
assign(const charT * arg_first,const charT * arg_last,flag_type f)227    void assign(const charT* arg_first,
228                           const charT* arg_last,
229                           flag_type f)
230    {
231       regex_data<charT, traits>* pdat = this;
232       basic_regex_parser<charT, traits> parser(pdat);
233       parser.parse(arg_first, arg_last, f);
234    }
235 
imbue(locale_type l)236    locale_type BOOST_REGEX_CALL imbue(locale_type l)
237    {
238       return this->m_ptraits->imbue(l);
239    }
getloc() const240    locale_type BOOST_REGEX_CALL getloc()const
241    {
242       return this->m_ptraits->getloc();
243    }
str() const244    std::basic_string<charT> BOOST_REGEX_CALL str()const
245    {
246       std::basic_string<charT> result;
247       if(this->m_status == 0)
248          result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
249       return result;
250    }
expression() const251    const_iterator BOOST_REGEX_CALL expression()const
252    {
253       return this->m_expression;
254    }
subexpression(std::size_t n) const255    std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
256    {
257       const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);
258       std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);
259       return p;
260    }
261    //
262    // begin, end:
begin() const263    const_iterator BOOST_REGEX_CALL begin()const
264    {
265       return (this->m_status ? 0 : this->m_expression);
266    }
end() const267    const_iterator BOOST_REGEX_CALL end()const
268    {
269       return (this->m_status ? 0 : this->m_expression + this->m_expression_len);
270    }
flags() const271    flag_type BOOST_REGEX_CALL flags()const
272    {
273       return this->m_flags;
274    }
size() const275    size_type BOOST_REGEX_CALL size()const
276    {
277       return this->m_expression_len;
278    }
status() const279    int BOOST_REGEX_CALL status()const
280    {
281       return this->m_status;
282    }
mark_count() const283    size_type BOOST_REGEX_CALL mark_count()const
284    {
285       return this->m_mark_count - 1;
286    }
get_first_state() const287    const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
288    {
289       return this->m_first_state;
290    }
get_restart_type() const291    unsigned get_restart_type()const
292    {
293       return this->m_restart_type;
294    }
get_map() const295    const unsigned char* get_map()const
296    {
297       return this->m_startmap;
298    }
get_traits() const299    const ::boost::regex_traits_wrapper<traits>& get_traits()const
300    {
301       return *(this->m_ptraits);
302    }
can_be_null() const303    bool can_be_null()const
304    {
305       return this->m_can_be_null;
306    }
get_data() const307    const regex_data<charT, traits>& get_data()const
308    {
309       basic_regex_implementation<charT, traits> const* p = this;
310       return *static_cast<const regex_data<charT, traits>*>(p);
311    }
312 };
313 
314 } // namespace BOOST_REGEX_DETAIL_NS
315 //
316 // class basic_regex:
317 // represents the compiled
318 // regular expression:
319 //
320 
321 #ifdef BOOST_REGEX_NO_FWD
322 template <class charT, class traits = regex_traits<charT> >
323 #else
324 template <class charT, class traits >
325 #endif
326 class basic_regex : public regbase
327 {
328 public:
329    // typedefs:
330    typedef std::size_t                           traits_size_type;
331    typedef typename traits::string_type          traits_string_type;
332    typedef charT                                 char_type;
333    typedef traits                                traits_type;
334 
335    typedef charT                                 value_type;
336    typedef charT&                                reference;
337    typedef const charT&                          const_reference;
338    typedef const charT*                          const_iterator;
339    typedef const_iterator                        iterator;
340    typedef std::ptrdiff_t                        difference_type;
341    typedef std::size_t                           size_type;
342    typedef regex_constants::syntax_option_type   flag_type;
343    // locale_type
344    // placeholder for actual locale type used by the
345    // traits class to localise *this.
346    typedef typename traits::locale_type          locale_type;
347 
348 public:
basic_regex()349    explicit basic_regex(){}
basic_regex(const charT * p,flag_type f=regex_constants::normal)350    explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
351    {
352       assign(p, f);
353    }
basic_regex(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)354    basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
355    {
356       assign(p1, p2, f);
357    }
basic_regex(const charT * p,size_type len,flag_type f)358    basic_regex(const charT* p, size_type len, flag_type f)
359    {
360       assign(p, len, f);
361    }
basic_regex(const basic_regex & that)362    basic_regex(const basic_regex& that)
363       : m_pimpl(that.m_pimpl) {}
~basic_regex()364    ~basic_regex(){}
operator =(const basic_regex & that)365    basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)
366    {
367       return assign(that);
368    }
operator =(const charT * ptr)369    basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
370    {
371       return assign(ptr);
372    }
373 
374    //
375    // assign:
assign(const basic_regex & that)376    basic_regex& assign(const basic_regex& that)
377    {
378       m_pimpl = that.m_pimpl;
379       return *this;
380    }
assign(const charT * p,flag_type f=regex_constants::normal)381    basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
382    {
383       return assign(p, p + traits::length(p), f);
384    }
assign(const charT * p,size_type len,flag_type f)385    basic_regex& assign(const charT* p, size_type len, flag_type f)
386    {
387       return assign(p, p + len, f);
388    }
389 private:
390    basic_regex& do_assign(const charT* p1,
391                           const charT* p2,
392                           flag_type f);
393 public:
assign(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)394    basic_regex& assign(const charT* p1,
395                           const charT* p2,
396                           flag_type f = regex_constants::normal)
397    {
398       return do_assign(p1, p2, f);
399    }
400 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
401 
402    template <class ST, class SA>
set_expression(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)403    unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
404    {
405       return set_expression(p.data(), p.data() + p.size(), f);
406    }
407 
408    template <class ST, class SA>
basic_regex(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)409    explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
410    {
411       assign(p, f);
412    }
413 
414    template <class InputIterator>
basic_regex(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)415    basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
416    {
417       typedef typename traits::string_type seq_type;
418       seq_type a(arg_first, arg_last);
419       if(!a.empty())
420          assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);
421       else
422          assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
423    }
424 
425    template <class ST, class SA>
operator =(const std::basic_string<charT,ST,SA> & p)426    basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
427    {
428       return assign(p.data(), p.data() + p.size(), regex_constants::normal);
429    }
430 
431    template <class string_traits, class A>
assign(const std::basic_string<charT,string_traits,A> & s,flag_type f=regex_constants::normal)432    basic_regex& BOOST_REGEX_CALL assign(
433        const std::basic_string<charT, string_traits, A>& s,
434        flag_type f = regex_constants::normal)
435    {
436       return assign(s.data(), s.data() + s.size(), f);
437    }
438 
439    template <class InputIterator>
assign(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)440    basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,
441                           InputIterator arg_last,
442                           flag_type f = regex_constants::normal)
443    {
444       typedef typename traits::string_type seq_type;
445       seq_type a(arg_first, arg_last);
446       if(a.size())
447       {
448          const charT* p1 = &*a.begin();
449          const charT* p2 = &*a.begin() + a.size();
450          return assign(p1, p2, f);
451       }
452       return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
453    }
454 #else
set_expression(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)455    unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
456    {
457       return set_expression(p.data(), p.data() + p.size(), f);
458    }
459 
basic_regex(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)460    basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
461    {
462       assign(p, f);
463    }
464 
operator =(const std::basic_string<charT> & p)465    basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
466    {
467       return assign(p.data(), p.data() + p.size(), regex_constants::normal);
468    }
469 
assign(const std::basic_string<charT> & s,flag_type f=regex_constants::normal)470    basic_regex& BOOST_REGEX_CALL assign(
471        const std::basic_string<charT>& s,
472        flag_type f = regex_constants::normal)
473    {
474       return assign(s.data(), s.data() + s.size(), f);
475    }
476 
477 #endif
478 
479    //
480    // locale:
481    locale_type BOOST_REGEX_CALL imbue(locale_type l);
getloc() const482    locale_type BOOST_REGEX_CALL getloc()const
483    {
484       return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
485    }
486    //
487    // getflags:
488    // retained for backwards compatibility only, "flags"
489    // is now the preferred name:
getflags() const490    flag_type BOOST_REGEX_CALL getflags()const
491    {
492       return flags();
493    }
flags() const494    flag_type BOOST_REGEX_CALL flags()const
495    {
496       return m_pimpl.get() ? m_pimpl->flags() : 0;
497    }
498    //
499    // str:
str() const500    std::basic_string<charT> BOOST_REGEX_CALL str()const
501    {
502       return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
503    }
504    //
505    // begin, end, subexpression:
subexpression(std::size_t n) const506    std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
507    {
508       if(!m_pimpl.get())
509          boost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));
510       return m_pimpl->subexpression(n);
511    }
begin() const512    const_iterator BOOST_REGEX_CALL begin()const
513    {
514       return (m_pimpl.get() ? m_pimpl->begin() : 0);
515    }
end() const516    const_iterator BOOST_REGEX_CALL end()const
517    {
518       return (m_pimpl.get() ? m_pimpl->end() : 0);
519    }
520    //
521    // swap:
swap(basic_regex & that)522    void BOOST_REGEX_CALL swap(basic_regex& that)throw()
523    {
524       m_pimpl.swap(that.m_pimpl);
525    }
526    //
527    // size:
size() const528    size_type BOOST_REGEX_CALL size()const
529    {
530       return (m_pimpl.get() ? m_pimpl->size() : 0);
531    }
532    //
533    // max_size:
max_size() const534    size_type BOOST_REGEX_CALL max_size()const
535    {
536       return UINT_MAX;
537    }
538    //
539    // empty:
empty() const540    bool BOOST_REGEX_CALL empty()const
541    {
542       return (m_pimpl.get() ? 0 != m_pimpl->status() : true);
543    }
544 
mark_count() const545    size_type BOOST_REGEX_CALL mark_count()const
546    {
547       return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
548    }
549 
status() const550    int status()const
551    {
552       return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
553    }
554 
compare(const basic_regex & that) const555    int BOOST_REGEX_CALL compare(const basic_regex& that) const
556    {
557       if(m_pimpl.get() == that.m_pimpl.get())
558          return 0;
559       if(!m_pimpl.get())
560          return -1;
561       if(!that.m_pimpl.get())
562          return 1;
563       if(status() != that.status())
564          return status() - that.status();
565       if(flags() != that.flags())
566          return flags() - that.flags();
567       return str().compare(that.str());
568    }
operator ==(const basic_regex & e) const569    bool BOOST_REGEX_CALL operator==(const basic_regex& e)const
570    {
571       return compare(e) == 0;
572    }
operator !=(const basic_regex & e) const573    bool BOOST_REGEX_CALL operator != (const basic_regex& e)const
574    {
575       return compare(e) != 0;
576    }
operator <(const basic_regex & e) const577    bool BOOST_REGEX_CALL operator<(const basic_regex& e)const
578    {
579       return compare(e) < 0;
580    }
operator >(const basic_regex & e) const581    bool BOOST_REGEX_CALL operator>(const basic_regex& e)const
582    {
583       return compare(e) > 0;
584    }
operator <=(const basic_regex & e) const585    bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const
586    {
587       return compare(e) <= 0;
588    }
operator >=(const basic_regex & e) const589    bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const
590    {
591       return compare(e) >= 0;
592    }
593 
594    //
595    // The following are deprecated as public interfaces
596    // but are available for compatibility with earlier versions.
expression() const597    const charT* BOOST_REGEX_CALL expression()const
598    {
599       return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
600    }
set_expression(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)601    unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
602    {
603       assign(p1, p2, f | regex_constants::no_except);
604       return status();
605    }
set_expression(const charT * p,flag_type f=regex_constants::normal)606    unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal)
607    {
608       assign(p, f | regex_constants::no_except);
609       return status();
610    }
error_code() const611    unsigned int BOOST_REGEX_CALL error_code()const
612    {
613       return status();
614    }
615    //
616    // private access methods:
617    //
get_first_state() const618    const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
619    {
620       BOOST_REGEX_ASSERT(0 != m_pimpl.get());
621       return m_pimpl->get_first_state();
622    }
get_restart_type() const623    unsigned get_restart_type()const
624    {
625       BOOST_REGEX_ASSERT(0 != m_pimpl.get());
626       return m_pimpl->get_restart_type();
627    }
get_map() const628    const unsigned char* get_map()const
629    {
630       BOOST_REGEX_ASSERT(0 != m_pimpl.get());
631       return m_pimpl->get_map();
632    }
get_traits() const633    const ::boost::regex_traits_wrapper<traits>& get_traits()const
634    {
635       BOOST_REGEX_ASSERT(0 != m_pimpl.get());
636       return m_pimpl->get_traits();
637    }
can_be_null() const638    bool can_be_null()const
639    {
640       BOOST_REGEX_ASSERT(0 != m_pimpl.get());
641       return m_pimpl->can_be_null();
642    }
get_data() const643    const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const
644    {
645       BOOST_REGEX_ASSERT(0 != m_pimpl.get());
646       return m_pimpl->get_data();
647    }
get_named_subs() const648    boost::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const
649    {
650       return m_pimpl;
651    }
652 
653 private:
654    shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;
655 };
656 
657 //
658 // out of line members;
659 // these are the only members that mutate the basic_regex object,
660 // and are designed to provide the strong exception guarantee
661 // (in the event of a throw, the state of the object remains unchanged).
662 //
663 template <class charT, class traits>
do_assign(const charT * p1,const charT * p2,flag_type f)664 basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
665                         const charT* p2,
666                         flag_type f)
667 {
668    shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;
669    if(!m_pimpl.get())
670    {
671       temp = shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
672    }
673    else
674    {
675       temp = shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
676    }
677    temp->assign(p1, p2, f);
678    temp.swap(m_pimpl);
679    return *this;
680 }
681 
682 template <class charT, class traits>
imbue(locale_type l)683 typename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)
684 {
685    shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
686    locale_type result = temp->imbue(l);
687    temp.swap(m_pimpl);
688    return result;
689 }
690 
691 //
692 // non-members:
693 //
694 template <class charT, class traits>
swap(basic_regex<charT,traits> & e1,basic_regex<charT,traits> & e2)695 void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
696 {
697    e1.swap(e2);
698 }
699 
700 #ifndef BOOST_NO_STD_LOCALE
701 template <class charT, class traits, class traits2>
702 std::basic_ostream<charT, traits>&
operator <<(std::basic_ostream<charT,traits> & os,const basic_regex<charT,traits2> & e)703    operator << (std::basic_ostream<charT, traits>& os,
704                 const basic_regex<charT, traits2>& e)
705 {
706    return (os << e.str());
707 }
708 #else
709 template <class traits>
operator <<(std::ostream & os,const basic_regex<char,traits> & e)710 std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)
711 {
712    return (os << e.str());
713 }
714 #endif
715 
716 //
717 // class reg_expression:
718 // this is provided for backwards compatibility only,
719 // it is deprecated, no not use!
720 //
721 #ifdef BOOST_REGEX_NO_FWD
722 template <class charT, class traits = regex_traits<charT> >
723 #else
724 template <class charT, class traits >
725 #endif
726 class reg_expression : public basic_regex<charT, traits>
727 {
728 public:
729    typedef typename basic_regex<charT, traits>::flag_type flag_type;
730    typedef typename basic_regex<charT, traits>::size_type size_type;
reg_expression()731    explicit reg_expression(){}
reg_expression(const charT * p,flag_type f=regex_constants::normal)732    explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
733       : basic_regex<charT, traits>(p, f){}
reg_expression(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)734    reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
735       : basic_regex<charT, traits>(p1, p2, f){}
reg_expression(const charT * p,size_type len,flag_type f)736    reg_expression(const charT* p, size_type len, flag_type f)
737       : basic_regex<charT, traits>(p, len, f){}
reg_expression(const reg_expression & that)738    reg_expression(const reg_expression& that)
739       : basic_regex<charT, traits>(that) {}
~reg_expression()740    ~reg_expression(){}
operator =(const reg_expression & that)741    reg_expression& BOOST_REGEX_CALL operator=(const reg_expression& that)
742    {
743       return this->assign(that);
744    }
745 
746 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
747    template <class ST, class SA>
reg_expression(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)748    explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
749    : basic_regex<charT, traits>(p, f)
750    {
751    }
752 
753    template <class InputIterator>
reg_expression(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)754    reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
755    : basic_regex<charT, traits>(arg_first, arg_last, f)
756    {
757    }
758 
759    template <class ST, class SA>
operator =(const std::basic_string<charT,ST,SA> & p)760    reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
761    {
762       this->assign(p);
763       return *this;
764    }
765 #else
reg_expression(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)766    explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
767    : basic_regex<charT, traits>(p, f)
768    {
769    }
770 
operator =(const std::basic_string<charT> & p)771    reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
772    {
773       this->assign(p);
774       return *this;
775    }
776 #endif
777 
778 };
779 
780 #ifdef BOOST_MSVC
781 #pragma warning (pop)
782 #endif
783 
784 } // namespace boost
785 
786 #ifdef BOOST_MSVC
787 #pragma warning(push)
788 #pragma warning(disable: 4103)
789 #endif
790 #ifdef BOOST_HAS_ABI_HEADERS
791 #  include BOOST_ABI_SUFFIX
792 #endif
793 #ifdef BOOST_MSVC
794 #pragma warning(pop)
795 #endif
796 
797 #endif
798