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