basic_regex.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  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. static const int hash_value_mask = 1 << (std::numeric_limits<int>::digits - 1);
  65. template <class Iterator>
  66. inline int hash_value_from_capture_name(Iterator i, Iterator j)
  67. {
  68. std::size_t r = boost::hash_range(i, j);
  69. r %= ((std::numeric_limits<int>::max)());
  70. return static_cast<int>(r) | hash_value_mask;
  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_flags(0), m_status(0), m_expression(0), m_expression_len(0),
  159. m_mark_count(0), m_first_state(0), m_restart_type(0),
  160. #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !(defined(BOOST_MSVC) && (BOOST_MSVC < 1900))
  161. m_startmap{ 0 },
  162. #endif
  163. m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
  164. regex_data()
  165. : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),
  166. m_mark_count(0), m_first_state(0), m_restart_type(0),
  167. #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !(defined(BOOST_MSVC) && (BOOST_MSVC < 1900))
  168. m_startmap{ 0 },
  169. #endif
  170. m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
  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. BOOST_REGEX_DETAIL_NS::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. BOOST_REGEX_DETAIL_NS::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. bool m_disable_match_any; // when set we need to disable the match_any flag as it causes different/buggy behaviour.
  190. };
  191. //
  192. // class basic_regex_implementation
  193. // pimpl implementation class for basic_regex.
  194. //
  195. template <class charT, class traits>
  196. class basic_regex_implementation
  197. : public regex_data<charT, traits>
  198. {
  199. public:
  200. typedef regex_constants::syntax_option_type flag_type;
  201. typedef std::ptrdiff_t difference_type;
  202. typedef std::size_t size_type;
  203. typedef typename traits::locale_type locale_type;
  204. typedef const charT* const_iterator;
  205. basic_regex_implementation(){}
  206. basic_regex_implementation(const ::boost::shared_ptr<
  207. ::boost::regex_traits_wrapper<traits> >& t)
  208. : regex_data<charT, traits>(t) {}
  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. locale_type BOOST_REGEX_CALL imbue(locale_type l)
  218. {
  219. return this->m_ptraits->imbue(l);
  220. }
  221. locale_type BOOST_REGEX_CALL getloc()const
  222. {
  223. return this->m_ptraits->getloc();
  224. }
  225. std::basic_string<charT> BOOST_REGEX_CALL str()const
  226. {
  227. std::basic_string<charT> result;
  228. if(this->m_status == 0)
  229. result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
  230. return result;
  231. }
  232. const_iterator BOOST_REGEX_CALL expression()const
  233. {
  234. return this->m_expression;
  235. }
  236. std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
  237. {
  238. const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);
  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 - 1;
  267. }
  268. const BOOST_REGEX_DETAIL_NS::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. } // namespace BOOST_REGEX_DETAIL_NS
  295. //
  296. // class basic_regex:
  297. // represents the compiled
  298. // regular expression:
  299. //
  300. #ifdef BOOST_REGEX_NO_FWD
  301. template <class charT, class traits = regex_traits<charT> >
  302. #else
  303. template <class charT, class traits >
  304. #endif
  305. class basic_regex : public regbase
  306. {
  307. public:
  308. // typedefs:
  309. typedef std::size_t traits_size_type;
  310. typedef typename traits::string_type traits_string_type;
  311. typedef charT char_type;
  312. typedef traits traits_type;
  313. typedef charT value_type;
  314. typedef charT& reference;
  315. typedef const charT& const_reference;
  316. typedef const charT* const_iterator;
  317. typedef const_iterator iterator;
  318. typedef std::ptrdiff_t difference_type;
  319. typedef std::size_t size_type;
  320. typedef regex_constants::syntax_option_type flag_type;
  321. // locale_type
  322. // placeholder for actual locale type used by the
  323. // traits class to localise *this.
  324. typedef typename traits::locale_type locale_type;
  325. public:
  326. explicit basic_regex(){}
  327. explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
  328. {
  329. assign(p, f);
  330. }
  331. basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
  332. {
  333. assign(p1, p2, f);
  334. }
  335. basic_regex(const charT* p, size_type len, flag_type f)
  336. {
  337. assign(p, len, f);
  338. }
  339. basic_regex(const basic_regex& that)
  340. : m_pimpl(that.m_pimpl) {}
  341. ~basic_regex(){}
  342. basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)
  343. {
  344. return assign(that);
  345. }
  346. basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
  347. {
  348. return assign(ptr);
  349. }
  350. //
  351. // assign:
  352. basic_regex& assign(const basic_regex& that)
  353. {
  354. m_pimpl = that.m_pimpl;
  355. return *this;
  356. }
  357. basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
  358. {
  359. return assign(p, p + traits::length(p), f);
  360. }
  361. basic_regex& assign(const charT* p, size_type len, flag_type f)
  362. {
  363. return assign(p, p + len, f);
  364. }
  365. private:
  366. basic_regex& do_assign(const charT* p1,
  367. const charT* p2,
  368. flag_type f);
  369. public:
  370. basic_regex& assign(const charT* p1,
  371. const charT* p2,
  372. flag_type f = regex_constants::normal)
  373. {
  374. return do_assign(p1, p2, f);
  375. }
  376. #if !defined(BOOST_NO_MEMBER_TEMPLATES)
  377. template <class ST, class SA>
  378. unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
  379. {
  380. return set_expression(p.data(), p.data() + p.size(), f);
  381. }
  382. template <class ST, class SA>
  383. explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
  384. {
  385. assign(p, f);
  386. }
  387. template <class InputIterator>
  388. basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
  389. {
  390. typedef typename traits::string_type seq_type;
  391. seq_type a(arg_first, arg_last);
  392. if(!a.empty())
  393. assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);
  394. else
  395. assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
  396. }
  397. template <class ST, class SA>
  398. basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
  399. {
  400. return assign(p.data(), p.data() + p.size(), regex_constants::normal);
  401. }
  402. template <class string_traits, class A>
  403. basic_regex& BOOST_REGEX_CALL assign(
  404. const std::basic_string<charT, string_traits, A>& s,
  405. flag_type f = regex_constants::normal)
  406. {
  407. return assign(s.data(), s.data() + s.size(), f);
  408. }
  409. template <class InputIterator>
  410. basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,
  411. InputIterator arg_last,
  412. flag_type f = regex_constants::normal)
  413. {
  414. typedef typename traits::string_type seq_type;
  415. seq_type a(arg_first, arg_last);
  416. if(a.size())
  417. {
  418. const charT* p1 = &*a.begin();
  419. const charT* p2 = &*a.begin() + a.size();
  420. return assign(p1, p2, f);
  421. }
  422. return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
  423. }
  424. #else
  425. unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
  426. {
  427. return set_expression(p.data(), p.data() + p.size(), f);
  428. }
  429. basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
  430. {
  431. assign(p, f);
  432. }
  433. basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
  434. {
  435. return assign(p.data(), p.data() + p.size(), regex_constants::normal);
  436. }
  437. basic_regex& BOOST_REGEX_CALL assign(
  438. const std::basic_string<charT>& s,
  439. flag_type f = regex_constants::normal)
  440. {
  441. return assign(s.data(), s.data() + s.size(), f);
  442. }
  443. #endif
  444. //
  445. // locale:
  446. locale_type BOOST_REGEX_CALL imbue(locale_type l);
  447. locale_type BOOST_REGEX_CALL getloc()const
  448. {
  449. return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
  450. }
  451. //
  452. // getflags:
  453. // retained for backwards compatibility only, "flags"
  454. // is now the preferred name:
  455. flag_type BOOST_REGEX_CALL getflags()const
  456. {
  457. return flags();
  458. }
  459. flag_type BOOST_REGEX_CALL flags()const
  460. {
  461. return m_pimpl.get() ? m_pimpl->flags() : 0;
  462. }
  463. //
  464. // str:
  465. std::basic_string<charT> BOOST_REGEX_CALL str()const
  466. {
  467. return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
  468. }
  469. //
  470. // begin, end, subexpression:
  471. std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
  472. {
  473. if(!m_pimpl.get())
  474. boost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));
  475. return m_pimpl->subexpression(n);
  476. }
  477. const_iterator BOOST_REGEX_CALL begin()const
  478. {
  479. return (m_pimpl.get() ? m_pimpl->begin() : 0);
  480. }
  481. const_iterator BOOST_REGEX_CALL end()const
  482. {
  483. return (m_pimpl.get() ? m_pimpl->end() : 0);
  484. }
  485. //
  486. // swap:
  487. void BOOST_REGEX_CALL swap(basic_regex& that)throw()
  488. {
  489. m_pimpl.swap(that.m_pimpl);
  490. }
  491. //
  492. // size:
  493. size_type BOOST_REGEX_CALL size()const
  494. {
  495. return (m_pimpl.get() ? m_pimpl->size() : 0);
  496. }
  497. //
  498. // max_size:
  499. size_type BOOST_REGEX_CALL max_size()const
  500. {
  501. return UINT_MAX;
  502. }
  503. //
  504. // empty:
  505. bool BOOST_REGEX_CALL empty()const
  506. {
  507. return (m_pimpl.get() ? 0 != m_pimpl->status() : true);
  508. }
  509. size_type BOOST_REGEX_CALL mark_count()const
  510. {
  511. return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
  512. }
  513. int status()const
  514. {
  515. return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
  516. }
  517. int BOOST_REGEX_CALL compare(const basic_regex& that) const
  518. {
  519. if(m_pimpl.get() == that.m_pimpl.get())
  520. return 0;
  521. if(!m_pimpl.get())
  522. return -1;
  523. if(!that.m_pimpl.get())
  524. return 1;
  525. if(status() != that.status())
  526. return status() - that.status();
  527. if(flags() != that.flags())
  528. return flags() - that.flags();
  529. return str().compare(that.str());
  530. }
  531. bool BOOST_REGEX_CALL operator==(const basic_regex& e)const
  532. {
  533. return compare(e) == 0;
  534. }
  535. bool BOOST_REGEX_CALL operator != (const basic_regex& e)const
  536. {
  537. return compare(e) != 0;
  538. }
  539. bool BOOST_REGEX_CALL operator<(const basic_regex& e)const
  540. {
  541. return compare(e) < 0;
  542. }
  543. bool BOOST_REGEX_CALL operator>(const basic_regex& e)const
  544. {
  545. return compare(e) > 0;
  546. }
  547. bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const
  548. {
  549. return compare(e) <= 0;
  550. }
  551. bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const
  552. {
  553. return compare(e) >= 0;
  554. }
  555. //
  556. // The following are deprecated as public interfaces
  557. // but are available for compatibility with earlier versions.
  558. const charT* BOOST_REGEX_CALL expression()const
  559. {
  560. return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
  561. }
  562. unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
  563. {
  564. assign(p1, p2, f | regex_constants::no_except);
  565. return status();
  566. }
  567. unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal)
  568. {
  569. assign(p, f | regex_constants::no_except);
  570. return status();
  571. }
  572. unsigned int BOOST_REGEX_CALL error_code()const
  573. {
  574. return status();
  575. }
  576. //
  577. // private access methods:
  578. //
  579. const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
  580. {
  581. BOOST_REGEX_ASSERT(0 != m_pimpl.get());
  582. return m_pimpl->get_first_state();
  583. }
  584. unsigned get_restart_type()const
  585. {
  586. BOOST_REGEX_ASSERT(0 != m_pimpl.get());
  587. return m_pimpl->get_restart_type();
  588. }
  589. const unsigned char* get_map()const
  590. {
  591. BOOST_REGEX_ASSERT(0 != m_pimpl.get());
  592. return m_pimpl->get_map();
  593. }
  594. const ::boost::regex_traits_wrapper<traits>& get_traits()const
  595. {
  596. BOOST_REGEX_ASSERT(0 != m_pimpl.get());
  597. return m_pimpl->get_traits();
  598. }
  599. bool can_be_null()const
  600. {
  601. BOOST_REGEX_ASSERT(0 != m_pimpl.get());
  602. return m_pimpl->can_be_null();
  603. }
  604. const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const
  605. {
  606. BOOST_REGEX_ASSERT(0 != m_pimpl.get());
  607. return m_pimpl->get_data();
  608. }
  609. boost::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const
  610. {
  611. return m_pimpl;
  612. }
  613. private:
  614. shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;
  615. };
  616. //
  617. // out of line members;
  618. // these are the only members that mutate the basic_regex object,
  619. // and are designed to provide the strong exception guarantee
  620. // (in the event of a throw, the state of the object remains unchanged).
  621. //
  622. template <class charT, class traits>
  623. basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
  624. const charT* p2,
  625. flag_type f)
  626. {
  627. shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;
  628. if(!m_pimpl.get())
  629. {
  630. temp = shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
  631. }
  632. else
  633. {
  634. 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));
  635. }
  636. temp->assign(p1, p2, f);
  637. temp.swap(m_pimpl);
  638. return *this;
  639. }
  640. template <class charT, class traits>
  641. typename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)
  642. {
  643. shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
  644. locale_type result = temp->imbue(l);
  645. temp.swap(m_pimpl);
  646. return result;
  647. }
  648. //
  649. // non-members:
  650. //
  651. template <class charT, class traits>
  652. void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
  653. {
  654. e1.swap(e2);
  655. }
  656. #ifndef BOOST_NO_STD_LOCALE
  657. template <class charT, class traits, class traits2>
  658. std::basic_ostream<charT, traits>&
  659. operator << (std::basic_ostream<charT, traits>& os,
  660. const basic_regex<charT, traits2>& e)
  661. {
  662. return (os << e.str());
  663. }
  664. #else
  665. template <class traits>
  666. std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)
  667. {
  668. return (os << e.str());
  669. }
  670. #endif
  671. //
  672. // class reg_expression:
  673. // this is provided for backwards compatibility only,
  674. // it is deprecated, no not use!
  675. //
  676. #ifdef BOOST_REGEX_NO_FWD
  677. template <class charT, class traits = regex_traits<charT> >
  678. #else
  679. template <class charT, class traits >
  680. #endif
  681. class reg_expression : public basic_regex<charT, traits>
  682. {
  683. public:
  684. typedef typename basic_regex<charT, traits>::flag_type flag_type;
  685. typedef typename basic_regex<charT, traits>::size_type size_type;
  686. explicit reg_expression(){}
  687. explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
  688. : basic_regex<charT, traits>(p, f){}
  689. reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
  690. : basic_regex<charT, traits>(p1, p2, f){}
  691. reg_expression(const charT* p, size_type len, flag_type f)
  692. : basic_regex<charT, traits>(p, len, f){}
  693. reg_expression(const reg_expression& that)
  694. : basic_regex<charT, traits>(that) {}
  695. ~reg_expression(){}
  696. reg_expression& BOOST_REGEX_CALL operator=(const reg_expression& that)
  697. {
  698. return this->assign(that);
  699. }
  700. #if !defined(BOOST_NO_MEMBER_TEMPLATES)
  701. template <class ST, class SA>
  702. explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
  703. : basic_regex<charT, traits>(p, f)
  704. {
  705. }
  706. template <class InputIterator>
  707. reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
  708. : basic_regex<charT, traits>(arg_first, arg_last, f)
  709. {
  710. }
  711. template <class ST, class SA>
  712. reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
  713. {
  714. this->assign(p);
  715. return *this;
  716. }
  717. #else
  718. explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
  719. : basic_regex<charT, traits>(p, f)
  720. {
  721. }
  722. reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
  723. {
  724. this->assign(p);
  725. return *this;
  726. }
  727. #endif
  728. };
  729. #ifdef BOOST_MSVC
  730. #pragma warning (pop)
  731. #endif
  732. } // namespace boost
  733. #ifdef BOOST_MSVC
  734. #pragma warning(push)
  735. #pragma warning(disable: 4103)
  736. #endif
  737. #ifdef BOOST_HAS_ABI_HEADERS
  738. # include BOOST_ABI_SUFFIX
  739. #endif
  740. #ifdef BOOST_MSVC
  741. #pragma warning(pop)
  742. #endif
  743. #endif