match_results.hpp 44 KB

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