basic_regex.hpp 23 KB

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