basic_regex.hpp 23 KB

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