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