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/functional/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 4231 4800)
40 #if BOOST_MSVC < 1600
41 #pragma warning(disable : 4660)
42 #endif
43 #endif
44 
45 namespace BOOST_REGEX_DETAIL_NS{
46 
47 //
48 // forward declaration, we will need this one later:
49 //
50 template <class charT, class traits>
51 class basic_regex_parser;
52 
53 template <class I>
bubble_down_one(I first,I last)54 void bubble_down_one(I first, I last)
55 {
56    if(first != last)
57    {
58       I next = last - 1;
59       while((next != first) && (*next < *(next-1)))
60       {
61          (next-1)->swap(*next);
62          --next;
63       }
64    }
65 }
66 
67 template <class Iterator>
hash_value_from_capture_name(Iterator i,Iterator j)68 inline int hash_value_from_capture_name(Iterator i, Iterator j)
69 {
70    std::size_t r = boost::hash_range(i, j);
71    r %= ((std::numeric_limits<int>::max)() - 10001);
72    r += 10000;
73    return static_cast<int>(r);
74 }
75 
76 class named_subexpressions
77 {
78 public:
79    struct name
80    {
81       template <class charT>
nameboost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name82       name(const charT* i, const charT* j, int idx)
83          : index(idx)
84       {
85          hash = hash_value_from_capture_name(i, j);
86       }
nameboost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name87       name(int h, int idx)
88          : index(idx), hash(h)
89       {
90       }
91       int index;
92       int hash;
operator <boost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name93       bool operator < (const name& other)const
94       {
95          return hash < other.hash;
96       }
operator ==boost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name97       bool operator == (const name& other)const
98       {
99          return hash == other.hash;
100       }
swapboost::BOOST_REGEX_DETAIL_NS::named_subexpressions::name101       void swap(name& other)
102       {
103          std::swap(index, other.index);
104          std::swap(hash, other.hash);
105       }
106    };
107 
108    typedef std::vector<name>::const_iterator const_iterator;
109    typedef std::pair<const_iterator, const_iterator> range_type;
110 
named_subexpressions()111    named_subexpressions(){}
112 
113    template <class charT>
set_name(const charT * i,const charT * j,int index)114    void set_name(const charT* i, const charT* j, int index)
115    {
116       m_sub_names.push_back(name(i, j, index));
117       bubble_down_one(m_sub_names.begin(), m_sub_names.end());
118    }
119    template <class charT>
get_id(const charT * i,const charT * j) const120    int get_id(const charT* i, const charT* j)const
121    {
122       name t(i, j, 0);
123       typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
124       if((pos != m_sub_names.end()) && (*pos == t))
125       {
126          return pos->index;
127       }
128       return -1;
129    }
130    template <class charT>
equal_range(const charT * i,const charT * j) const131    range_type equal_range(const charT* i, const charT* j)const
132    {
133       name t(i, j, 0);
134       return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
135    }
get_id(int h) const136    int get_id(int h)const
137    {
138       name t(h, 0);
139       std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
140       if((pos != m_sub_names.end()) && (*pos == t))
141       {
142          return pos->index;
143       }
144       return -1;
145    }
equal_range(int h) const146    range_type equal_range(int h)const
147    {
148       name t(h, 0);
149       return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
150    }
151 private:
152    std::vector<name> m_sub_names;
153 };
154 
155 //
156 // class regex_data:
157 // represents the data we wish to expose to the matching algorithms.
158 //
159 template <class charT, class traits>
160 struct regex_data : public named_subexpressions
161 {
162    typedef regex_constants::syntax_option_type   flag_type;
163    typedef std::size_t                           size_type;
164 
regex_databoost::BOOST_REGEX_DETAIL_NS::regex_data165    regex_data(const ::boost::shared_ptr<
166       ::boost::regex_traits_wrapper<traits> >& t)
167       : m_ptraits(t), m_expression(0), m_expression_len(0), m_disable_match_any(false) {}
regex_databoost::BOOST_REGEX_DETAIL_NS::regex_data168    regex_data()
169       : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_expression(0), m_expression_len(0), m_disable_match_any(false) {}
170 
171    ::boost::shared_ptr<
172       ::boost::regex_traits_wrapper<traits>
173       >                        m_ptraits;                 // traits class instance
174    flag_type                   m_flags;                   // flags with which we were compiled
175    int                         m_status;                  // error code (0 implies OK).
176    const charT*                m_expression;              // the original expression
177    std::ptrdiff_t              m_expression_len;          // the length of the original expression
178    size_type                   m_mark_count;              // the number of marked sub-expressions
179    BOOST_REGEX_DETAIL_NS::re_syntax_base*  m_first_state;             // the first state of the machine
180    unsigned                    m_restart_type;            // search optimisation type
181    unsigned char               m_startmap[1 << CHAR_BIT]; // which characters can start a match
182    unsigned int                m_can_be_null;             // whether we can match a null string
183    BOOST_REGEX_DETAIL_NS::raw_storage      m_data;                    // the buffer in which our states are constructed
184    typename traits::char_class_type    m_word_mask;       // mask used to determine if a character is a word character
185    std::vector<
186       std::pair<
187       std::size_t, std::size_t> > m_subs;                 // Position of sub-expressions within the *string*.
188    bool                        m_has_recursions;          // whether we have recursive expressions;
189    bool                        m_disable_match_any;       // when set we need to disable the match_any flag as it causes different/buggy behaviour.
190 };
191 //
192 // class basic_regex_implementation
193 // pimpl implementation class for basic_regex.
194 //
195 template <class charT, class traits>
196 class basic_regex_implementation
197    : public regex_data<charT, traits>
198 {
199 public:
200    typedef regex_constants::syntax_option_type   flag_type;
201    typedef std::ptrdiff_t                        difference_type;
202    typedef std::size_t                           size_type;
203    typedef typename traits::locale_type          locale_type;
204    typedef const charT*                          const_iterator;
205 
basic_regex_implementation()206    basic_regex_implementation(){}
basic_regex_implementation(const::boost::shared_ptr<::boost::regex_traits_wrapper<traits>> & t)207    basic_regex_implementation(const ::boost::shared_ptr<
208       ::boost::regex_traits_wrapper<traits> >& t)
209       : regex_data<charT, traits>(t) {}
assign(const charT * arg_first,const charT * arg_last,flag_type f)210    void assign(const charT* arg_first,
211                           const charT* arg_last,
212                           flag_type f)
213    {
214       regex_data<charT, traits>* pdat = this;
215       basic_regex_parser<charT, traits> parser(pdat);
216       parser.parse(arg_first, arg_last, f);
217    }
218 
imbue(locale_type l)219    locale_type BOOST_REGEX_CALL imbue(locale_type l)
220    {
221       return this->m_ptraits->imbue(l);
222    }
getloc() const223    locale_type BOOST_REGEX_CALL getloc()const
224    {
225       return this->m_ptraits->getloc();
226    }
str() const227    std::basic_string<charT> BOOST_REGEX_CALL str()const
228    {
229       std::basic_string<charT> result;
230       if(this->m_status == 0)
231          result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
232       return result;
233    }
expression() const234    const_iterator BOOST_REGEX_CALL expression()const
235    {
236       return this->m_expression;
237    }
subexpression(std::size_t n) const238    std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
239    {
240       const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);
241       std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);
242       return p;
243    }
244    //
245    // begin, end:
begin() const246    const_iterator BOOST_REGEX_CALL begin()const
247    {
248       return (this->m_status ? 0 : this->m_expression);
249    }
end() const250    const_iterator BOOST_REGEX_CALL end()const
251    {
252       return (this->m_status ? 0 : this->m_expression + this->m_expression_len);
253    }
flags() const254    flag_type BOOST_REGEX_CALL flags()const
255    {
256       return this->m_flags;
257    }
size() const258    size_type BOOST_REGEX_CALL size()const
259    {
260       return this->m_expression_len;
261    }
status() const262    int BOOST_REGEX_CALL status()const
263    {
264       return this->m_status;
265    }
mark_count() const266    size_type BOOST_REGEX_CALL mark_count()const
267    {
268       return this->m_mark_count - 1;
269    }
get_first_state() const270    const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
271    {
272       return this->m_first_state;
273    }
get_restart_type() const274    unsigned get_restart_type()const
275    {
276       return this->m_restart_type;
277    }
get_map() const278    const unsigned char* get_map()const
279    {
280       return this->m_startmap;
281    }
get_traits() const282    const ::boost::regex_traits_wrapper<traits>& get_traits()const
283    {
284       return *(this->m_ptraits);
285    }
can_be_null() const286    bool can_be_null()const
287    {
288       return this->m_can_be_null;
289    }
get_data() const290    const regex_data<charT, traits>& get_data()const
291    {
292       basic_regex_implementation<charT, traits> const* p = this;
293       return *static_cast<const regex_data<charT, traits>*>(p);
294    }
295 };
296 
297 } // namespace BOOST_REGEX_DETAIL_NS
298 //
299 // class basic_regex:
300 // represents the compiled
301 // regular expression:
302 //
303 
304 #ifdef BOOST_REGEX_NO_FWD
305 template <class charT, class traits = regex_traits<charT> >
306 #else
307 template <class charT, class traits >
308 #endif
309 class basic_regex : public regbase
310 {
311 public:
312    // typedefs:
313    typedef std::size_t                           traits_size_type;
314    typedef typename traits::string_type          traits_string_type;
315    typedef charT                                 char_type;
316    typedef traits                                traits_type;
317 
318    typedef charT                                 value_type;
319    typedef charT&                                reference;
320    typedef const charT&                          const_reference;
321    typedef const charT*                          const_iterator;
322    typedef const_iterator                        iterator;
323    typedef std::ptrdiff_t                        difference_type;
324    typedef std::size_t                           size_type;
325    typedef regex_constants::syntax_option_type   flag_type;
326    // locale_type
327    // placeholder for actual locale type used by the
328    // traits class to localise *this.
329    typedef typename traits::locale_type          locale_type;
330 
331 public:
basic_regex()332    explicit basic_regex(){}
basic_regex(const charT * p,flag_type f=regex_constants::normal)333    explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
334    {
335       assign(p, f);
336    }
basic_regex(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)337    basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
338    {
339       assign(p1, p2, f);
340    }
basic_regex(const charT * p,size_type len,flag_type f)341    basic_regex(const charT* p, size_type len, flag_type f)
342    {
343       assign(p, len, f);
344    }
basic_regex(const basic_regex & that)345    basic_regex(const basic_regex& that)
346       : m_pimpl(that.m_pimpl) {}
~basic_regex()347    ~basic_regex(){}
operator =(const basic_regex & that)348    basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)
349    {
350       return assign(that);
351    }
operator =(const charT * ptr)352    basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
353    {
354       return assign(ptr);
355    }
356 
357    //
358    // assign:
assign(const basic_regex & that)359    basic_regex& assign(const basic_regex& that)
360    {
361       m_pimpl = that.m_pimpl;
362       return *this;
363    }
assign(const charT * p,flag_type f=regex_constants::normal)364    basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
365    {
366       return assign(p, p + traits::length(p), f);
367    }
assign(const charT * p,size_type len,flag_type f)368    basic_regex& assign(const charT* p, size_type len, flag_type f)
369    {
370       return assign(p, p + len, f);
371    }
372 private:
373    basic_regex& do_assign(const charT* p1,
374                           const charT* p2,
375                           flag_type f);
376 public:
assign(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)377    basic_regex& assign(const charT* p1,
378                           const charT* p2,
379                           flag_type f = regex_constants::normal)
380    {
381       return do_assign(p1, p2, f);
382    }
383 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
384 
385    template <class ST, class SA>
set_expression(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)386    unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
387    {
388       return set_expression(p.data(), p.data() + p.size(), f);
389    }
390 
391    template <class ST, class SA>
basic_regex(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)392    explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
393    {
394       assign(p, f);
395    }
396 
397    template <class InputIterator>
basic_regex(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)398    basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
399    {
400       typedef typename traits::string_type seq_type;
401       seq_type a(arg_first, arg_last);
402       if(a.size())
403          assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);
404       else
405          assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
406    }
407 
408    template <class ST, class SA>
operator =(const std::basic_string<charT,ST,SA> & p)409    basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
410    {
411       return assign(p.data(), p.data() + p.size(), regex_constants::normal);
412    }
413 
414    template <class string_traits, class A>
assign(const std::basic_string<charT,string_traits,A> & s,flag_type f=regex_constants::normal)415    basic_regex& BOOST_REGEX_CALL assign(
416        const std::basic_string<charT, string_traits, A>& s,
417        flag_type f = regex_constants::normal)
418    {
419       return assign(s.data(), s.data() + s.size(), f);
420    }
421 
422    template <class InputIterator>
assign(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)423    basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,
424                           InputIterator arg_last,
425                           flag_type f = regex_constants::normal)
426    {
427       typedef typename traits::string_type seq_type;
428       seq_type a(arg_first, arg_last);
429       if(a.size())
430       {
431          const charT* p1 = &*a.begin();
432          const charT* p2 = &*a.begin() + a.size();
433          return assign(p1, p2, f);
434       }
435       return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
436    }
437 #else
set_expression(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)438    unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
439    {
440       return set_expression(p.data(), p.data() + p.size(), f);
441    }
442 
basic_regex(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)443    basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
444    {
445       assign(p, f);
446    }
447 
operator =(const std::basic_string<charT> & p)448    basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
449    {
450       return assign(p.data(), p.data() + p.size(), regex_constants::normal);
451    }
452 
assign(const std::basic_string<charT> & s,flag_type f=regex_constants::normal)453    basic_regex& BOOST_REGEX_CALL assign(
454        const std::basic_string<charT>& s,
455        flag_type f = regex_constants::normal)
456    {
457       return assign(s.data(), s.data() + s.size(), f);
458    }
459 
460 #endif
461 
462    //
463    // locale:
464    locale_type BOOST_REGEX_CALL imbue(locale_type l);
getloc() const465    locale_type BOOST_REGEX_CALL getloc()const
466    {
467       return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
468    }
469    //
470    // getflags:
471    // retained for backwards compatibility only, "flags"
472    // is now the preferred name:
getflags() const473    flag_type BOOST_REGEX_CALL getflags()const
474    {
475       return flags();
476    }
flags() const477    flag_type BOOST_REGEX_CALL flags()const
478    {
479       return m_pimpl.get() ? m_pimpl->flags() : 0;
480    }
481    //
482    // str:
str() const483    std::basic_string<charT> BOOST_REGEX_CALL str()const
484    {
485       return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
486    }
487    //
488    // begin, end, subexpression:
subexpression(std::size_t n) const489    std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
490    {
491       if(!m_pimpl.get())
492          boost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));
493       return m_pimpl->subexpression(n);
494    }
begin() const495    const_iterator BOOST_REGEX_CALL begin()const
496    {
497       return (m_pimpl.get() ? m_pimpl->begin() : 0);
498    }
end() const499    const_iterator BOOST_REGEX_CALL end()const
500    {
501       return (m_pimpl.get() ? m_pimpl->end() : 0);
502    }
503    //
504    // swap:
swap(basic_regex & that)505    void BOOST_REGEX_CALL swap(basic_regex& that)throw()
506    {
507       m_pimpl.swap(that.m_pimpl);
508    }
509    //
510    // size:
size() const511    size_type BOOST_REGEX_CALL size()const
512    {
513       return (m_pimpl.get() ? m_pimpl->size() : 0);
514    }
515    //
516    // max_size:
max_size() const517    size_type BOOST_REGEX_CALL max_size()const
518    {
519       return UINT_MAX;
520    }
521    //
522    // empty:
empty() const523    bool BOOST_REGEX_CALL empty()const
524    {
525       return (m_pimpl.get() ? 0 != m_pimpl->status() : true);
526    }
527 
mark_count() const528    size_type BOOST_REGEX_CALL mark_count()const
529    {
530       return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
531    }
532 
status() const533    int status()const
534    {
535       return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
536    }
537 
compare(const basic_regex & that) const538    int BOOST_REGEX_CALL compare(const basic_regex& that) const
539    {
540       if(m_pimpl.get() == that.m_pimpl.get())
541          return 0;
542       if(!m_pimpl.get())
543          return -1;
544       if(!that.m_pimpl.get())
545          return 1;
546       if(status() != that.status())
547          return status() - that.status();
548       if(flags() != that.flags())
549          return flags() - that.flags();
550       return str().compare(that.str());
551    }
operator ==(const basic_regex & e) const552    bool BOOST_REGEX_CALL operator==(const basic_regex& e)const
553    {
554       return compare(e) == 0;
555    }
operator !=(const basic_regex & e) const556    bool BOOST_REGEX_CALL operator != (const basic_regex& e)const
557    {
558       return compare(e) != 0;
559    }
operator <(const basic_regex & e) const560    bool BOOST_REGEX_CALL operator<(const basic_regex& e)const
561    {
562       return compare(e) < 0;
563    }
operator >(const basic_regex & e) const564    bool BOOST_REGEX_CALL operator>(const basic_regex& e)const
565    {
566       return compare(e) > 0;
567    }
operator <=(const basic_regex & e) const568    bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const
569    {
570       return compare(e) <= 0;
571    }
operator >=(const basic_regex & e) const572    bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const
573    {
574       return compare(e) >= 0;
575    }
576 
577    //
578    // The following are deprecated as public interfaces
579    // but are available for compatibility with earlier versions.
expression() const580    const charT* BOOST_REGEX_CALL expression()const
581    {
582       return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
583    }
set_expression(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)584    unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
585    {
586       assign(p1, p2, f | regex_constants::no_except);
587       return status();
588    }
set_expression(const charT * p,flag_type f=regex_constants::normal)589    unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal)
590    {
591       assign(p, f | regex_constants::no_except);
592       return status();
593    }
error_code() const594    unsigned int BOOST_REGEX_CALL error_code()const
595    {
596       return status();
597    }
598    //
599    // private access methods:
600    //
get_first_state() const601    const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
602    {
603       BOOST_ASSERT(0 != m_pimpl.get());
604       return m_pimpl->get_first_state();
605    }
get_restart_type() const606    unsigned get_restart_type()const
607    {
608       BOOST_ASSERT(0 != m_pimpl.get());
609       return m_pimpl->get_restart_type();
610    }
get_map() const611    const unsigned char* get_map()const
612    {
613       BOOST_ASSERT(0 != m_pimpl.get());
614       return m_pimpl->get_map();
615    }
get_traits() const616    const ::boost::regex_traits_wrapper<traits>& get_traits()const
617    {
618       BOOST_ASSERT(0 != m_pimpl.get());
619       return m_pimpl->get_traits();
620    }
can_be_null() const621    bool can_be_null()const
622    {
623       BOOST_ASSERT(0 != m_pimpl.get());
624       return m_pimpl->can_be_null();
625    }
get_data() const626    const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const
627    {
628       BOOST_ASSERT(0 != m_pimpl.get());
629       return m_pimpl->get_data();
630    }
get_named_subs() const631    boost::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const
632    {
633       return m_pimpl;
634    }
635 
636 private:
637    shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;
638 };
639 
640 //
641 // out of line members;
642 // these are the only members that mutate the basic_regex object,
643 // and are designed to provide the strong exception guarentee
644 // (in the event of a throw, the state of the object remains unchanged).
645 //
646 template <class charT, class traits>
do_assign(const charT * p1,const charT * p2,flag_type f)647 basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
648                         const charT* p2,
649                         flag_type f)
650 {
651    shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;
652    if(!m_pimpl.get())
653    {
654       temp = shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
655    }
656    else
657    {
658       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));
659    }
660    temp->assign(p1, p2, f);
661    temp.swap(m_pimpl);
662    return *this;
663 }
664 
665 template <class charT, class traits>
imbue(locale_type l)666 typename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)
667 {
668    shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
669    locale_type result = temp->imbue(l);
670    temp.swap(m_pimpl);
671    return result;
672 }
673 
674 //
675 // non-members:
676 //
677 template <class charT, class traits>
swap(basic_regex<charT,traits> & e1,basic_regex<charT,traits> & e2)678 void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
679 {
680    e1.swap(e2);
681 }
682 
683 #ifndef BOOST_NO_STD_LOCALE
684 template <class charT, class traits, class traits2>
685 std::basic_ostream<charT, traits>&
operator <<(std::basic_ostream<charT,traits> & os,const basic_regex<charT,traits2> & e)686    operator << (std::basic_ostream<charT, traits>& os,
687                 const basic_regex<charT, traits2>& e)
688 {
689    return (os << e.str());
690 }
691 #else
692 template <class traits>
operator <<(std::ostream & os,const basic_regex<char,traits> & e)693 std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)
694 {
695    return (os << e.str());
696 }
697 #endif
698 
699 //
700 // class reg_expression:
701 // this is provided for backwards compatibility only,
702 // it is deprecated, no not use!
703 //
704 #ifdef BOOST_REGEX_NO_FWD
705 template <class charT, class traits = regex_traits<charT> >
706 #else
707 template <class charT, class traits >
708 #endif
709 class reg_expression : public basic_regex<charT, traits>
710 {
711 public:
712    typedef typename basic_regex<charT, traits>::flag_type flag_type;
713    typedef typename basic_regex<charT, traits>::size_type size_type;
reg_expression()714    explicit reg_expression(){}
reg_expression(const charT * p,flag_type f=regex_constants::normal)715    explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
716       : basic_regex<charT, traits>(p, f){}
reg_expression(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)717    reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
718       : basic_regex<charT, traits>(p1, p2, f){}
reg_expression(const charT * p,size_type len,flag_type f)719    reg_expression(const charT* p, size_type len, flag_type f)
720       : basic_regex<charT, traits>(p, len, f){}
reg_expression(const reg_expression & that)721    reg_expression(const reg_expression& that)
722       : basic_regex<charT, traits>(that) {}
~reg_expression()723    ~reg_expression(){}
operator =(const reg_expression & that)724    reg_expression& BOOST_REGEX_CALL operator=(const reg_expression& that)
725    {
726       return this->assign(that);
727    }
728 
729 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
730    template <class ST, class SA>
reg_expression(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)731    explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
732    : basic_regex<charT, traits>(p, f)
733    {
734    }
735 
736    template <class InputIterator>
reg_expression(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)737    reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
738    : basic_regex<charT, traits>(arg_first, arg_last, f)
739    {
740    }
741 
742    template <class ST, class SA>
operator =(const std::basic_string<charT,ST,SA> & p)743    reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
744    {
745       this->assign(p);
746       return *this;
747    }
748 #else
reg_expression(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)749    explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
750    : basic_regex<charT, traits>(p, f)
751    {
752    }
753 
operator =(const std::basic_string<charT> & p)754    reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
755    {
756       this->assign(p);
757       return *this;
758    }
759 #endif
760 
761 };
762 
763 #ifdef BOOST_MSVC
764 #pragma warning (pop)
765 #endif
766 
767 } // namespace boost
768 
769 #ifdef BOOST_MSVC
770 #pragma warning(push)
771 #pragma warning(disable: 4103)
772 #endif
773 #ifdef BOOST_HAS_ABI_HEADERS
774 #  include BOOST_ABI_SUFFIX
775 #endif
776 #ifdef BOOST_MSVC
777 #pragma warning(pop)
778 #endif
779 
780 #endif
781 
782