match_results.hpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398
  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file match_results.hpp
  3. /// Contains the definition of the match_results type and associated helpers.
  4. /// The match_results type holds the results of a regex_match() or
  5. /// regex_search() operation.
  6. //
  7. // Copyright 2008 Eric Niebler. Distributed under the Boost
  8. // Software License, Version 1.0. (See accompanying file
  9. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Acknowledgements: Thanks to Markus Schoepflin for helping to track down
  12. // a tricky formatting bug on HP Tru64, and to Steven Watanabe for suggesting
  13. // the fix.
  14. #ifndef BOOST_XPRESSIVE_MATCH_RESULTS_HPP_EAN_10_04_2005
  15. #define BOOST_XPRESSIVE_MATCH_RESULTS_HPP_EAN_10_04_2005
  16. // MS compatible compilers support #pragma once
  17. #if defined(_MSC_VER)
  18. # pragma once
  19. #endif
  20. #include <map>
  21. #include <string>
  22. #include <vector>
  23. #include <utility>
  24. #include <iterator>
  25. #include <typeinfo>
  26. #include <algorithm>
  27. #include <boost/config.hpp>
  28. #include <boost/assert.hpp>
  29. #include <boost/integer.hpp>
  30. #include <boost/mpl/if.hpp>
  31. #include <boost/mpl/not.hpp>
  32. #include <boost/mpl/size_t.hpp>
  33. #include <boost/mpl/assert.hpp>
  34. #include <boost/intrusive_ptr.hpp>
  35. #include <boost/throw_exception.hpp>
  36. #include <boost/iterator_adaptors.hpp>
  37. #include <boost/utility/enable_if.hpp>
  38. #include <boost/detail/workaround.hpp>
  39. #include <boost/numeric/conversion/converter.hpp>
  40. #include <boost/optional.hpp>
  41. #include <boost/range/end.hpp>
  42. #include <boost/range/begin.hpp>
  43. #include <boost/range/as_literal.hpp>
  44. #include <boost/range/const_iterator.hpp>
  45. #include <boost/type_traits/is_function.hpp>
  46. #if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
  47. # include <boost/iterator/filter_iterator.hpp>
  48. #endif
  49. #include <boost/xpressive/regex_constants.hpp>
  50. #include <boost/xpressive/detail/detail_fwd.hpp>
  51. #include <boost/xpressive/detail/core/regex_impl.hpp>
  52. #include <boost/xpressive/detail/core/sub_match_vector.hpp>
  53. #include <boost/xpressive/detail/utility/sequence_stack.hpp>
  54. #include <boost/xpressive/detail/core/results_cache.hpp>
  55. #include <boost/xpressive/detail/utility/literals.hpp>
  56. #include <boost/xpressive/detail/utility/algorithm.hpp>
  57. #include <boost/xpressive/detail/utility/counted_base.hpp>
  58. // Doxygen can't handle proto :-(
  59. #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
  60. # include <boost/proto/proto_fwd.hpp>
  61. # include <boost/proto/traits.hpp>
  62. #endif
  63. namespace boost { namespace xpressive { namespace detail
  64. {
  65. ///////////////////////////////////////////////////////////////////////////////
  66. // type_info_less
  67. //
  68. struct type_info_less
  69. {
  70. bool operator()(std::type_info const *left, std::type_info const *right) const
  71. {
  72. return 0 != left->before(*right);
  73. }
  74. };
  75. ///////////////////////////////////////////////////////////////////////////////
  76. // ActionArgBinding
  77. //
  78. struct ActionArgBinding
  79. : proto::assign<proto::terminal<action_arg<proto::_, proto::_> >, proto::terminal<proto::_> >
  80. {
  81. };
  82. ///////////////////////////////////////////////////////////////////////////////
  83. // results_extras
  84. //
  85. template<typename BidiIter>
  86. struct results_extras
  87. : counted_base<results_extras<BidiIter> >
  88. {
  89. sequence_stack<sub_match_impl<BidiIter> > sub_match_stack_;
  90. results_cache<BidiIter> results_cache_;
  91. };
  92. ///////////////////////////////////////////////////////////////////////////////
  93. // char_overflow_handler_
  94. //
  95. struct char_overflow_handler_
  96. {
  97. void operator ()(numeric::range_check_result result) const // throw(regex_error)
  98. {
  99. if(numeric::cInRange != result)
  100. {
  101. BOOST_THROW_EXCEPTION(
  102. regex_error(
  103. regex_constants::error_escape
  104. , "character escape too large to fit in target character type"
  105. )
  106. );
  107. }
  108. }
  109. };
  110. ///////////////////////////////////////////////////////////////////////////////
  111. // transform_op enum
  112. //
  113. enum transform_op { op_none = 0, op_upper = 1, op_lower = 2 };
  114. enum transform_scope { scope_next = 0, scope_rest = 1 };
  115. ///////////////////////////////////////////////////////////////////////////////
  116. // case_converting_iterator
  117. //
  118. template<typename OutputIterator, typename Char>
  119. struct case_converting_iterator
  120. : std::iterator<std::output_iterator_tag, Char, void, void, case_converting_iterator<OutputIterator, Char> >
  121. {
  122. case_converting_iterator(OutputIterator const &out, traits<Char> const *tr)
  123. : out_(out)
  124. , traits_(tr)
  125. , next_(op_none)
  126. , rest_(op_none)
  127. {}
  128. OutputIterator base() const
  129. {
  130. return this->out_;
  131. }
  132. case_converting_iterator &operator ++()
  133. {
  134. ++this->out_;
  135. this->next_ = op_none;
  136. return *this;
  137. }
  138. case_converting_iterator operator ++(int)
  139. {
  140. case_converting_iterator tmp(*this);
  141. ++*this;
  142. return tmp;
  143. }
  144. case_converting_iterator &operator *()
  145. {
  146. return *this;
  147. }
  148. friend bool set_transform(case_converting_iterator &iter, transform_op trans, transform_scope scope)
  149. {
  150. BOOST_ASSERT(scope == scope_next || scope == scope_rest);
  151. if(scope == scope_next)
  152. iter.next_ = trans;
  153. else
  154. iter.rest_ = trans;
  155. return true;
  156. }
  157. case_converting_iterator &operator =(Char ch)
  158. {
  159. switch(this->next_ ? this->next_ : this->rest_)
  160. {
  161. case op_lower:
  162. ch = this->traits_->tolower(ch);
  163. break;
  164. case op_upper:
  165. ch = this->traits_->toupper(ch);
  166. break;
  167. default:;
  168. }
  169. *this->out_ = ch;
  170. return *this;
  171. }
  172. private:
  173. OutputIterator out_;
  174. traits<Char> const *traits_;
  175. transform_op next_, rest_;
  176. };
  177. template<typename Iterator>
  178. inline bool set_transform(Iterator &, transform_op, transform_scope)
  179. {
  180. return false;
  181. }
  182. ///////////////////////////////////////////////////////////////////////////////
  183. // noop_output_iterator
  184. //
  185. template<typename Char>
  186. struct noop_output_iterator
  187. : std::iterator<std::output_iterator_tag, Char, void, void, noop_output_iterator<Char> >
  188. {
  189. noop_output_iterator &operator ++()
  190. {
  191. return *this;
  192. }
  193. noop_output_iterator &operator ++(int)
  194. {
  195. return *this;
  196. }
  197. noop_output_iterator &operator *()
  198. {
  199. return *this;
  200. }
  201. noop_output_iterator &operator =(Char const &)
  202. {
  203. return *this;
  204. }
  205. };
  206. struct any_type { any_type(...); };
  207. typedef char no_type;
  208. typedef char (&unary_type)[2];
  209. typedef char (&binary_type)[3];
  210. typedef char (&ternary_type)[4];
  211. no_type check_is_formatter(unary_type, binary_type, ternary_type);
  212. template<typename T>
  213. unary_type check_is_formatter(T const &, binary_type, ternary_type);
  214. template<typename T>
  215. binary_type check_is_formatter(unary_type, T const &, ternary_type);
  216. template<typename T, typename U>
  217. binary_type check_is_formatter(T const &, U const &, ternary_type);
  218. template<typename T>
  219. ternary_type check_is_formatter(unary_type, binary_type, T const &);
  220. template<typename T, typename U>
  221. ternary_type check_is_formatter(T const &, binary_type, U const &);
  222. template<typename T, typename U>
  223. ternary_type check_is_formatter(unary_type, T const &, U const &);
  224. template<typename T, typename U, typename V>
  225. ternary_type check_is_formatter(T const &, U const &, V const &);
  226. struct unary_binary_ternary
  227. {
  228. typedef unary_type (*unary_fun)(any_type);
  229. typedef binary_type (*binary_fun)(any_type, any_type);
  230. typedef ternary_type (*ternary_fun)(any_type, any_type, any_type);
  231. operator unary_fun();
  232. operator binary_fun();
  233. operator ternary_fun();
  234. };
  235. template<typename Formatter, bool IsFunction = is_function<Formatter>::value>
  236. struct formatter_wrapper
  237. : Formatter
  238. , unary_binary_ternary
  239. {
  240. formatter_wrapper();
  241. };
  242. template<typename Formatter>
  243. struct formatter_wrapper<Formatter, true>
  244. : unary_binary_ternary
  245. {
  246. operator Formatter *();
  247. };
  248. template<typename Formatter>
  249. struct formatter_wrapper<Formatter *, false>
  250. : unary_binary_ternary
  251. {
  252. operator Formatter *();
  253. };
  254. template<typename Formatter, typename What, typename Out, typename Void = void>
  255. struct formatter_arity
  256. {
  257. static formatter_wrapper<Formatter> &formatter;
  258. static What &what;
  259. static Out &out;
  260. BOOST_STATIC_CONSTANT(
  261. std::size_t
  262. , value = sizeof(
  263. check_is_formatter(
  264. formatter(what)
  265. , formatter(what, out)
  266. , formatter(what, out, regex_constants::format_default)
  267. )
  268. ) - 1
  269. );
  270. typedef mpl::size_t<value> type;
  271. };
  272. template<typename Formatter, typename What, typename Out>
  273. struct formatter_arity<Formatter, What, Out, typename Formatter::proto_is_expr_>
  274. : mpl::size_t<4>
  275. {};
  276. template<typename T>
  277. struct is_char_ptr
  278. : mpl::false_
  279. {};
  280. template<typename T>
  281. struct is_char_ptr<T *>
  282. : mpl::not_<is_function<T> >
  283. {};
  284. #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
  285. // work around gcc-4.0.1 compiler bug wrt function references
  286. template<typename T>
  287. typename mpl::if_<is_function<T>, T *, T const &>::type
  288. as_callable(T const &t)
  289. {
  290. return t;
  291. }
  292. #endif
  293. } // detail
  294. ///////////////////////////////////////////////////////////////////////////////
  295. // match_results
  296. /// \brief Class template match_results\<\> holds the results of a regex_match() or a
  297. /// regex_search() as a collection of sub_match objects.
  298. ///
  299. /// Class template match_results\<\> denotes a collection of sequences representing the result of
  300. /// a regular expression match. Storage for the collection is allocated and freed as necessary by
  301. /// the member functions of class match_results\<\>.
  302. ///
  303. /// The class template match_results\<\> conforms to the requirements of a Sequence, as specified
  304. /// in (lib.sequence.reqmts), except that only operations defined for const-qualified Sequences are
  305. /// supported.
  306. template<typename BidiIter>
  307. struct match_results
  308. {
  309. private:
  310. /// INTERNAL ONLY
  311. ///
  312. struct dummy { int i_; };
  313. typedef int dummy::*bool_type;
  314. public:
  315. typedef typename iterator_value<BidiIter>::type char_type;
  316. typedef typename detail::string_type<char_type>::type string_type;
  317. typedef std::size_t size_type;
  318. typedef sub_match<BidiIter> value_type;
  319. typedef typename iterator_difference<BidiIter>::type difference_type;
  320. typedef value_type const &reference;
  321. typedef value_type const &const_reference;
  322. typedef typename detail::sub_match_vector<BidiIter>::iterator iterator;
  323. typedef typename detail::sub_match_vector<BidiIter>::const_iterator const_iterator;
  324. typedef typename detail::nested_results<BidiIter> nested_results_type;
  325. /// \post regex_id() == 0
  326. /// \post size() == 0
  327. /// \post empty() == true
  328. /// \post str() == string_type()
  329. match_results()
  330. : regex_id_(0)
  331. , sub_matches_()
  332. , base_()
  333. , prefix_()
  334. , suffix_()
  335. , nested_results_()
  336. , extras_ptr_()
  337. , traits_()
  338. , args_()
  339. , named_marks_()
  340. {
  341. }
  342. /// \param that The match_results object to copy
  343. /// \post regex_id() == that.regex_id().
  344. /// \post size() == that.size().
  345. /// \post empty() == that.empty().
  346. /// \post str(n) == that.str(n) for all positive integers n \< that.size().
  347. /// \post prefix() == that.prefix().
  348. /// \post suffix() == that.suffix().
  349. /// \post (*this)[n] == that[n] for all positive integers n \< that.size().
  350. /// \post length(n) == that.length(n) for all positive integers n \< that.size().
  351. /// \post position(n) == that.position(n) for all positive integers n \< that.size().
  352. match_results(match_results<BidiIter> const &that)
  353. : regex_id_(that.regex_id_)
  354. , sub_matches_()
  355. , base_()
  356. , prefix_()
  357. , suffix_()
  358. , nested_results_()
  359. , extras_ptr_()
  360. , traits_()
  361. , args_(that.args_)
  362. , named_marks_(that.named_marks_)
  363. {
  364. if(that)
  365. {
  366. extras_type &extras = this->get_extras_();
  367. std::size_t size = that.sub_matches_.size();
  368. detail::sub_match_impl<BidiIter> *sub_matches = extras.sub_match_stack_.push_sequence(size, detail::sub_match_impl<BidiIter>(*that.base_), detail::fill);
  369. detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, sub_matches, size, that.sub_matches_);
  370. this->base_ = that.base_;
  371. this->prefix_ = that.prefix_;
  372. this->suffix_ = that.suffix_;
  373. // BUGBUG this doesn't share the extras::sequence_stack
  374. this->nested_results_ = that.nested_results_;
  375. this->traits_ = that.traits_;
  376. }
  377. }
  378. ~match_results()
  379. {
  380. }
  381. /// \param that The match_results object to copy.
  382. /// \post regex_id() == that.regex_id().
  383. /// \post size() == that.size().
  384. /// \post empty() == that.empty().
  385. /// \post str(n) == that.str(n) for all positive integers n \< that.size().
  386. /// \post prefix() == that.prefix().
  387. /// \post suffix() == that.suffix().
  388. /// \post (*this)[n] == that[n] for all positive integers n \< that.size().
  389. /// \post length(n) == that.length(n) for all positive integers n \< that.size().
  390. /// \post position(n) == that.position(n) for all positive integers n \< that.size().
  391. match_results<BidiIter> &operator =(match_results<BidiIter> const &that)
  392. {
  393. match_results<BidiIter>(that).swap(*this);
  394. return *this;
  395. }
  396. /// Returns one plus the number of marked sub-expressions in the regular
  397. /// expression that was matched if *this represents the result of a
  398. /// successful match. Otherwise returns 0.
  399. size_type size() const
  400. {
  401. return this->sub_matches_.size();
  402. }
  403. /// Returns size() == 0.
  404. ///
  405. bool empty() const
  406. {
  407. return 0 == this->size();
  408. }
  409. /// Returns (*this)[sub].length().
  410. ///
  411. difference_type length(size_type sub = 0) const
  412. {
  413. return this->sub_matches_[ sub ].length();
  414. }
  415. /// If !(*this)[sub].matched then returns -1. Otherwise returns std::distance(base, (*this)[sub].first),
  416. /// where base is the start iterator of the sequence that was searched. [Note - unless this is part
  417. /// of a repeated search with a regex_iterator then base is the same as prefix().first - end note]
  418. difference_type position(size_type sub = 0) const
  419. {
  420. return this->sub_matches_[ sub ].matched ? std::distance(*this->base_, this->sub_matches_[ sub ].first) : -1;
  421. }
  422. /// Returns (*this)[sub].str().
  423. ///
  424. string_type str(size_type sub = 0) const
  425. {
  426. return this->sub_matches_[ sub ].str();
  427. }
  428. /// Returns a reference to the sub_match object representing the sequence that
  429. /// matched marked sub-expression sub. If sub == 0 then returns a reference to
  430. /// a sub_match object representing the sequence that matched the whole regular
  431. /// expression. If sub >= size() then returns a sub_match object representing an
  432. /// unmatched sub-expression.
  433. template<typename Sub>
  434. const_reference operator [](Sub const &sub) const
  435. {
  436. return this->at_(sub);
  437. }
  438. /// Returns a reference to the sub_match object representing the character sequence from
  439. /// the start of the string being matched/searched, to the start of the match found.
  440. ///
  441. /// \pre (*this)[0].matched is true
  442. const_reference prefix() const
  443. {
  444. return this->prefix_ ? *this->prefix_ : this->sub_matches_[this->sub_matches_.size()];
  445. }
  446. /// Returns a reference to the sub_match object representing the character sequence from
  447. /// the end of the match found to the end of the string being matched/searched.
  448. ///
  449. /// \pre (*this)[0].matched is true
  450. const_reference suffix() const
  451. {
  452. return this->suffix_ ? *this->suffix_ : this->sub_matches_[this->sub_matches_.size()];
  453. }
  454. /// Returns a starting iterator that enumerates over all the marked sub-expression matches
  455. /// stored in *this.
  456. ///
  457. const_iterator begin() const
  458. {
  459. return this->sub_matches_.begin();
  460. }
  461. /// Returns a terminating iterator that enumerates over all the marked sub-expression
  462. /// matches stored in *this.
  463. ///
  464. const_iterator end() const
  465. {
  466. return this->sub_matches_.end();
  467. }
  468. /// Returns a true value if (*this)[0].matched, else returns a false value.
  469. ///
  470. operator bool_type() const
  471. {
  472. return (!this->empty() && this->sub_matches_[ 0 ].matched) ? &dummy::i_ : 0;
  473. }
  474. /// Returns true if empty() || !(*this)[0].matched, else returns false.
  475. ///
  476. bool operator !() const
  477. {
  478. return this->empty() || !this->sub_matches_[ 0 ].matched;
  479. }
  480. /// Returns the id of the basic_regex object most recently used with this match_results object.
  481. ///
  482. regex_id_type regex_id() const
  483. {
  484. return this->regex_id_;
  485. }
  486. /// Returns a Sequence of nested match_results elements.
  487. ///
  488. nested_results_type const &nested_results() const
  489. {
  490. return this->nested_results_;
  491. }
  492. /// If \c Format models \c ForwardRange or is a null-terminated string, this function
  493. /// copies the character sequence in \c fmt to \c OutputIterator \c out. For each format
  494. /// specifier or escape sequence in \c fmt, replace that sequence with either the character(s) it
  495. /// represents, or the sequence within <tt>*this</tt> to which it refers. The bitmasks specified in flags
  496. /// determines what format specifiers or escape sequences are recognized. By default, this is the
  497. /// format used by ECMA-262, ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace.
  498. ///
  499. /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator, regex_constants::match_flag_type\></tt>,
  500. /// this function returns <tt>fmt(*this, out, flags)</tt>.
  501. ///
  502. /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator\></tt>, this function
  503. /// returns <tt>fmt(*this, out)</tt>.
  504. ///
  505. /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\> \></tt>, this function
  506. /// returns <tt>std::copy(x.begin(), x.end(), out)</tt>, where \c x is the result of
  507. /// calling <tt>fmt(*this)</tt>.
  508. template<typename Format, typename OutputIterator>
  509. OutputIterator format
  510. (
  511. OutputIterator out
  512. , Format const &fmt
  513. , regex_constants::match_flag_type flags = regex_constants::format_default
  514. , typename disable_if<detail::is_char_ptr<Format> >::type * = 0
  515. ) const
  516. {
  517. // Is this a formatter object, or a format string?
  518. typedef
  519. typename detail::formatter_arity<
  520. Format
  521. , match_results<BidiIter>
  522. , OutputIterator
  523. >::type
  524. arity;
  525. return this->format_(out, fmt, flags, arity());
  526. }
  527. /// \overload
  528. ///
  529. template<typename OutputIterator>
  530. OutputIterator format
  531. (
  532. OutputIterator out
  533. , char_type const *fmt
  534. , regex_constants::match_flag_type flags = regex_constants::format_default
  535. ) const
  536. {
  537. return this->format_(out, boost::as_literal(fmt), flags, mpl::size_t<0>());
  538. }
  539. /// If \c Format models \c ForwardRange or is a null-terminated string, this function
  540. /// returns a copy of the character sequence \c fmt. For each format specifier or escape sequence in \c fmt,
  541. /// replace that sequence with either the character(s) it represents, or the sequence within
  542. /// <tt>*this</tt> to which it refers. The bitmasks specified in \c flags determines what format specifiers
  543. /// or escape sequences are recognized. By default this is the format used by ECMA-262,
  544. /// ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace.
  545. ///
  546. /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator, regex_constants::match_flag_type\></tt>,
  547. /// this function returns a \c string_type object \c x populated by calling <tt>fmt(*this, out, flags)</tt>,
  548. /// where \c out is a \c back_insert_iterator into \c x.
  549. ///
  550. /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator\></tt>, this function
  551. /// returns a \c string_type object \c x populated by calling <tt>fmt(*this, out)</tt>,
  552. /// where \c out is a \c back_insert_iterator into \c x.
  553. ///
  554. /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\> \></tt>, this function
  555. /// returns <tt>fmt(*this)</tt>.
  556. template<typename Format, typename OutputIterator>
  557. string_type format
  558. (
  559. Format const &fmt
  560. , regex_constants::match_flag_type flags = regex_constants::format_default
  561. , typename disable_if<detail::is_char_ptr<Format> >::type * = 0
  562. ) const
  563. {
  564. string_type result;
  565. this->format(std::back_inserter(result), fmt, flags);
  566. return result;
  567. }
  568. /// \overload
  569. ///
  570. string_type format
  571. (
  572. char_type const *fmt
  573. , regex_constants::match_flag_type flags = regex_constants::format_default
  574. ) const
  575. {
  576. string_type result;
  577. this->format(std::back_inserter(result), fmt, flags);
  578. return result;
  579. }
  580. /// Swaps the contents of two match_results objects. Guaranteed not to throw.
  581. /// \param that The match_results object to swap with.
  582. /// \post *this contains the sequence of matched sub-expressions that were in that,
  583. /// that contains the sequence of matched sub-expressions that were in *this.
  584. /// \throw nothrow
  585. void swap(match_results<BidiIter> &that) // throw()
  586. {
  587. using std::swap;
  588. swap(this->regex_id_, that.regex_id_);
  589. this->sub_matches_.swap(that.sub_matches_);
  590. this->base_.swap(that.base_);
  591. this->prefix_.swap(that.prefix_);
  592. this->suffix_.swap(that.suffix_);
  593. this->nested_results_.swap(that.nested_results_);
  594. this->extras_ptr_.swap(that.extras_ptr_);
  595. this->traits_.swap(that.traits_);
  596. this->args_.swap(that.args_);
  597. }
  598. /// TODO document me
  599. ///
  600. template<typename Arg>
  601. match_results<BidiIter> &let(Arg const &arg)
  602. {
  603. typedef typename proto::result_of::left<Arg>::type left_type;
  604. typedef typename proto::result_of::right<Arg>::type right_type;
  605. typedef typename proto::result_of::value<left_type>::type arg_left_type;
  606. typedef typename proto::result_of::value<right_type>::type arg_right_type;
  607. BOOST_MPL_ASSERT((proto::matches<Arg, detail::ActionArgBinding>));
  608. BOOST_MPL_ASSERT((is_same<typename arg_left_type::type, arg_right_type>));
  609. this->args_[&typeid(proto::value(proto::left(arg)))] = &proto::value(proto::right(arg));
  610. return *this;
  611. }
  612. /// INTERNAL ONLY
  613. ///
  614. match_results<BidiIter> const &operator ()(regex_id_type regex_id, size_type index = 0) const
  615. {
  616. // BUGBUG this is linear, make it O(1)
  617. static match_results<BidiIter> const s_null;
  618. regex_id_filter_predicate<BidiIter> pred(regex_id);
  619. typename nested_results_type::const_iterator
  620. begin = this->nested_results_.begin()
  621. , end = this->nested_results_.end()
  622. , cur = detail::find_nth_if(begin, end, index, pred);
  623. return (cur == end) ? s_null : *cur;
  624. }
  625. /// INTERNAL ONLY
  626. ///
  627. match_results<BidiIter> const &operator ()(basic_regex<BidiIter> const &rex, std::size_t index = 0) const
  628. {
  629. return (*this)(rex.regex_id(), index);
  630. }
  631. private:
  632. friend struct detail::core_access<BidiIter>;
  633. typedef detail::results_extras<BidiIter> extras_type;
  634. /// INTERNAL ONLY
  635. ///
  636. void init_
  637. (
  638. regex_id_type regex_id
  639. , intrusive_ptr<detail::traits<char_type> const> const &tr
  640. , detail::sub_match_impl<BidiIter> *sub_matches
  641. , size_type size
  642. , std::vector<detail::named_mark<char_type> > const &named_marks
  643. )
  644. {
  645. this->traits_ = tr;
  646. this->regex_id_ = regex_id;
  647. this->named_marks_ = named_marks;
  648. detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, sub_matches, size);
  649. }
  650. /// INTERNAL ONLY
  651. ///
  652. extras_type &get_extras_()
  653. {
  654. if(!this->extras_ptr_)
  655. {
  656. this->extras_ptr_ = new extras_type;
  657. }
  658. return *this->extras_ptr_;
  659. }
  660. /// INTERNAL ONLY
  661. ///
  662. void set_prefix_suffix_(BidiIter begin, BidiIter end)
  663. {
  664. this->base_ = begin;
  665. this->prefix_ = sub_match<BidiIter>(begin, this->sub_matches_[ 0 ].first, begin != this->sub_matches_[ 0 ].first);
  666. this->suffix_ = sub_match<BidiIter>(this->sub_matches_[ 0 ].second, end, this->sub_matches_[ 0 ].second != end);
  667. typename nested_results_type::iterator ibegin = this->nested_results_.begin();
  668. typename nested_results_type::iterator iend = this->nested_results_.end();
  669. for( ; ibegin != iend; ++ibegin )
  670. {
  671. ibegin->set_prefix_suffix_(begin, end);
  672. }
  673. }
  674. /// INTERNAL ONLY
  675. ///
  676. void reset_()
  677. {
  678. detail::core_access<BidiIter>::init_sub_match_vector(this->sub_matches_, 0, 0);
  679. }
  680. /// INTERNAL ONLY
  681. ///
  682. void set_base_(BidiIter base)
  683. {
  684. this->base_ = base;
  685. typename nested_results_type::iterator ibegin = this->nested_results_.begin();
  686. typename nested_results_type::iterator iend = this->nested_results_.end();
  687. for( ; ibegin != iend; ++ibegin )
  688. {
  689. ibegin->set_base_(base);
  690. }
  691. }
  692. /// INTERNAL ONLY
  693. ///
  694. const_reference at_(size_type sub) const
  695. {
  696. return this->sub_matches_[ sub ];
  697. }
  698. /// INTERNAL ONLY
  699. ///
  700. const_reference at_(detail::basic_mark_tag const &mark) const
  701. {
  702. return this->sub_matches_[ detail::get_mark_number(mark) ];
  703. }
  704. /// INTERNAL ONLY
  705. ///
  706. const_reference at_(char_type const *name) const
  707. {
  708. for(std::size_t i = 0; i < this->named_marks_.size(); ++i)
  709. {
  710. if(this->named_marks_[i].name_ == name)
  711. {
  712. return this->sub_matches_[ this->named_marks_[i].mark_nbr_ ];
  713. }
  714. }
  715. BOOST_THROW_EXCEPTION(
  716. regex_error(regex_constants::error_badmark, "invalid named back-reference")
  717. );
  718. // Should never execute, but if it does, this returns
  719. // a "null" sub_match.
  720. return this->sub_matches_[this->sub_matches_.size()];
  721. }
  722. /// INTERNAL ONLY
  723. ///
  724. const_reference at_(string_type const &name) const
  725. {
  726. return (*this)[name.c_str()];
  727. }
  728. /// INTERNAL ONLY
  729. ///
  730. template<typename OutputIterator, typename ForwardRange>
  731. OutputIterator format2_(OutputIterator out, ForwardRange const &result) const
  732. {
  733. return std::copy(boost::begin(result), boost::end(result), out);
  734. }
  735. /// INTERNAL ONLY
  736. ///
  737. template<typename OutputIterator, typename Char>
  738. OutputIterator format2_(OutputIterator out, Char const *const &result) const
  739. {
  740. Char const *tmp = result;
  741. BOOST_ASSERT(0 != tmp);
  742. for(; 0 != *tmp; ++tmp, ++out)
  743. {
  744. *out = *tmp;
  745. }
  746. return out;
  747. }
  748. /// INTERNAL ONLY
  749. ///
  750. template<typename OutputIterator, typename ForwardRange>
  751. OutputIterator format_
  752. (
  753. OutputIterator out
  754. , ForwardRange const &format
  755. , regex_constants::match_flag_type flags
  756. , mpl::size_t<0>
  757. ) const
  758. {
  759. typedef typename range_const_iterator<ForwardRange>::type iterator;
  760. iterator cur = boost::begin(format), end = boost::end(format);
  761. if(0 != (regex_constants::format_literal & flags))
  762. {
  763. return std::copy(cur, end, out);
  764. }
  765. else if(0 != (regex_constants::format_perl & flags))
  766. {
  767. return this->format_perl_(cur, end, out);
  768. }
  769. else if(0 != (regex_constants::format_sed & flags))
  770. {
  771. return this->format_sed_(cur, end, out);
  772. }
  773. else if(0 != (regex_constants::format_all & flags))
  774. {
  775. return this->format_all_(cur, end, out);
  776. }
  777. return this->format_ecma_262_(cur, end, out);
  778. }
  779. /// INTERNAL ONLY
  780. ///
  781. template<typename OutputIterator, typename Callable1>
  782. OutputIterator format_
  783. (
  784. OutputIterator out
  785. , Callable1 const &format
  786. , regex_constants::match_flag_type
  787. , mpl::size_t<1>
  788. ) const
  789. {
  790. #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
  791. return this->format2_(out, detail::as_callable(format)(*this));
  792. #else
  793. return this->format2_(out, format(*this));
  794. #endif
  795. }
  796. /// INTERNAL ONLY
  797. ///
  798. template<typename OutputIterator, typename Callable2>
  799. OutputIterator format_
  800. (
  801. OutputIterator out
  802. , Callable2 const &format
  803. , regex_constants::match_flag_type
  804. , mpl::size_t<2>
  805. ) const
  806. {
  807. #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
  808. return detail::as_callable(format)(*this, out);
  809. #else
  810. return format(*this, out);
  811. #endif
  812. }
  813. /// INTERNAL ONLY
  814. ///
  815. template<typename OutputIterator, typename Callable3>
  816. OutputIterator format_
  817. (
  818. OutputIterator out
  819. , Callable3 const &format
  820. , regex_constants::match_flag_type flags
  821. , mpl::size_t<3>
  822. ) const
  823. {
  824. #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
  825. return detail::as_callable(format)(*this, out, flags);
  826. #else
  827. return format(*this, out, flags);
  828. #endif
  829. }
  830. /// INTERNAL ONLY
  831. ///
  832. template<typename OutputIterator, typename Expr>
  833. OutputIterator format_
  834. (
  835. OutputIterator out
  836. , Expr const &format
  837. , regex_constants::match_flag_type
  838. , mpl::size_t<4>
  839. ) const
  840. {
  841. // detail::ReplaceAlgo may be an incomplete type at this point, so
  842. // we can't construct it directly.
  843. typedef typename mpl::if_c<true, detail::ReplaceAlgo, OutputIterator>::type ReplaceAlgo;
  844. return this->format2_(out, ReplaceAlgo()(format, 0, *this));
  845. }
  846. /// INTERNAL ONLY
  847. ///
  848. template<typename ForwardIterator, typename OutputIterator>
  849. OutputIterator format_ecma_262_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
  850. {
  851. while(cur != end)
  852. {
  853. switch(*cur)
  854. {
  855. case BOOST_XPR_CHAR_(char_type, '$'):
  856. out = this->format_backref_(++cur, end, out);
  857. break;
  858. default:
  859. *out++ = *cur++;
  860. break;
  861. }
  862. }
  863. return out;
  864. }
  865. /// INTERNAL ONLY
  866. ///
  867. template<typename ForwardIterator, typename OutputIterator>
  868. OutputIterator format_sed_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
  869. {
  870. while(cur != end)
  871. {
  872. switch(*cur)
  873. {
  874. case BOOST_XPR_CHAR_(char_type, '&'):
  875. ++cur;
  876. out = std::copy(this->sub_matches_[ 0 ].first, this->sub_matches_[ 0 ].second, out);
  877. break;
  878. case BOOST_XPR_CHAR_(char_type, '\\'):
  879. out = this->format_escape_(++cur, end, out);
  880. break;
  881. default:
  882. *out++ = *cur++;
  883. break;
  884. }
  885. }
  886. return out;
  887. }
  888. /// INTERNAL ONLY
  889. ///
  890. template<typename ForwardIterator, typename OutputIterator>
  891. OutputIterator format_perl_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
  892. {
  893. detail::case_converting_iterator<OutputIterator, char_type> iout(out, this->traits_.get());
  894. while(cur != end)
  895. {
  896. switch(*cur)
  897. {
  898. case BOOST_XPR_CHAR_(char_type, '$'):
  899. iout = this->format_backref_(++cur, end, iout);
  900. break;
  901. case BOOST_XPR_CHAR_(char_type, '\\'):
  902. if(++cur != end && BOOST_XPR_CHAR_(char_type, 'g') == *cur)
  903. {
  904. iout = this->format_named_backref_(++cur, end, iout);
  905. }
  906. else
  907. {
  908. iout = this->format_escape_(cur, end, iout);
  909. }
  910. break;
  911. default:
  912. *iout++ = *cur++;
  913. break;
  914. }
  915. }
  916. return iout.base();
  917. }
  918. /// INTERNAL ONLY
  919. ///
  920. template<typename ForwardIterator, typename OutputIterator>
  921. OutputIterator format_all_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
  922. {
  923. detail::case_converting_iterator<OutputIterator, char_type> iout(out, this->traits_.get());
  924. iout = this->format_all_impl_(cur, end, iout);
  925. BOOST_XPR_ENSURE_(cur == end
  926. , regex_constants::error_paren, "unbalanced parentheses in format string");
  927. return iout.base();
  928. }
  929. /// INTERNAL ONLY
  930. ///
  931. template<typename ForwardIterator, typename OutputIterator>
  932. OutputIterator format_all_impl_(ForwardIterator &cur, ForwardIterator end, OutputIterator out, bool metacolon = false) const
  933. {
  934. int max = 0, sub = 0;
  935. detail::noop_output_iterator<char_type> noop;
  936. while(cur != end)
  937. {
  938. switch(*cur)
  939. {
  940. case BOOST_XPR_CHAR_(char_type, '$'):
  941. out = this->format_backref_(++cur, end, out);
  942. break;
  943. case BOOST_XPR_CHAR_(char_type, '\\'):
  944. if(++cur != end && BOOST_XPR_CHAR_(char_type, 'g') == *cur)
  945. {
  946. out = this->format_named_backref_(++cur, end, out);
  947. }
  948. else
  949. {
  950. out = this->format_escape_(cur, end, out);
  951. }
  952. break;
  953. case BOOST_XPR_CHAR_(char_type, '('):
  954. out = this->format_all_impl_(++cur, end, out);
  955. BOOST_XPR_ENSURE_(BOOST_XPR_CHAR_(char_type, ')') == *(cur-1)
  956. , regex_constants::error_paren, "unbalanced parentheses in format string");
  957. break;
  958. case BOOST_XPR_CHAR_(char_type, '?'):
  959. BOOST_XPR_ENSURE_(++cur != end
  960. , regex_constants::error_subreg, "malformed conditional in format string");
  961. max = static_cast<int>(this->size() - 1);
  962. sub = detail::toi(cur, end, *this->traits_, 10, max);
  963. BOOST_XPR_ENSURE_(0 != sub, regex_constants::error_subreg, "invalid back-reference");
  964. if(this->sub_matches_[ sub ].matched)
  965. {
  966. out = this->format_all_impl_(cur, end, out, true);
  967. if(BOOST_XPR_CHAR_(char_type, ':') == *(cur-1))
  968. this->format_all_impl_(cur, end, noop);
  969. }
  970. else
  971. {
  972. this->format_all_impl_(cur, end, noop, true);
  973. if(BOOST_XPR_CHAR_(char_type, ':') == *(cur-1))
  974. out = this->format_all_impl_(cur, end, out);
  975. }
  976. return out;
  977. case BOOST_XPR_CHAR_(char_type, ':'):
  978. if(metacolon)
  979. {
  980. BOOST_FALLTHROUGH;
  981. case BOOST_XPR_CHAR_(char_type, ')'):
  982. ++cur;
  983. return out;
  984. }
  985. BOOST_FALLTHROUGH;
  986. default:
  987. *out++ = *cur++;
  988. break;
  989. }
  990. }
  991. return out;
  992. }
  993. /// INTERNAL ONLY
  994. ///
  995. template<typename ForwardIterator, typename OutputIterator>
  996. OutputIterator format_backref_
  997. (
  998. ForwardIterator &cur
  999. , ForwardIterator end
  1000. , OutputIterator out
  1001. ) const
  1002. {
  1003. if(cur == end)
  1004. {
  1005. *out++ = BOOST_XPR_CHAR_(char_type, '$');
  1006. }
  1007. else if(BOOST_XPR_CHAR_(char_type, '$') == *cur)
  1008. {
  1009. *out++ = *cur++;
  1010. }
  1011. else if(BOOST_XPR_CHAR_(char_type, '&') == *cur) // whole match
  1012. {
  1013. ++cur;
  1014. out = std::copy(this->sub_matches_[ 0 ].first, this->sub_matches_[ 0 ].second, out);
  1015. }
  1016. else if(BOOST_XPR_CHAR_(char_type, '`') == *cur) // prefix
  1017. {
  1018. ++cur;
  1019. out = std::copy(this->prefix().first, this->prefix().second, out);
  1020. }
  1021. else if(BOOST_XPR_CHAR_(char_type, '\'') == *cur) // suffix
  1022. {
  1023. ++cur;
  1024. out = std::copy(this->suffix().first, this->suffix().second, out);
  1025. }
  1026. else if(-1 != this->traits_->value(*cur, 10)) // a sub-match
  1027. {
  1028. int max = static_cast<int>(this->size() - 1);
  1029. int sub = detail::toi(cur, end, *this->traits_, 10, max);
  1030. BOOST_XPR_ENSURE_(0 != sub, regex_constants::error_subreg, "invalid back-reference");
  1031. if(this->sub_matches_[ sub ].matched)
  1032. out = std::copy(this->sub_matches_[ sub ].first, this->sub_matches_[ sub ].second, out);
  1033. }
  1034. else
  1035. {
  1036. *out++ = BOOST_XPR_CHAR_(char_type, '$');
  1037. *out++ = *cur++;
  1038. }
  1039. return out;
  1040. }
  1041. /// INTERNAL ONLY
  1042. ///
  1043. template<typename ForwardIterator, typename OutputIterator>
  1044. OutputIterator format_escape_
  1045. (
  1046. ForwardIterator &cur
  1047. , ForwardIterator end
  1048. , OutputIterator out
  1049. ) const
  1050. {
  1051. using namespace regex_constants;
  1052. ForwardIterator tmp;
  1053. // define an unsigned type the same size as char_type
  1054. typedef typename boost::uint_t<CHAR_BIT * sizeof(char_type)>::least uchar_t;
  1055. BOOST_MPL_ASSERT_RELATION(sizeof(uchar_t), ==, sizeof(char_type));
  1056. typedef numeric::conversion_traits<uchar_t, int> converstion_traits;
  1057. numeric::converter<int, uchar_t, converstion_traits, detail::char_overflow_handler_> converter;
  1058. if(cur == end)
  1059. {
  1060. *out++ = BOOST_XPR_CHAR_(char_type, '\\');
  1061. return out;
  1062. }
  1063. char_type ch = *cur++;
  1064. switch(ch)
  1065. {
  1066. case BOOST_XPR_CHAR_(char_type, 'a'):
  1067. *out++ = BOOST_XPR_CHAR_(char_type, '\a');
  1068. break;
  1069. case BOOST_XPR_CHAR_(char_type, 'e'):
  1070. *out++ = converter(27);
  1071. break;
  1072. case BOOST_XPR_CHAR_(char_type, 'f'):
  1073. *out++ = BOOST_XPR_CHAR_(char_type, '\f');
  1074. break;
  1075. case BOOST_XPR_CHAR_(char_type, 'n'):
  1076. *out++ = BOOST_XPR_CHAR_(char_type, '\n');
  1077. break;
  1078. case BOOST_XPR_CHAR_(char_type, 'r'):
  1079. *out++ = BOOST_XPR_CHAR_(char_type, '\r');
  1080. break;
  1081. case BOOST_XPR_CHAR_(char_type, 't'):
  1082. *out++ = BOOST_XPR_CHAR_(char_type, '\t');
  1083. break;
  1084. case BOOST_XPR_CHAR_(char_type, 'v'):
  1085. *out++ = BOOST_XPR_CHAR_(char_type, '\v');
  1086. break;
  1087. case BOOST_XPR_CHAR_(char_type, 'x'):
  1088. BOOST_XPR_ENSURE_(cur != end, error_escape, "unexpected end of format found");
  1089. if(BOOST_XPR_CHAR_(char_type, '{') == *cur)
  1090. {
  1091. BOOST_XPR_ENSURE_(++cur != end, error_escape, "unexpected end of format found");
  1092. tmp = cur;
  1093. *out++ = converter(detail::toi(cur, end, *this->traits_, 16, 0xffff));
  1094. BOOST_XPR_ENSURE_(4 == std::distance(tmp, cur) && cur != end && BOOST_XPR_CHAR_(char_type, '}') == *cur++
  1095. , error_escape, "invalid hex escape : must be \\x { HexDigit HexDigit HexDigit HexDigit }");
  1096. }
  1097. else
  1098. {
  1099. tmp = cur;
  1100. *out++ = converter(detail::toi(cur, end, *this->traits_, 16, 0xff));
  1101. BOOST_XPR_ENSURE_(2 == std::distance(tmp, cur), error_escape
  1102. , "invalid hex escape : must be \\x HexDigit HexDigit");
  1103. }
  1104. break;
  1105. case BOOST_XPR_CHAR_(char_type, 'c'):
  1106. BOOST_XPR_ENSURE_(cur != end, error_escape, "unexpected end of format found");
  1107. BOOST_XPR_ENSURE_
  1108. (
  1109. this->traits_->in_range(BOOST_XPR_CHAR_(char_type, 'a'), BOOST_XPR_CHAR_(char_type, 'z'), *cur)
  1110. || this->traits_->in_range(BOOST_XPR_CHAR_(char_type, 'A'), BOOST_XPR_CHAR_(char_type, 'Z'), *cur)
  1111. , error_escape
  1112. , "invalid escape control letter; must be one of a-z or A-Z"
  1113. );
  1114. // Convert to character according to ECMA-262, section 15.10.2.10:
  1115. *out++ = converter(*cur % 32);
  1116. ++cur;
  1117. break;
  1118. case BOOST_XPR_CHAR_(char_type, 'l'):
  1119. if(!set_transform(out, detail::op_lower, detail::scope_next))
  1120. {
  1121. *out++ = BOOST_XPR_CHAR_(char_type, 'l');
  1122. }
  1123. break;
  1124. case BOOST_XPR_CHAR_(char_type, 'L'):
  1125. if(!set_transform(out, detail::op_lower, detail::scope_rest))
  1126. {
  1127. *out++ = BOOST_XPR_CHAR_(char_type, 'L');
  1128. }
  1129. break;
  1130. case BOOST_XPR_CHAR_(char_type, 'u'):
  1131. if(!set_transform(out, detail::op_upper, detail::scope_next))
  1132. {
  1133. *out++ = BOOST_XPR_CHAR_(char_type, 'u');
  1134. }
  1135. break;
  1136. case BOOST_XPR_CHAR_(char_type, 'U'):
  1137. if(!set_transform(out, detail::op_upper, detail::scope_rest))
  1138. {
  1139. *out++ = BOOST_XPR_CHAR_(char_type, 'U');
  1140. }
  1141. break;
  1142. case BOOST_XPR_CHAR_(char_type, 'E'):
  1143. if(!set_transform(out, detail::op_none, detail::scope_rest))
  1144. {
  1145. *out++ = BOOST_XPR_CHAR_(char_type, 'E');
  1146. }
  1147. break;
  1148. default:
  1149. // BUGBUG what about backreferences like \12 ?
  1150. if(0 < this->traits_->value(ch, 10))
  1151. {
  1152. int sub = this->traits_->value(ch, 10);
  1153. if(this->sub_matches_[ sub ].matched)
  1154. out = std::copy(this->sub_matches_[ sub ].first, this->sub_matches_[ sub ].second, out);
  1155. }
  1156. else
  1157. {
  1158. *out++ = ch;
  1159. }
  1160. break;
  1161. }
  1162. return out;
  1163. }
  1164. /// INTERNAL ONLY
  1165. ///
  1166. template<typename ForwardIterator, typename OutputIterator>
  1167. OutputIterator format_named_backref_
  1168. (
  1169. ForwardIterator &cur
  1170. , ForwardIterator end
  1171. , OutputIterator out
  1172. ) const
  1173. {
  1174. using namespace regex_constants;
  1175. BOOST_XPR_ENSURE_(cur != end && BOOST_XPR_CHAR_(char_type, '<') == *cur++
  1176. , error_badmark, "invalid named back-reference");
  1177. ForwardIterator begin = cur;
  1178. for(; cur != end && BOOST_XPR_CHAR_(char_type, '>') != *cur; ++cur)
  1179. {}
  1180. BOOST_XPR_ENSURE_(cur != begin && cur != end && BOOST_XPR_CHAR_(char_type, '>') == *cur
  1181. , error_badmark, "invalid named back-reference");
  1182. string_type name(begin, cur++);
  1183. for(std::size_t i = 0; i < this->named_marks_.size(); ++i)
  1184. {
  1185. if(this->named_marks_[i].name_ == name)
  1186. {
  1187. std::size_t sub = this->named_marks_[i].mark_nbr_;
  1188. return std::copy(this->sub_matches_[ sub ].first, this->sub_matches_[ sub ].second, out);
  1189. }
  1190. }
  1191. BOOST_THROW_EXCEPTION(regex_error(error_badmark, "invalid named back-reference"));
  1192. // Should never get here
  1193. return out;
  1194. }
  1195. regex_id_type regex_id_;
  1196. detail::sub_match_vector<BidiIter> sub_matches_;
  1197. boost::optional<BidiIter> base_;
  1198. boost::optional<sub_match<BidiIter> > prefix_;
  1199. boost::optional<sub_match<BidiIter> > suffix_;
  1200. nested_results_type nested_results_;
  1201. intrusive_ptr<extras_type> extras_ptr_;
  1202. intrusive_ptr<detail::traits<char_type> const> traits_;
  1203. detail::action_args_type args_;
  1204. std::vector<detail::named_mark<char_type> > named_marks_;
  1205. };
  1206. ///////////////////////////////////////////////////////////////////////////////
  1207. // regex_id_filter_predicate
  1208. //
  1209. template<typename BidiIter>
  1210. struct regex_id_filter_predicate
  1211. {
  1212. typedef match_results<BidiIter> argument_type;
  1213. typedef bool result_type;
  1214. regex_id_filter_predicate(regex_id_type regex_id)
  1215. : regex_id_(regex_id)
  1216. {
  1217. }
  1218. bool operator ()(match_results<BidiIter> const &res) const
  1219. {
  1220. return this->regex_id_ == res.regex_id();
  1221. }
  1222. private:
  1223. regex_id_type regex_id_;
  1224. };
  1225. }} // namespace boost::xpressive
  1226. #ifdef BOOST_HAS_CONCEPTS
  1227. // Better living through concepts. :-P
  1228. namespace std
  1229. {
  1230. template<typename Iter_, typename Char_>
  1231. concept_map OutputIterator<
  1232. boost::xpressive::detail::case_converting_iterator<Iter_, Char_>
  1233. , Char_
  1234. >
  1235. {};
  1236. template<typename Char_>
  1237. concept_map OutputIterator<
  1238. boost::xpressive::detail::noop_output_iterator<Char_>
  1239. , Char_
  1240. >
  1241. {};
  1242. }
  1243. #endif
  1244. #endif