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 re_detail{
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::re_detail::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::re_detail::named_subexpressions::name87       name(int h, int idx)
88          : index(idx), hash(h)
89       {
90       }
91       int index;
92       int hash;
operator <boost::re_detail::named_subexpressions::name93       bool operator < (const name& other)const
94       {
95          return hash < other.hash;
96       }
operator ==boost::re_detail::named_subexpressions::name97       bool operator == (const name& other)const
98       {
99          return hash == other.hash;
100       }
swapboost::re_detail::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::re_detail::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) {}
regex_databoost::re_detail::regex_data168    regex_data()
169       : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_expression(0), m_expression_len(0) {}
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    re_detail::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    re_detail::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 };
190 //
191 // class basic_regex_implementation
192 // pimpl implementation class for basic_regex.
193 //
194 template <class charT, class traits>
195 class basic_regex_implementation
196    : public regex_data<charT, traits>
197 {
198 public:
199    typedef regex_constants::syntax_option_type   flag_type;
200    typedef std::ptrdiff_t                        difference_type;
201    typedef std::size_t                           size_type;
202    typedef typename traits::locale_type          locale_type;
203    typedef const charT*                          const_iterator;
204 
basic_regex_implementation()205    basic_regex_implementation(){}
basic_regex_implementation(const::boost::shared_ptr<::boost::regex_traits_wrapper<traits>> & t)206    basic_regex_implementation(const ::boost::shared_ptr<
207       ::boost::regex_traits_wrapper<traits> >& t)
208       : regex_data<charT, traits>(t) {}
assign(const charT * arg_first,const charT * arg_last,flag_type f)209    void assign(const charT* arg_first,
210                           const charT* arg_last,
211                           flag_type f)
212    {
213       regex_data<charT, traits>* pdat = this;
214       basic_regex_parser<charT, traits> parser(pdat);
215       parser.parse(arg_first, arg_last, f);
216    }
217 
imbue(locale_type l)218    locale_type BOOST_REGEX_CALL imbue(locale_type l)
219    {
220       return this->m_ptraits->imbue(l);
221    }
getloc() const222    locale_type BOOST_REGEX_CALL getloc()const
223    {
224       return this->m_ptraits->getloc();
225    }
str() const226    std::basic_string<charT> BOOST_REGEX_CALL str()const
227    {
228       std::basic_string<charT> result;
229       if(this->m_status == 0)
230          result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
231       return result;
232    }
expression() const233    const_iterator BOOST_REGEX_CALL expression()const
234    {
235       return this->m_expression;
236    }
subexpression(std::size_t n) const237    std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
238    {
239       const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);
240       std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);
241       return p;
242    }
243    //
244    // begin, end:
begin() const245    const_iterator BOOST_REGEX_CALL begin()const
246    {
247       return (this->m_status ? 0 : this->m_expression);
248    }
end() const249    const_iterator BOOST_REGEX_CALL end()const
250    {
251       return (this->m_status ? 0 : this->m_expression + this->m_expression_len);
252    }
flags() const253    flag_type BOOST_REGEX_CALL flags()const
254    {
255       return this->m_flags;
256    }
size() const257    size_type BOOST_REGEX_CALL size()const
258    {
259       return this->m_expression_len;
260    }
status() const261    int BOOST_REGEX_CALL status()const
262    {
263       return this->m_status;
264    }
mark_count() const265    size_type BOOST_REGEX_CALL mark_count()const
266    {
267       return this->m_mark_count - 1;
268    }
get_first_state() const269    const re_detail::re_syntax_base* get_first_state()const
270    {
271       return this->m_first_state;
272    }
get_restart_type() const273    unsigned get_restart_type()const
274    {
275       return this->m_restart_type;
276    }
get_map() const277    const unsigned char* get_map()const
278    {
279       return this->m_startmap;
280    }
get_traits() const281    const ::boost::regex_traits_wrapper<traits>& get_traits()const
282    {
283       return *(this->m_ptraits);
284    }
can_be_null() const285    bool can_be_null()const
286    {
287       return this->m_can_be_null;
288    }
get_data() const289    const regex_data<charT, traits>& get_data()const
290    {
291       basic_regex_implementation<charT, traits> const* p = this;
292       return *static_cast<const regex_data<charT, traits>*>(p);
293    }
294 };
295 
296 } // namespace re_detail
297 //
298 // class basic_regex:
299 // represents the compiled
300 // regular expression:
301 //
302 
303 #ifdef BOOST_REGEX_NO_FWD
304 template <class charT, class traits = regex_traits<charT> >
305 #else
306 template <class charT, class traits >
307 #endif
308 class basic_regex : public regbase
309 {
310 public:
311    // typedefs:
312    typedef std::size_t                           traits_size_type;
313    typedef typename traits::string_type          traits_string_type;
314    typedef charT                                 char_type;
315    typedef traits                                traits_type;
316 
317    typedef charT                                 value_type;
318    typedef charT&                                reference;
319    typedef const charT&                          const_reference;
320    typedef const charT*                          const_iterator;
321    typedef const_iterator                        iterator;
322    typedef std::ptrdiff_t                        difference_type;
323    typedef std::size_t                           size_type;
324    typedef regex_constants::syntax_option_type   flag_type;
325    // locale_type
326    // placeholder for actual locale type used by the
327    // traits class to localise *this.
328    typedef typename traits::locale_type          locale_type;
329 
330 public:
basic_regex()331    explicit basic_regex(){}
basic_regex(const charT * p,flag_type f=regex_constants::normal)332    explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
333    {
334       assign(p, f);
335    }
basic_regex(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)336    basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
337    {
338       assign(p1, p2, f);
339    }
basic_regex(const charT * p,size_type len,flag_type f)340    basic_regex(const charT* p, size_type len, flag_type f)
341    {
342       assign(p, len, f);
343    }
basic_regex(const basic_regex & that)344    basic_regex(const basic_regex& that)
345       : m_pimpl(that.m_pimpl) {}
~basic_regex()346    ~basic_regex(){}
operator =(const basic_regex & that)347    basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)
348    {
349       return assign(that);
350    }
operator =(const charT * ptr)351    basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
352    {
353       return assign(ptr);
354    }
355 
356    //
357    // assign:
assign(const basic_regex & that)358    basic_regex& assign(const basic_regex& that)
359    {
360       m_pimpl = that.m_pimpl;
361       return *this;
362    }
assign(const charT * p,flag_type f=regex_constants::normal)363    basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
364    {
365       return assign(p, p + traits::length(p), f);
366    }
assign(const charT * p,size_type len,flag_type f)367    basic_regex& assign(const charT* p, size_type len, flag_type f)
368    {
369       return assign(p, p + len, f);
370    }
371 private:
372    basic_regex& do_assign(const charT* p1,
373                           const charT* p2,
374                           flag_type f);
375 public:
assign(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)376    basic_regex& assign(const charT* p1,
377                           const charT* p2,
378                           flag_type f = regex_constants::normal)
379    {
380       return do_assign(p1, p2, f);
381    }
382 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
383 
384    template <class ST, class SA>
set_expression(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)385    unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
386    {
387       return set_expression(p.data(), p.data() + p.size(), f);
388    }
389 
390    template <class ST, class SA>
basic_regex(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)391    explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
392    {
393       assign(p, f);
394    }
395 
396    template <class InputIterator>
basic_regex(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)397    basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
398    {
399       typedef typename traits::string_type seq_type;
400       seq_type a(arg_first, arg_last);
401       if(a.size())
402          assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);
403       else
404          assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
405    }
406 
407    template <class ST, class SA>
operator =(const std::basic_string<charT,ST,SA> & p)408    basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
409    {
410       return assign(p.data(), p.data() + p.size(), regex_constants::normal);
411    }
412 
413    template <class string_traits, class A>
assign(const std::basic_string<charT,string_traits,A> & s,flag_type f=regex_constants::normal)414    basic_regex& BOOST_REGEX_CALL assign(
415        const std::basic_string<charT, string_traits, A>& s,
416        flag_type f = regex_constants::normal)
417    {
418       return assign(s.data(), s.data() + s.size(), f);
419    }
420 
421    template <class InputIterator>
assign(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)422    basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,
423                           InputIterator arg_last,
424                           flag_type f = regex_constants::normal)
425    {
426       typedef typename traits::string_type seq_type;
427       seq_type a(arg_first, arg_last);
428       if(a.size())
429       {
430          const charT* p1 = &*a.begin();
431          const charT* p2 = &*a.begin() + a.size();
432          return assign(p1, p2, f);
433       }
434       return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
435    }
436 #else
set_expression(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)437    unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
438    {
439       return set_expression(p.data(), p.data() + p.size(), f);
440    }
441 
basic_regex(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)442    basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
443    {
444       assign(p, f);
445    }
446 
operator =(const std::basic_string<charT> & p)447    basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
448    {
449       return assign(p.data(), p.data() + p.size(), regex_constants::normal);
450    }
451 
assign(const std::basic_string<charT> & s,flag_type f=regex_constants::normal)452    basic_regex& BOOST_REGEX_CALL assign(
453        const std::basic_string<charT>& s,
454        flag_type f = regex_constants::normal)
455    {
456       return assign(s.data(), s.data() + s.size(), f);
457    }
458 
459 #endif
460 
461    //
462    // locale:
463    locale_type BOOST_REGEX_CALL imbue(locale_type l);
getloc() const464    locale_type BOOST_REGEX_CALL getloc()const
465    {
466       return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
467    }
468    //
469    // getflags:
470    // retained for backwards compatibility only, "flags"
471    // is now the preferred name:
getflags() const472    flag_type BOOST_REGEX_CALL getflags()const
473    {
474       return flags();
475    }
flags() const476    flag_type BOOST_REGEX_CALL flags()const
477    {
478       return m_pimpl.get() ? m_pimpl->flags() : 0;
479    }
480    //
481    // str:
str() const482    std::basic_string<charT> BOOST_REGEX_CALL str()const
483    {
484       return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
485    }
486    //
487    // begin, end, subexpression:
subexpression(std::size_t n) const488    std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
489    {
490       if(!m_pimpl.get())
491          boost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));
492       return m_pimpl->subexpression(n);
493    }
begin() const494    const_iterator BOOST_REGEX_CALL begin()const
495    {
496       return (m_pimpl.get() ? m_pimpl->begin() : 0);
497    }
end() const498    const_iterator BOOST_REGEX_CALL end()const
499    {
500       return (m_pimpl.get() ? m_pimpl->end() : 0);
501    }
502    //
503    // swap:
swap(basic_regex & that)504    void BOOST_REGEX_CALL swap(basic_regex& that)throw()
505    {
506       m_pimpl.swap(that.m_pimpl);
507    }
508    //
509    // size:
size() const510    size_type BOOST_REGEX_CALL size()const
511    {
512       return (m_pimpl.get() ? m_pimpl->size() : 0);
513    }
514    //
515    // max_size:
max_size() const516    size_type BOOST_REGEX_CALL max_size()const
517    {
518       return UINT_MAX;
519    }
520    //
521    // empty:
empty() const522    bool BOOST_REGEX_CALL empty()const
523    {
524       return (m_pimpl.get() ? 0 != m_pimpl->status() : true);
525    }
526 
mark_count() const527    size_type BOOST_REGEX_CALL mark_count()const
528    {
529       return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
530    }
531 
status() const532    int status()const
533    {
534       return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
535    }
536 
compare(const basic_regex & that) const537    int BOOST_REGEX_CALL compare(const basic_regex& that) const
538    {
539       if(m_pimpl.get() == that.m_pimpl.get())
540          return 0;
541       if(!m_pimpl.get())
542          return -1;
543       if(!that.m_pimpl.get())
544          return 1;
545       if(status() != that.status())
546          return status() - that.status();
547       if(flags() != that.flags())
548          return flags() - that.flags();
549       return str().compare(that.str());
550    }
operator ==(const basic_regex & e) const551    bool BOOST_REGEX_CALL operator==(const basic_regex& e)const
552    {
553       return compare(e) == 0;
554    }
operator !=(const basic_regex & e) const555    bool BOOST_REGEX_CALL operator != (const basic_regex& e)const
556    {
557       return compare(e) != 0;
558    }
operator <(const basic_regex & e) const559    bool BOOST_REGEX_CALL operator<(const basic_regex& e)const
560    {
561       return compare(e) < 0;
562    }
operator >(const basic_regex & e) const563    bool BOOST_REGEX_CALL operator>(const basic_regex& e)const
564    {
565       return compare(e) > 0;
566    }
operator <=(const basic_regex & e) const567    bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const
568    {
569       return compare(e) <= 0;
570    }
operator >=(const basic_regex & e) const571    bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const
572    {
573       return compare(e) >= 0;
574    }
575 
576    //
577    // The following are deprecated as public interfaces
578    // but are available for compatibility with earlier versions.
expression() const579    const charT* BOOST_REGEX_CALL expression()const
580    {
581       return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
582    }
set_expression(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)583    unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
584    {
585       assign(p1, p2, f | regex_constants::no_except);
586       return status();
587    }
set_expression(const charT * p,flag_type f=regex_constants::normal)588    unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal)
589    {
590       assign(p, f | regex_constants::no_except);
591       return status();
592    }
error_code() const593    unsigned int BOOST_REGEX_CALL error_code()const
594    {
595       return status();
596    }
597    //
598    // private access methods:
599    //
get_first_state() const600    const re_detail::re_syntax_base* get_first_state()const
601    {
602       BOOST_ASSERT(0 != m_pimpl.get());
603       return m_pimpl->get_first_state();
604    }
get_restart_type() const605    unsigned get_restart_type()const
606    {
607       BOOST_ASSERT(0 != m_pimpl.get());
608       return m_pimpl->get_restart_type();
609    }
get_map() const610    const unsigned char* get_map()const
611    {
612       BOOST_ASSERT(0 != m_pimpl.get());
613       return m_pimpl->get_map();
614    }
get_traits() const615    const ::boost::regex_traits_wrapper<traits>& get_traits()const
616    {
617       BOOST_ASSERT(0 != m_pimpl.get());
618       return m_pimpl->get_traits();
619    }
can_be_null() const620    bool can_be_null()const
621    {
622       BOOST_ASSERT(0 != m_pimpl.get());
623       return m_pimpl->can_be_null();
624    }
get_data() const625    const re_detail::regex_data<charT, traits>& get_data()const
626    {
627       BOOST_ASSERT(0 != m_pimpl.get());
628       return m_pimpl->get_data();
629    }
get_named_subs() const630    boost::shared_ptr<re_detail::named_subexpressions > get_named_subs()const
631    {
632       return m_pimpl;
633    }
634 
635 private:
636    shared_ptr<re_detail::basic_regex_implementation<charT, traits> > m_pimpl;
637 };
638 
639 //
640 // out of line members;
641 // these are the only members that mutate the basic_regex object,
642 // and are designed to provide the strong exception guarentee
643 // (in the event of a throw, the state of the object remains unchanged).
644 //
645 template <class charT, class traits>
do_assign(const charT * p1,const charT * p2,flag_type f)646 basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
647                         const charT* p2,
648                         flag_type f)
649 {
650    shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp;
651    if(!m_pimpl.get())
652    {
653       temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
654    }
655    else
656    {
657       temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
658    }
659    temp->assign(p1, p2, f);
660    temp.swap(m_pimpl);
661    return *this;
662 }
663 
664 template <class charT, class traits>
imbue(locale_type l)665 typename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)
666 {
667    shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp(new re_detail::basic_regex_implementation<charT, traits>());
668    locale_type result = temp->imbue(l);
669    temp.swap(m_pimpl);
670    return result;
671 }
672 
673 //
674 // non-members:
675 //
676 template <class charT, class traits>
swap(basic_regex<charT,traits> & e1,basic_regex<charT,traits> & e2)677 void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
678 {
679    e1.swap(e2);
680 }
681 
682 #ifndef BOOST_NO_STD_LOCALE
683 template <class charT, class traits, class traits2>
684 std::basic_ostream<charT, traits>&
operator <<(std::basic_ostream<charT,traits> & os,const basic_regex<charT,traits2> & e)685    operator << (std::basic_ostream<charT, traits>& os,
686                 const basic_regex<charT, traits2>& e)
687 {
688    return (os << e.str());
689 }
690 #else
691 template <class traits>
operator <<(std::ostream & os,const basic_regex<char,traits> & e)692 std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)
693 {
694    return (os << e.str());
695 }
696 #endif
697 
698 //
699 // class reg_expression:
700 // this is provided for backwards compatibility only,
701 // it is deprecated, no not use!
702 //
703 #ifdef BOOST_REGEX_NO_FWD
704 template <class charT, class traits = regex_traits<charT> >
705 #else
706 template <class charT, class traits >
707 #endif
708 class reg_expression : public basic_regex<charT, traits>
709 {
710 public:
711    typedef typename basic_regex<charT, traits>::flag_type flag_type;
712    typedef typename basic_regex<charT, traits>::size_type size_type;
reg_expression()713    explicit reg_expression(){}
reg_expression(const charT * p,flag_type f=regex_constants::normal)714    explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
715       : basic_regex<charT, traits>(p, f){}
reg_expression(const charT * p1,const charT * p2,flag_type f=regex_constants::normal)716    reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
717       : basic_regex<charT, traits>(p1, p2, f){}
reg_expression(const charT * p,size_type len,flag_type f)718    reg_expression(const charT* p, size_type len, flag_type f)
719       : basic_regex<charT, traits>(p, len, f){}
reg_expression(const reg_expression & that)720    reg_expression(const reg_expression& that)
721       : basic_regex<charT, traits>(that) {}
~reg_expression()722    ~reg_expression(){}
operator =(const reg_expression & that)723    reg_expression& BOOST_REGEX_CALL operator=(const reg_expression& that)
724    {
725       return this->assign(that);
726    }
727 
728 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
729    template <class ST, class SA>
reg_expression(const std::basic_string<charT,ST,SA> & p,flag_type f=regex_constants::normal)730    explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
731    : basic_regex<charT, traits>(p, f)
732    {
733    }
734 
735    template <class InputIterator>
reg_expression(InputIterator arg_first,InputIterator arg_last,flag_type f=regex_constants::normal)736    reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
737    : basic_regex<charT, traits>(arg_first, arg_last, f)
738    {
739    }
740 
741    template <class ST, class SA>
operator =(const std::basic_string<charT,ST,SA> & p)742    reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
743    {
744       this->assign(p);
745       return *this;
746    }
747 #else
reg_expression(const std::basic_string<charT> & p,flag_type f=regex_constants::normal)748    explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
749    : basic_regex<charT, traits>(p, f)
750    {
751    }
752 
operator =(const std::basic_string<charT> & p)753    reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
754    {
755       this->assign(p);
756       return *this;
757    }
758 #endif
759 
760 };
761 
762 #ifdef BOOST_MSVC
763 #pragma warning (pop)
764 #endif
765 
766 } // namespace boost
767 
768 #ifdef BOOST_MSVC
769 #pragma warning(push)
770 #pragma warning(disable: 4103)
771 #endif
772 #ifdef BOOST_HAS_ABI_HEADERS
773 #  include BOOST_ABI_SUFFIX
774 #endif
775 #ifdef BOOST_MSVC
776 #pragma warning(pop)
777 #endif
778 
779 #endif
780 
781