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