1 | /////////////////////////////////////////////////////////////////////////////// |
2 | /// \file regex_actions.hpp |
3 | /// Defines the syntax elements of xpressive's action expressions. |
4 | // |
5 | // Copyright 2008 Eric Niebler. Distributed under the Boost |
6 | // Software License, Version 1.0. (See accompanying file |
7 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8 | |
9 | #ifndef BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007 |
10 | #define BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007 |
11 | |
12 | // MS compatible compilers support #pragma once |
13 | #if defined(_MSC_VER) |
14 | # pragma once |
15 | #endif |
16 | |
17 | #include <boost/config.hpp> |
18 | #include <boost/preprocessor/punctuation/comma_if.hpp> |
19 | #include <boost/ref.hpp> |
20 | #include <boost/mpl/if.hpp> |
21 | #include <boost/mpl/or.hpp> |
22 | #include <boost/mpl/int.hpp> |
23 | #include <boost/mpl/assert.hpp> |
24 | #include <boost/noncopyable.hpp> |
25 | #include <boost/lexical_cast.hpp> |
26 | #include <boost/throw_exception.hpp> |
27 | #include <boost/utility/enable_if.hpp> |
28 | #include <boost/type_traits/is_same.hpp> |
29 | #include <boost/type_traits/is_const.hpp> |
30 | #include <boost/type_traits/is_integral.hpp> |
31 | #include <boost/type_traits/decay.hpp> |
32 | #include <boost/type_traits/remove_cv.hpp> |
33 | #include <boost/type_traits/remove_reference.hpp> |
34 | #include <boost/range/iterator_range.hpp> |
35 | #include <boost/xpressive/detail/detail_fwd.hpp> |
36 | #include <boost/xpressive/detail/core/state.hpp> |
37 | #include <boost/xpressive/detail/core/matcher/attr_matcher.hpp> |
38 | #include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp> |
39 | #include <boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp> |
40 | #include <boost/xpressive/detail/core/matcher/predicate_matcher.hpp> |
41 | #include <boost/xpressive/detail/utility/ignore_unused.hpp> |
42 | #include <boost/xpressive/detail/static/type_traits.hpp> |
43 | |
44 | // These are very often needed by client code. |
45 | #include <boost/typeof/std/map.hpp> |
46 | #include <boost/typeof/std/string.hpp> |
47 | |
48 | // Doxygen can't handle proto :-( |
49 | #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED |
50 | # include <boost/proto/core.hpp> |
51 | # include <boost/proto/transform.hpp> |
52 | # include <boost/xpressive/detail/core/matcher/action_matcher.hpp> |
53 | #endif |
54 | |
55 | #if BOOST_MSVC |
56 | #pragma warning(push) |
57 | #pragma warning(disable : 4510) // default constructor could not be generated |
58 | #pragma warning(disable : 4512) // assignment operator could not be generated |
59 | #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required |
60 | #endif |
61 | |
62 | namespace boost { namespace xpressive |
63 | { |
64 | |
65 | namespace detail |
66 | { |
67 | template<typename T, typename U> |
68 | struct action_arg |
69 | { |
70 | typedef T type; |
71 | typedef typename add_reference<T>::type reference; |
72 | |
73 | reference cast(void *pv) const |
74 | { |
75 | return *static_cast<typename remove_reference<T>::type *>(pv); |
76 | } |
77 | }; |
78 | |
79 | template<typename T> |
80 | struct value_wrapper |
81 | : private noncopyable |
82 | { |
83 | value_wrapper() |
84 | : value() |
85 | {} |
86 | |
87 | value_wrapper(T const &t) |
88 | : value(t) |
89 | {} |
90 | |
91 | T value; |
92 | }; |
93 | |
94 | struct check_tag |
95 | {}; |
96 | |
97 | struct BindArg |
98 | { |
99 | BOOST_PROTO_CALLABLE() |
100 | template<typename Sig> |
101 | struct result {}; |
102 | |
103 | template<typename This, typename MatchResults, typename Expr> |
104 | struct result<This(MatchResults, Expr)> |
105 | { |
106 | typedef Expr type; |
107 | }; |
108 | |
109 | template<typename MatchResults, typename Expr> |
110 | Expr const & operator ()(MatchResults &what, Expr const &expr) const |
111 | { |
112 | what.let(expr); |
113 | return expr; |
114 | } |
115 | }; |
116 | |
117 | struct let_tag |
118 | {}; |
119 | |
120 | // let(_a = b, _c = d) |
121 | struct BindArgs |
122 | : proto::function< |
123 | proto::terminal<let_tag> |
124 | , proto::vararg< |
125 | proto::when< |
126 | proto::assign<proto::_, proto::_> |
127 | , proto::call<BindArg(proto::_data, proto::_)> |
128 | > |
129 | > |
130 | > |
131 | {}; |
132 | |
133 | struct let_domain |
134 | : boost::proto::domain<boost::proto::pod_generator<let_> > |
135 | {}; |
136 | |
137 | template<typename Expr> |
138 | struct let_ |
139 | { |
140 | BOOST_PROTO_BASIC_EXTENDS(Expr, let_<Expr>, let_domain) |
141 | BOOST_PROTO_EXTENDS_FUNCTION() |
142 | }; |
143 | |
144 | template<typename Args, typename BidiIter> |
145 | void bind_args(let_<Args> const &args, match_results<BidiIter> &what) |
146 | { |
147 | BindArgs()(args, 0, what); |
148 | } |
149 | |
150 | typedef boost::proto::functional::make_expr<proto::tag::function, proto::default_domain> make_function; |
151 | } |
152 | |
153 | namespace op |
154 | { |
155 | /// \brief \c at is a PolymorphicFunctionObject for indexing into a sequence |
156 | struct at |
157 | { |
158 | BOOST_PROTO_CALLABLE() |
159 | template<typename Sig> |
160 | struct result {}; |
161 | |
162 | template<typename This, typename Cont, typename Idx> |
163 | struct result<This(Cont &, Idx)> |
164 | { |
165 | typedef typename Cont::reference type; |
166 | }; |
167 | |
168 | template<typename This, typename Cont, typename Idx> |
169 | struct result<This(Cont const &, Idx)> |
170 | { |
171 | typedef typename Cont::const_reference type; |
172 | }; |
173 | |
174 | template<typename This, typename Cont, typename Idx> |
175 | struct result<This(Cont, Idx)> |
176 | { |
177 | typedef typename Cont::const_reference type; |
178 | }; |
179 | |
180 | /// \pre \c Cont is a model of RandomAccessSequence |
181 | /// \param c The RandomAccessSequence to index into |
182 | /// \param idx The index |
183 | /// \return <tt>c[idx]</tt> |
184 | template<typename Cont, typename Idx> |
185 | typename Cont::reference operator()(Cont &c, Idx idx BOOST_PROTO_DISABLE_IF_IS_CONST(Cont)) const |
186 | { |
187 | return c[idx]; |
188 | } |
189 | |
190 | /// \overload |
191 | /// |
192 | template<typename Cont, typename Idx> |
193 | typename Cont::const_reference operator()(Cont const &c, Idx idx) const |
194 | { |
195 | return c[idx]; |
196 | } |
197 | }; |
198 | |
199 | /// \brief \c push is a PolymorphicFunctionObject for pushing an element into a container. |
200 | struct push |
201 | { |
202 | BOOST_PROTO_CALLABLE() |
203 | typedef void result_type; |
204 | |
205 | /// \param seq The sequence into which the value should be pushed. |
206 | /// \param val The value to push into the sequence. |
207 | /// \brief Equivalent to <tt>seq.push(val)</tt>. |
208 | /// \return \c void |
209 | template<typename Sequence, typename Value> |
210 | void operator()(Sequence &seq, Value const &val) const |
211 | { |
212 | seq.push(val); |
213 | } |
214 | }; |
215 | |
216 | /// \brief \c push_back is a PolymorphicFunctionObject for pushing an element into the back of a container. |
217 | struct push_back |
218 | { |
219 | BOOST_PROTO_CALLABLE() |
220 | typedef void result_type; |
221 | |
222 | /// \param seq The sequence into which the value should be pushed. |
223 | /// \param val The value to push into the sequence. |
224 | /// \brief Equivalent to <tt>seq.push_back(val)</tt>. |
225 | /// \return \c void |
226 | template<typename Sequence, typename Value> |
227 | void operator()(Sequence &seq, Value const &val) const |
228 | { |
229 | seq.push_back(val); |
230 | } |
231 | }; |
232 | |
233 | /// \brief \c push_front is a PolymorphicFunctionObject for pushing an element into the front of a container. |
234 | struct push_front |
235 | { |
236 | BOOST_PROTO_CALLABLE() |
237 | typedef void result_type; |
238 | |
239 | /// \param seq The sequence into which the value should be pushed. |
240 | /// \param val The value to push into the sequence. |
241 | /// \brief Equivalent to <tt>seq.push_front(val)</tt>. |
242 | /// \return \c void |
243 | template<typename Sequence, typename Value> |
244 | void operator()(Sequence &seq, Value const &val) const |
245 | { |
246 | seq.push_front(val); |
247 | } |
248 | }; |
249 | |
250 | /// \brief \c pop is a PolymorphicFunctionObject for popping an element from a container. |
251 | struct pop |
252 | { |
253 | BOOST_PROTO_CALLABLE() |
254 | typedef void result_type; |
255 | |
256 | /// \param seq The sequence from which to pop. |
257 | /// \brief Equivalent to <tt>seq.pop()</tt>. |
258 | /// \return \c void |
259 | template<typename Sequence> |
260 | void operator()(Sequence &seq) const |
261 | { |
262 | seq.pop(); |
263 | } |
264 | }; |
265 | |
266 | /// \brief \c pop_back is a PolymorphicFunctionObject for popping an element from the back of a container. |
267 | struct pop_back |
268 | { |
269 | BOOST_PROTO_CALLABLE() |
270 | typedef void result_type; |
271 | |
272 | /// \param seq The sequence from which to pop. |
273 | /// \brief Equivalent to <tt>seq.pop_back()</tt>. |
274 | /// \return \c void |
275 | template<typename Sequence> |
276 | void operator()(Sequence &seq) const |
277 | { |
278 | seq.pop_back(); |
279 | } |
280 | }; |
281 | |
282 | /// \brief \c pop_front is a PolymorphicFunctionObject for popping an element from the front of a container. |
283 | struct pop_front |
284 | { |
285 | BOOST_PROTO_CALLABLE() |
286 | typedef void result_type; |
287 | |
288 | /// \param seq The sequence from which to pop. |
289 | /// \brief Equivalent to <tt>seq.pop_front()</tt>. |
290 | /// \return \c void |
291 | template<typename Sequence> |
292 | void operator()(Sequence &seq) const |
293 | { |
294 | seq.pop_front(); |
295 | } |
296 | }; |
297 | |
298 | /// \brief \c front is a PolymorphicFunctionObject for fetching the front element of a container. |
299 | struct front |
300 | { |
301 | BOOST_PROTO_CALLABLE() |
302 | template<typename Sig> |
303 | struct result {}; |
304 | |
305 | template<typename This, typename Sequence> |
306 | struct result<This(Sequence)> |
307 | { |
308 | typedef typename remove_reference<Sequence>::type sequence_type; |
309 | typedef |
310 | typename mpl::if_c< |
311 | is_const<sequence_type>::value |
312 | , typename sequence_type::const_reference |
313 | , typename sequence_type::reference |
314 | >::type |
315 | type; |
316 | }; |
317 | |
318 | /// \param seq The sequence from which to fetch the front. |
319 | /// \return <tt>seq.front()</tt> |
320 | template<typename Sequence> |
321 | typename result<front(Sequence &)>::type operator()(Sequence &seq) const |
322 | { |
323 | return seq.front(); |
324 | } |
325 | }; |
326 | |
327 | /// \brief \c back is a PolymorphicFunctionObject for fetching the back element of a container. |
328 | struct back |
329 | { |
330 | BOOST_PROTO_CALLABLE() |
331 | template<typename Sig> |
332 | struct result {}; |
333 | |
334 | template<typename This, typename Sequence> |
335 | struct result<This(Sequence)> |
336 | { |
337 | typedef typename remove_reference<Sequence>::type sequence_type; |
338 | typedef |
339 | typename mpl::if_c< |
340 | is_const<sequence_type>::value |
341 | , typename sequence_type::const_reference |
342 | , typename sequence_type::reference |
343 | >::type |
344 | type; |
345 | }; |
346 | |
347 | /// \param seq The sequence from which to fetch the back. |
348 | /// \return <tt>seq.back()</tt> |
349 | template<typename Sequence> |
350 | typename result<back(Sequence &)>::type operator()(Sequence &seq) const |
351 | { |
352 | return seq.back(); |
353 | } |
354 | }; |
355 | |
356 | /// \brief \c top is a PolymorphicFunctionObject for fetching the top element of a stack. |
357 | struct top |
358 | { |
359 | BOOST_PROTO_CALLABLE() |
360 | template<typename Sig> |
361 | struct result {}; |
362 | |
363 | template<typename This, typename Sequence> |
364 | struct result<This(Sequence)> |
365 | { |
366 | typedef typename remove_reference<Sequence>::type sequence_type; |
367 | typedef |
368 | typename mpl::if_c< |
369 | is_const<sequence_type>::value |
370 | , typename sequence_type::value_type const & |
371 | , typename sequence_type::value_type & |
372 | >::type |
373 | type; |
374 | }; |
375 | |
376 | /// \param seq The sequence from which to fetch the top. |
377 | /// \return <tt>seq.top()</tt> |
378 | template<typename Sequence> |
379 | typename result<top(Sequence &)>::type operator()(Sequence &seq) const |
380 | { |
381 | return seq.top(); |
382 | } |
383 | }; |
384 | |
385 | /// \brief \c first is a PolymorphicFunctionObject for fetching the first element of a pair. |
386 | struct first |
387 | { |
388 | BOOST_PROTO_CALLABLE() |
389 | template<typename Sig> |
390 | struct result {}; |
391 | |
392 | template<typename This, typename Pair> |
393 | struct result<This(Pair)> |
394 | { |
395 | typedef typename remove_reference<Pair>::type::first_type type; |
396 | }; |
397 | |
398 | /// \param p The pair from which to fetch the first element. |
399 | /// \return <tt>p.first</tt> |
400 | template<typename Pair> |
401 | typename Pair::first_type operator()(Pair const &p) const |
402 | { |
403 | return p.first; |
404 | } |
405 | }; |
406 | |
407 | /// \brief \c second is a PolymorphicFunctionObject for fetching the second element of a pair. |
408 | struct second |
409 | { |
410 | BOOST_PROTO_CALLABLE() |
411 | template<typename Sig> |
412 | struct result {}; |
413 | |
414 | template<typename This, typename Pair> |
415 | struct result<This(Pair)> |
416 | { |
417 | typedef typename remove_reference<Pair>::type::second_type type; |
418 | }; |
419 | |
420 | /// \param p The pair from which to fetch the second element. |
421 | /// \return <tt>p.second</tt> |
422 | template<typename Pair> |
423 | typename Pair::second_type operator()(Pair const &p) const |
424 | { |
425 | return p.second; |
426 | } |
427 | }; |
428 | |
429 | /// \brief \c matched is a PolymorphicFunctionObject for assessing whether a \c sub_match object |
430 | /// matched or not. |
431 | struct matched |
432 | { |
433 | BOOST_PROTO_CALLABLE() |
434 | typedef bool result_type; |
435 | |
436 | /// \param sub The \c sub_match object. |
437 | /// \return <tt>sub.matched</tt> |
438 | template<typename Sub> |
439 | bool operator()(Sub const &sub) const |
440 | { |
441 | return sub.matched; |
442 | } |
443 | }; |
444 | |
445 | /// \brief \c length is a PolymorphicFunctionObject for fetching the length of \c sub_match. |
446 | struct length |
447 | { |
448 | BOOST_PROTO_CALLABLE() |
449 | template<typename Sig> |
450 | struct result {}; |
451 | |
452 | template<typename This, typename Sub> |
453 | struct result<This(Sub)> |
454 | { |
455 | typedef typename remove_reference<Sub>::type::difference_type type; |
456 | }; |
457 | |
458 | /// \param sub The \c sub_match object. |
459 | /// \return <tt>sub.length()</tt> |
460 | template<typename Sub> |
461 | typename Sub::difference_type operator()(Sub const &sub) const |
462 | { |
463 | return sub.length(); |
464 | } |
465 | }; |
466 | |
467 | /// \brief \c str is a PolymorphicFunctionObject for turning a \c sub_match into an |
468 | /// equivalent \c std::string. |
469 | struct str |
470 | { |
471 | BOOST_PROTO_CALLABLE() |
472 | template<typename Sig> |
473 | struct result {}; |
474 | |
475 | template<typename This, typename Sub> |
476 | struct result<This(Sub)> |
477 | { |
478 | typedef typename remove_reference<Sub>::type::string_type type; |
479 | }; |
480 | |
481 | /// \param sub The \c sub_match object. |
482 | /// \return <tt>sub.str()</tt> |
483 | template<typename Sub> |
484 | typename Sub::string_type operator()(Sub const &sub) const |
485 | { |
486 | return sub.str(); |
487 | } |
488 | }; |
489 | |
490 | // This codifies the return types of the various insert member |
491 | // functions found in sequence containers, the 2 flavors of |
492 | // associative containers, and strings. |
493 | // |
494 | /// \brief \c insert is a PolymorphicFunctionObject for inserting a value or a |
495 | /// sequence of values into a sequence container, an associative |
496 | /// container, or a string. |
497 | struct insert |
498 | { |
499 | BOOST_PROTO_CALLABLE() |
500 | |
501 | /// INTERNAL ONLY |
502 | /// |
503 | struct detail |
504 | { |
505 | template<typename Sig, typename EnableIf = void> |
506 | struct result_detail |
507 | {}; |
508 | |
509 | // assoc containers |
510 | template<typename This, typename Cont, typename Value> |
511 | struct result_detail<This(Cont, Value), void> |
512 | { |
513 | typedef typename remove_reference<Cont>::type cont_type; |
514 | typedef typename remove_reference<Value>::type value_type; |
515 | static cont_type &scont_; |
516 | static value_type &svalue_; |
517 | typedef char yes_type; |
518 | typedef char (&no_type)[2]; |
519 | static yes_type check_insert_return(typename cont_type::iterator); |
520 | static no_type check_insert_return(std::pair<typename cont_type::iterator, bool>); |
521 | BOOST_STATIC_CONSTANT(bool, is_iterator = (sizeof(yes_type) == sizeof(check_insert_return(scont_.insert(svalue_))))); |
522 | typedef |
523 | typename mpl::if_c< |
524 | is_iterator |
525 | , typename cont_type::iterator |
526 | , std::pair<typename cont_type::iterator, bool> |
527 | >::type |
528 | type; |
529 | }; |
530 | |
531 | // sequence containers, assoc containers, strings |
532 | template<typename This, typename Cont, typename It, typename Value> |
533 | struct result_detail<This(Cont, It, Value), |
534 | typename disable_if< |
535 | mpl::or_< |
536 | is_integral<typename remove_cv<typename remove_reference<It>::type>::type> |
537 | , is_same< |
538 | typename remove_cv<typename remove_reference<It>::type>::type |
539 | , typename remove_cv<typename remove_reference<Value>::type>::type |
540 | > |
541 | > |
542 | >::type |
543 | > |
544 | { |
545 | typedef typename remove_reference<Cont>::type::iterator type; |
546 | }; |
547 | |
548 | // strings |
549 | template<typename This, typename Cont, typename Size, typename T> |
550 | struct result_detail<This(Cont, Size, T), |
551 | typename enable_if< |
552 | is_integral<typename remove_cv<typename remove_reference<Size>::type>::type> |
553 | >::type |
554 | > |
555 | { |
556 | typedef typename remove_reference<Cont>::type &type; |
557 | }; |
558 | |
559 | // assoc containers |
560 | template<typename This, typename Cont, typename It> |
561 | struct result_detail<This(Cont, It, It), void> |
562 | { |
563 | typedef void type; |
564 | }; |
565 | |
566 | // sequence containers, strings |
567 | template<typename This, typename Cont, typename It, typename Size, typename Value> |
568 | struct result_detail<This(Cont, It, Size, Value), |
569 | typename disable_if< |
570 | is_integral<typename remove_cv<typename remove_reference<It>::type>::type> |
571 | >::type |
572 | > |
573 | { |
574 | typedef void type; |
575 | }; |
576 | |
577 | // strings |
578 | template<typename This, typename Cont, typename Size, typename A0, typename A1> |
579 | struct result_detail<This(Cont, Size, A0, A1), |
580 | typename enable_if< |
581 | is_integral<typename remove_cv<typename remove_reference<Size>::type>::type> |
582 | >::type |
583 | > |
584 | { |
585 | typedef typename remove_reference<Cont>::type &type; |
586 | }; |
587 | |
588 | // strings |
589 | template<typename This, typename Cont, typename Pos0, typename String, typename Pos1, typename Length> |
590 | struct result_detail<This(Cont, Pos0, String, Pos1, Length)> |
591 | { |
592 | typedef typename remove_reference<Cont>::type &type; |
593 | }; |
594 | }; |
595 | |
596 | template<typename Sig> |
597 | struct result |
598 | { |
599 | typedef typename detail::result_detail<Sig>::type type; |
600 | }; |
601 | |
602 | /// \overload |
603 | /// |
604 | template<typename Cont, typename A0> |
605 | typename result<insert(Cont &, A0 const &)>::type |
606 | operator()(Cont &cont, A0 const &a0) const |
607 | { |
608 | return cont.insert(a0); |
609 | } |
610 | |
611 | /// \overload |
612 | /// |
613 | template<typename Cont, typename A0, typename A1> |
614 | typename result<insert(Cont &, A0 const &, A1 const &)>::type |
615 | operator()(Cont &cont, A0 const &a0, A1 const &a1) const |
616 | { |
617 | return cont.insert(a0, a1); |
618 | } |
619 | |
620 | /// \overload |
621 | /// |
622 | template<typename Cont, typename A0, typename A1, typename A2> |
623 | typename result<insert(Cont &, A0 const &, A1 const &, A2 const &)>::type |
624 | operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2) const |
625 | { |
626 | return cont.insert(a0, a1, a2); |
627 | } |
628 | |
629 | /// \param cont The container into which to insert the element(s) |
630 | /// \param a0 A value, iterator, or count |
631 | /// \param a1 A value, iterator, string, count, or character |
632 | /// \param a2 A value, iterator, or count |
633 | /// \param a3 A count |
634 | /// \return \li For the form <tt>insert()(cont, a0)</tt>, return <tt>cont.insert(a0)</tt>. |
635 | /// \li For the form <tt>insert()(cont, a0, a1)</tt>, return <tt>cont.insert(a0, a1)</tt>. |
636 | /// \li For the form <tt>insert()(cont, a0, a1, a2)</tt>, return <tt>cont.insert(a0, a1, a2)</tt>. |
637 | /// \li For the form <tt>insert()(cont, a0, a1, a2, a3)</tt>, return <tt>cont.insert(a0, a1, a2, a3)</tt>. |
638 | template<typename Cont, typename A0, typename A1, typename A2, typename A3> |
639 | typename result<insert(Cont &, A0 const &, A1 const &, A2 const &, A3 const &)>::type |
640 | operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2, A3 const &a3) const |
641 | { |
642 | return cont.insert(a0, a1, a2, a3); |
643 | } |
644 | }; |
645 | |
646 | /// \brief \c make_pair is a PolymorphicFunctionObject for building a \c std::pair out of two parameters |
647 | struct make_pair |
648 | { |
649 | BOOST_PROTO_CALLABLE() |
650 | template<typename Sig> |
651 | struct result {}; |
652 | |
653 | template<typename This, typename First, typename Second> |
654 | struct result<This(First, Second)> |
655 | { |
656 | /// \brief For exposition only |
657 | typedef typename decay<First>::type first_type; |
658 | /// \brief For exposition only |
659 | typedef typename decay<Second>::type second_type; |
660 | typedef std::pair<first_type, second_type> type; |
661 | }; |
662 | |
663 | /// \param first The first element of the pair |
664 | /// \param second The second element of the pair |
665 | /// \return <tt>std::make_pair(first, second)</tt> |
666 | template<typename First, typename Second> |
667 | std::pair<First, Second> operator()(First const &first, Second const &second) const |
668 | { |
669 | return std::make_pair(first, second); |
670 | } |
671 | }; |
672 | |
673 | /// \brief \c as\<\> is a PolymorphicFunctionObject for lexically casting a parameter to a different type. |
674 | /// \tparam T The type to which to lexically cast the parameter. |
675 | template<typename T> |
676 | struct as |
677 | { |
678 | BOOST_PROTO_CALLABLE() |
679 | typedef T result_type; |
680 | |
681 | /// \param val The value to lexically cast. |
682 | /// \return <tt>boost::lexical_cast\<T\>(val)</tt> |
683 | template<typename Value> |
684 | T operator()(Value const &val) const |
685 | { |
686 | return boost::lexical_cast<T>(val); |
687 | } |
688 | |
689 | // Hack around some limitations in boost::lexical_cast |
690 | /// INTERNAL ONLY |
691 | T operator()(csub_match const &val) const |
692 | { |
693 | return val.matched |
694 | ? boost::lexical_cast<T>(boost::make_iterator_range(Begin: val.first, End: val.second)) |
695 | : boost::lexical_cast<T>("" ); |
696 | } |
697 | |
698 | #ifndef BOOST_XPRESSIVE_NO_WREGEX |
699 | /// INTERNAL ONLY |
700 | T operator()(wcsub_match const &val) const |
701 | { |
702 | return val.matched |
703 | ? boost::lexical_cast<T>(boost::make_iterator_range(Begin: val.first, End: val.second)) |
704 | : boost::lexical_cast<T>("" ); |
705 | } |
706 | #endif |
707 | |
708 | /// INTERNAL ONLY |
709 | template<typename BidiIter> |
710 | T operator()(sub_match<BidiIter> const &val) const |
711 | { |
712 | // If this assert fires, you're trying to coerce a sequences of non-characters |
713 | // to some other type. Xpressive doesn't know how to do that. |
714 | typedef typename iterator_value<BidiIter>::type char_type; |
715 | BOOST_MPL_ASSERT_MSG( |
716 | (xpressive::detail::is_char<char_type>::value) |
717 | , CAN_ONLY_CONVERT_FROM_CHARACTER_SEQUENCES |
718 | , (char_type) |
719 | ); |
720 | return this->impl(val, xpressive::detail::is_string_iterator<BidiIter>()); |
721 | } |
722 | |
723 | private: |
724 | /// INTERNAL ONLY |
725 | template<typename RandIter> |
726 | T impl(sub_match<RandIter> const &val, mpl::true_) const |
727 | { |
728 | return val.matched |
729 | ? boost::lexical_cast<T>(boost::make_iterator_range(&*val.first, &*val.first + (val.second - val.first))) |
730 | : boost::lexical_cast<T>("" ); |
731 | } |
732 | |
733 | /// INTERNAL ONLY |
734 | template<typename BidiIter> |
735 | T impl(sub_match<BidiIter> const &val, mpl::false_) const |
736 | { |
737 | return boost::lexical_cast<T>(val.str()); |
738 | } |
739 | }; |
740 | |
741 | /// \brief \c static_cast_\<\> is a PolymorphicFunctionObject for statically casting a parameter to a different type. |
742 | /// \tparam T The type to which to statically cast the parameter. |
743 | template<typename T> |
744 | struct static_cast_ |
745 | { |
746 | BOOST_PROTO_CALLABLE() |
747 | typedef T result_type; |
748 | |
749 | /// \param val The value to statically cast. |
750 | /// \return <tt>static_cast\<T\>(val)</tt> |
751 | template<typename Value> |
752 | T operator()(Value const &val) const |
753 | { |
754 | return static_cast<T>(val); |
755 | } |
756 | }; |
757 | |
758 | /// \brief \c dynamic_cast_\<\> is a PolymorphicFunctionObject for dynamically casting a parameter to a different type. |
759 | /// \tparam T The type to which to dynamically cast the parameter. |
760 | template<typename T> |
761 | struct dynamic_cast_ |
762 | { |
763 | BOOST_PROTO_CALLABLE() |
764 | typedef T result_type; |
765 | |
766 | /// \param val The value to dynamically cast. |
767 | /// \return <tt>dynamic_cast\<T\>(val)</tt> |
768 | template<typename Value> |
769 | T operator()(Value const &val) const |
770 | { |
771 | return dynamic_cast<T>(val); |
772 | } |
773 | }; |
774 | |
775 | /// \brief \c const_cast_\<\> is a PolymorphicFunctionObject for const-casting a parameter to a cv qualification. |
776 | /// \tparam T The type to which to const-cast the parameter. |
777 | template<typename T> |
778 | struct const_cast_ |
779 | { |
780 | BOOST_PROTO_CALLABLE() |
781 | typedef T result_type; |
782 | |
783 | /// \param val The value to const-cast. |
784 | /// \pre Types \c T and \c Value differ only in cv-qualification. |
785 | /// \return <tt>const_cast\<T\>(val)</tt> |
786 | template<typename Value> |
787 | T operator()(Value const &val) const |
788 | { |
789 | return const_cast<T>(val); |
790 | } |
791 | }; |
792 | |
793 | /// \brief \c construct\<\> is a PolymorphicFunctionObject for constructing a new object. |
794 | /// \tparam T The type of the object to construct. |
795 | template<typename T> |
796 | struct construct |
797 | { |
798 | BOOST_PROTO_CALLABLE() |
799 | typedef T result_type; |
800 | |
801 | /// \overload |
802 | T operator()() const |
803 | { |
804 | return T(); |
805 | } |
806 | |
807 | /// \overload |
808 | template<typename A0> |
809 | T operator()(A0 const &a0) const |
810 | { |
811 | return T(a0); |
812 | } |
813 | |
814 | /// \overload |
815 | template<typename A0, typename A1> |
816 | T operator()(A0 const &a0, A1 const &a1) const |
817 | { |
818 | return T(a0, a1); |
819 | } |
820 | |
821 | /// \param a0 The first argument to the constructor |
822 | /// \param a1 The second argument to the constructor |
823 | /// \param a2 The third argument to the constructor |
824 | /// \return <tt>T(a0,a1,...)</tt> |
825 | template<typename A0, typename A1, typename A2> |
826 | T operator()(A0 const &a0, A1 const &a1, A2 const &a2) const |
827 | { |
828 | return T(a0, a1, a2); |
829 | } |
830 | }; |
831 | |
832 | /// \brief \c throw_\<\> is a PolymorphicFunctionObject for throwing an exception. |
833 | /// \tparam Except The type of the object to throw. |
834 | template<typename Except> |
835 | struct throw_ |
836 | { |
837 | BOOST_PROTO_CALLABLE() |
838 | typedef void result_type; |
839 | |
840 | /// \overload |
841 | void operator()() const |
842 | { |
843 | BOOST_THROW_EXCEPTION(Except()); |
844 | } |
845 | |
846 | /// \overload |
847 | template<typename A0> |
848 | void operator()(A0 const &a0) const |
849 | { |
850 | BOOST_THROW_EXCEPTION(Except(a0)); |
851 | } |
852 | |
853 | /// \overload |
854 | template<typename A0, typename A1> |
855 | void operator()(A0 const &a0, A1 const &a1) const |
856 | { |
857 | BOOST_THROW_EXCEPTION(Except(a0, a1)); |
858 | } |
859 | |
860 | /// \param a0 The first argument to the constructor |
861 | /// \param a1 The second argument to the constructor |
862 | /// \param a2 The third argument to the constructor |
863 | /// \throw <tt>Except(a0,a1,...)</tt> |
864 | /// \note This function makes use of the \c BOOST_THROW_EXCEPTION macro |
865 | /// to actually throw the exception. See the documentation for the |
866 | /// Boost.Exception library. |
867 | template<typename A0, typename A1, typename A2> |
868 | void operator()(A0 const &a0, A1 const &a1, A2 const &a2) const |
869 | { |
870 | BOOST_THROW_EXCEPTION(Except(a0, a1, a2)); |
871 | } |
872 | }; |
873 | |
874 | /// \brief \c unwrap_reference is a PolymorphicFunctionObject for unwrapping a <tt>boost::reference_wrapper\<\></tt>. |
875 | struct unwrap_reference |
876 | { |
877 | BOOST_PROTO_CALLABLE() |
878 | template<typename Sig> |
879 | struct result {}; |
880 | |
881 | template<typename This, typename Ref> |
882 | struct result<This(Ref)> |
883 | { |
884 | typedef typename boost::unwrap_reference<Ref>::type &type; |
885 | }; |
886 | |
887 | template<typename This, typename Ref> |
888 | struct result<This(Ref &)> |
889 | { |
890 | typedef typename boost::unwrap_reference<Ref>::type &type; |
891 | }; |
892 | |
893 | /// \param r The <tt>boost::reference_wrapper\<T\></tt> to unwrap. |
894 | /// \return <tt>static_cast\<T &\>(r)</tt> |
895 | template<typename T> |
896 | T &operator()(boost::reference_wrapper<T> r) const |
897 | { |
898 | return static_cast<T &>(r); |
899 | } |
900 | }; |
901 | } |
902 | |
903 | /// \brief A unary metafunction that turns an ordinary function object type into the type of |
904 | /// a deferred function object for use in xpressive semantic actions. |
905 | /// |
906 | /// Use \c xpressive::function\<\> to turn an ordinary polymorphic function object type |
907 | /// into a type that can be used to declare an object for use in xpressive semantic actions. |
908 | /// |
909 | /// For example, the global object \c xpressive::push_back can be used to create deferred actions |
910 | /// that have the effect of pushing a value into a container. It is defined with |
911 | /// \c xpressive::function\<\> as follows: |
912 | /// |
913 | /** \code |
914 | xpressive::function<xpressive::op::push_back>::type const push_back = {}; |
915 | \endcode |
916 | */ |
917 | /// |
918 | /// where \c op::push_back is an ordinary function object that pushes its second argument into |
919 | /// its first. Thus defined, \c xpressive::push_back can be used in semantic actions as follows: |
920 | /// |
921 | /** \code |
922 | namespace xp = boost::xpressive; |
923 | using xp::_; |
924 | std::list<int> result; |
925 | std::string str("1 23 456 7890"); |
926 | xp::sregex rx = (+_d)[ xp::push_back(xp::ref(result), xp::as<int>(_) ] |
927 | >> *(' ' >> (+_d)[ xp::push_back(xp::ref(result), xp::as<int>(_) ) ]); |
928 | \endcode |
929 | */ |
930 | template<typename PolymorphicFunctionObject> |
931 | struct function |
932 | { |
933 | typedef typename proto::terminal<PolymorphicFunctionObject>::type type; |
934 | }; |
935 | |
936 | /// \brief \c at is a lazy PolymorphicFunctionObject for indexing into a sequence in an |
937 | /// xpressive semantic action. |
938 | function<op::at>::type const at = {.child0: {}}; |
939 | |
940 | /// \brief \c push is a lazy PolymorphicFunctionObject for pushing a value into a container in an |
941 | /// xpressive semantic action. |
942 | function<op::push>::type const push = {.child0: {}}; |
943 | |
944 | /// \brief \c push_back is a lazy PolymorphicFunctionObject for pushing a value into a container in an |
945 | /// xpressive semantic action. |
946 | function<op::push_back>::type const push_back = {.child0: {}}; |
947 | |
948 | /// \brief \c push_front is a lazy PolymorphicFunctionObject for pushing a value into a container in an |
949 | /// xpressive semantic action. |
950 | function<op::push_front>::type const push_front = {.child0: {}}; |
951 | |
952 | /// \brief \c pop is a lazy PolymorphicFunctionObject for popping the top element from a sequence in an |
953 | /// xpressive semantic action. |
954 | function<op::pop>::type const pop = {.child0: {}}; |
955 | |
956 | /// \brief \c pop_back is a lazy PolymorphicFunctionObject for popping the back element from a sequence in an |
957 | /// xpressive semantic action. |
958 | function<op::pop_back>::type const pop_back = {.child0: {}}; |
959 | |
960 | /// \brief \c pop_front is a lazy PolymorphicFunctionObject for popping the front element from a sequence in an |
961 | /// xpressive semantic action. |
962 | function<op::pop_front>::type const pop_front = {.child0: {}}; |
963 | |
964 | /// \brief \c top is a lazy PolymorphicFunctionObject for accessing the top element from a stack in an |
965 | /// xpressive semantic action. |
966 | function<op::top>::type const top = {.child0: {}}; |
967 | |
968 | /// \brief \c back is a lazy PolymorphicFunctionObject for fetching the back element of a sequence in an |
969 | /// xpressive semantic action. |
970 | function<op::back>::type const back = {.child0: {}}; |
971 | |
972 | /// \brief \c front is a lazy PolymorphicFunctionObject for fetching the front element of a sequence in an |
973 | /// xpressive semantic action. |
974 | function<op::front>::type const front = {.child0: {}}; |
975 | |
976 | /// \brief \c first is a lazy PolymorphicFunctionObject for accessing the first element of a \c std::pair\<\> in an |
977 | /// xpressive semantic action. |
978 | function<op::first>::type const first = {.child0: {}}; |
979 | |
980 | /// \brief \c second is a lazy PolymorphicFunctionObject for accessing the second element of a \c std::pair\<\> in an |
981 | /// xpressive semantic action. |
982 | function<op::second>::type const second = {.child0: {}}; |
983 | |
984 | /// \brief \c matched is a lazy PolymorphicFunctionObject for accessing the \c matched member of a \c xpressive::sub_match\<\> in an |
985 | /// xpressive semantic action. |
986 | function<op::matched>::type const matched = {.child0: {}}; |
987 | |
988 | /// \brief \c length is a lazy PolymorphicFunctionObject for computing the length of a \c xpressive::sub_match\<\> in an |
989 | /// xpressive semantic action. |
990 | function<op::length>::type const length = {.child0: {}}; |
991 | |
992 | /// \brief \c str is a lazy PolymorphicFunctionObject for converting a \c xpressive::sub_match\<\> to a \c std::basic_string\<\> in an |
993 | /// xpressive semantic action. |
994 | function<op::str>::type const str = {.child0: {}}; |
995 | |
996 | /// \brief \c insert is a lazy PolymorphicFunctionObject for inserting a value or a range of values into a sequence in an |
997 | /// xpressive semantic action. |
998 | function<op::insert>::type const insert = {.child0: {}}; |
999 | |
1000 | /// \brief \c make_pair is a lazy PolymorphicFunctionObject for making a \c std::pair\<\> in an |
1001 | /// xpressive semantic action. |
1002 | function<op::make_pair>::type const make_pair = {.child0: {}}; |
1003 | |
1004 | /// \brief \c unwrap_reference is a lazy PolymorphicFunctionObject for unwrapping a \c boost::reference_wrapper\<\> in an |
1005 | /// xpressive semantic action. |
1006 | function<op::unwrap_reference>::type const unwrap_reference = {.child0: {}}; |
1007 | |
1008 | /// \brief \c value\<\> is a lazy wrapper for a value that can be used in xpressive semantic actions. |
1009 | /// \tparam T The type of the value to store. |
1010 | /// |
1011 | /// Below is an example that shows where \c <tt>value\<\></tt> is useful. |
1012 | /// |
1013 | /** \code |
1014 | sregex good_voodoo(boost::shared_ptr<int> pi) |
1015 | { |
1016 | using namespace boost::xpressive; |
1017 | // Use val() to hold the shared_ptr by value: |
1018 | sregex rex = +( _d [ ++*val(pi) ] >> '!' ); |
1019 | // OK, rex holds a reference count to the integer. |
1020 | return rex; |
1021 | } |
1022 | \endcode |
1023 | */ |
1024 | /// |
1025 | /// In the above code, \c xpressive::val() is a function that returns a \c value\<\> object. Had |
1026 | /// \c val() not been used here, the operation <tt>++*pi</tt> would have been evaluated eagerly |
1027 | /// once, instead of lazily when the regex match happens. |
1028 | template<typename T> |
1029 | struct value |
1030 | : proto::extends<typename proto::terminal<T>::type, value<T> > |
1031 | { |
1032 | /// INTERNAL ONLY |
1033 | typedef proto::extends<typename proto::terminal<T>::type, value<T> > base_type; |
1034 | |
1035 | /// \brief Store a default-constructed \c T |
1036 | value() |
1037 | : base_type() |
1038 | {} |
1039 | |
1040 | /// \param t The initial value. |
1041 | /// \brief Store a copy of \c t. |
1042 | explicit value(T const &t) |
1043 | : base_type(base_type::proto_base_expr::make(t)) |
1044 | {} |
1045 | |
1046 | using base_type::operator=; |
1047 | |
1048 | /// \overload |
1049 | T &get() |
1050 | { |
1051 | return proto::value(*this); |
1052 | } |
1053 | |
1054 | /// \brief Fetch the stored value |
1055 | T const &get() const |
1056 | { |
1057 | return proto::value(*this); |
1058 | } |
1059 | }; |
1060 | |
1061 | /// \brief \c reference\<\> is a lazy wrapper for a reference that can be used in |
1062 | /// xpressive semantic actions. |
1063 | /// |
1064 | /// \tparam T The type of the referent. |
1065 | /// |
1066 | /// Here is an example of how to use \c reference\<\> to create a lazy reference to |
1067 | /// an existing object so it can be read and written in an xpressive semantic action. |
1068 | /// |
1069 | /** \code |
1070 | using namespace boost::xpressive; |
1071 | std::map<std::string, int> result; |
1072 | reference<std::map<std::string, int> > result_ref(result); |
1073 | |
1074 | // Match a word and an integer, separated by =>, |
1075 | // and then stuff the result into a std::map<> |
1076 | sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) |
1077 | [ result_ref[s1] = as<int>(s2) ]; |
1078 | \endcode |
1079 | */ |
1080 | template<typename T> |
1081 | struct reference |
1082 | : proto::extends<typename proto::terminal<reference_wrapper<T> >::type, reference<T> > |
1083 | { |
1084 | /// INTERNAL ONLY |
1085 | typedef proto::extends<typename proto::terminal<reference_wrapper<T> >::type, reference<T> > base_type; |
1086 | |
1087 | /// \param t Reference to object |
1088 | /// \brief Store a reference to \c t |
1089 | explicit reference(T &t) |
1090 | : base_type(base_type::proto_base_expr::make(boost::ref(t))) |
1091 | {} |
1092 | |
1093 | using base_type::operator=; |
1094 | |
1095 | /// \brief Fetch the stored value |
1096 | T &get() const |
1097 | { |
1098 | return proto::value(*this).get(); |
1099 | } |
1100 | }; |
1101 | |
1102 | /// \brief \c local\<\> is a lazy wrapper for a reference to a value that is stored within the local itself. |
1103 | /// It is for use within xpressive semantic actions. |
1104 | /// |
1105 | /// \tparam T The type of the local variable. |
1106 | /// |
1107 | /// Below is an example of how to use \c local\<\> in semantic actions. |
1108 | /// |
1109 | /** \code |
1110 | using namespace boost::xpressive; |
1111 | local<int> i(0); |
1112 | std::string str("1!2!3?"); |
1113 | // count the exciting digits, but not the |
1114 | // questionable ones. |
1115 | sregex rex = +( _d [ ++i ] >> '!' ); |
1116 | regex_search(str, rex); |
1117 | assert( i.get() == 2 ); |
1118 | \endcode |
1119 | */ |
1120 | /// |
1121 | /// \note As the name "local" suggests, \c local\<\> objects and the regexes |
1122 | /// that refer to them should never leave the local scope. The value stored |
1123 | /// within the local object will be destroyed at the end of the \c local\<\>'s |
1124 | /// lifetime, and any regex objects still holding the \c local\<\> will be |
1125 | /// left with a dangling reference. |
1126 | template<typename T> |
1127 | struct local |
1128 | : detail::value_wrapper<T> |
1129 | , proto::terminal<reference_wrapper<T> >::type |
1130 | { |
1131 | /// INTERNAL ONLY |
1132 | typedef typename proto::terminal<reference_wrapper<T> >::type base_type; |
1133 | |
1134 | /// \brief Store a default-constructed value of type \c T |
1135 | local() |
1136 | : detail::value_wrapper<T>() |
1137 | , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value))) |
1138 | {} |
1139 | |
1140 | /// \param t The initial value. |
1141 | /// \brief Store a default-constructed value of type \c T |
1142 | explicit local(T const &t) |
1143 | : detail::value_wrapper<T>(t) |
1144 | , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value))) |
1145 | {} |
1146 | |
1147 | using base_type::operator=; |
1148 | |
1149 | /// Fetch the wrapped value. |
1150 | T &get() |
1151 | { |
1152 | return proto::value(*this); |
1153 | } |
1154 | |
1155 | /// \overload |
1156 | T const &get() const |
1157 | { |
1158 | return proto::value(*this); |
1159 | } |
1160 | }; |
1161 | |
1162 | /// \brief \c as() is a lazy funtion for lexically casting a parameter to a different type. |
1163 | /// \tparam T The type to which to lexically cast the parameter. |
1164 | /// \param a The lazy value to lexically cast. |
1165 | /// \return A lazy object that, when evaluated, lexically casts its argument to the desired type. |
1166 | template<typename T, typename A> |
1167 | typename detail::make_function::impl<op::as<T> const, A const &>::result_type const |
1168 | as(A const &a) |
1169 | { |
1170 | return detail::make_function::impl<op::as<T> const, A const &>()((op::as<T>()), a); |
1171 | } |
1172 | |
1173 | /// \brief \c static_cast_ is a lazy funtion for statically casting a parameter to a different type. |
1174 | /// \tparam T The type to which to statically cast the parameter. |
1175 | /// \param a The lazy value to statically cast. |
1176 | /// \return A lazy object that, when evaluated, statically casts its argument to the desired type. |
1177 | template<typename T, typename A> |
1178 | typename detail::make_function::impl<op::static_cast_<T> const, A const &>::result_type const |
1179 | static_cast_(A const &a) |
1180 | { |
1181 | return detail::make_function::impl<op::static_cast_<T> const, A const &>()((op::static_cast_<T>()), a); |
1182 | } |
1183 | |
1184 | /// \brief \c dynamic_cast_ is a lazy funtion for dynamically casting a parameter to a different type. |
1185 | /// \tparam T The type to which to dynamically cast the parameter. |
1186 | /// \param a The lazy value to dynamically cast. |
1187 | /// \return A lazy object that, when evaluated, dynamically casts its argument to the desired type. |
1188 | template<typename T, typename A> |
1189 | typename detail::make_function::impl<op::dynamic_cast_<T> const, A const &>::result_type const |
1190 | dynamic_cast_(A const &a) |
1191 | { |
1192 | return detail::make_function::impl<op::dynamic_cast_<T> const, A const &>()((op::dynamic_cast_<T>()), a); |
1193 | } |
1194 | |
1195 | /// \brief \c dynamic_cast_ is a lazy funtion for const-casting a parameter to a different type. |
1196 | /// \tparam T The type to which to const-cast the parameter. |
1197 | /// \param a The lazy value to const-cast. |
1198 | /// \return A lazy object that, when evaluated, const-casts its argument to the desired type. |
1199 | template<typename T, typename A> |
1200 | typename detail::make_function::impl<op::const_cast_<T> const, A const &>::result_type const |
1201 | const_cast_(A const &a) |
1202 | { |
1203 | return detail::make_function::impl<op::const_cast_<T> const, A const &>()((op::const_cast_<T>()), a); |
1204 | } |
1205 | |
1206 | /// \brief Helper for constructing \c value\<\> objects. |
1207 | /// \return <tt>value\<T\>(t)</tt> |
1208 | template<typename T> |
1209 | value<T> const val(T const &t) |
1210 | { |
1211 | return value<T>(t); |
1212 | } |
1213 | |
1214 | /// \brief Helper for constructing \c reference\<\> objects. |
1215 | /// \return <tt>reference\<T\>(t)</tt> |
1216 | template<typename T> |
1217 | reference<T> const ref(T &t) |
1218 | { |
1219 | return reference<T>(t); |
1220 | } |
1221 | |
1222 | /// \brief Helper for constructing \c reference\<\> objects that |
1223 | /// store a reference to const. |
1224 | /// \return <tt>reference\<T const\>(t)</tt> |
1225 | template<typename T> |
1226 | reference<T const> const cref(T const &t) |
1227 | { |
1228 | return reference<T const>(t); |
1229 | } |
1230 | |
1231 | /// \brief For adding user-defined assertions to your regular expressions. |
1232 | /// |
1233 | /// \param t The UnaryPredicate object or Boolean semantic action. |
1234 | /// |
1235 | /// A \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.user_defined_assertions,user-defined assertion} |
1236 | /// is a kind of semantic action that evaluates |
1237 | /// a Boolean lambda and, if it evaluates to false, causes the match to |
1238 | /// fail at that location in the string. This will cause backtracking, |
1239 | /// so the match may ultimately succeed. |
1240 | /// |
1241 | /// To use \c check() to specify a user-defined assertion in a regex, use the |
1242 | /// following syntax: |
1243 | /// |
1244 | /** \code |
1245 | sregex s = (_d >> _d)[check( XXX )]; // XXX is a custom assertion |
1246 | \endcode |
1247 | */ |
1248 | /// |
1249 | /// The assertion is evaluated with a \c sub_match\<\> object that delineates |
1250 | /// what part of the string matched the sub-expression to which the assertion |
1251 | /// was attached. |
1252 | /// |
1253 | /// \c check() can be used with an ordinary predicate that takes a |
1254 | /// \c sub_match\<\> object as follows: |
1255 | /// |
1256 | /** \code |
1257 | // A predicate that is true IFF a sub-match is |
1258 | // either 3 or 6 characters long. |
1259 | struct three_or_six |
1260 | { |
1261 | bool operator()(ssub_match const &sub) const |
1262 | { |
1263 | return sub.length() == 3 || sub.length() == 6; |
1264 | } |
1265 | }; |
1266 | |
1267 | // match words of 3 characters or 6 characters. |
1268 | sregex rx = (bow >> +_w >> eow)[ check(three_or_six()) ] ; |
1269 | \endcode |
1270 | */ |
1271 | /// |
1272 | /// Alternately, \c check() can be used to define inline custom |
1273 | /// assertions with the same syntax as is used to define semantic |
1274 | /// actions. The following code is equivalent to above: |
1275 | /// |
1276 | /** \code |
1277 | // match words of 3 characters or 6 characters. |
1278 | sregex rx = (bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ] ; |
1279 | \endcode |
1280 | */ |
1281 | /// |
1282 | /// Within a custom assertion, \c _ is a placeholder for the \c sub_match\<\> |
1283 | /// That delineates the part of the string matched by the sub-expression to |
1284 | /// which the custom assertion was attached. |
1285 | #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. |
1286 | template<typename T> |
1287 | detail::unspecified check(T const &t); |
1288 | #else |
1289 | proto::terminal<detail::check_tag>::type const check = {.child0: {}}; |
1290 | #endif |
1291 | |
1292 | /// \brief For binding local variables to placeholders in semantic actions when |
1293 | /// constructing a \c regex_iterator or a \c regex_token_iterator. |
1294 | /// |
1295 | /// \param args A set of argument bindings, where each argument binding is an assignment |
1296 | /// expression, the left hand side of which must be an instance of \c placeholder\<X\> |
1297 | /// for some \c X, and the right hand side is an lvalue of type \c X. |
1298 | /// |
1299 | /// \c xpressive::let() serves the same purpose as <tt>match_results::let()</tt>; |
1300 | /// that is, it binds a placeholder to a local value. The purpose is to allow a |
1301 | /// regex with semantic actions to be defined that refers to objects that do not yet exist. |
1302 | /// Rather than referring directly to an object, a semantic action can refer to a placeholder, |
1303 | /// and the value of the placeholder can be specified later with a <em>let expression</em>. |
1304 | /// The <em>let expression</em> created with \c let() is passed to the constructor of either |
1305 | /// \c regex_iterator or \c regex_token_iterator. |
1306 | /// |
1307 | /// See the section \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.referring_to_non_local_variables, "Referring to Non-Local Variables"} |
1308 | /// in the Users' Guide for more discussion. |
1309 | /// |
1310 | /// \em Example: |
1311 | /// |
1312 | /** |
1313 | \code |
1314 | // Define a placeholder for a map object: |
1315 | placeholder<std::map<std::string, int> > _map; |
1316 | |
1317 | // Match a word and an integer, separated by =>, |
1318 | // and then stuff the result into a std::map<> |
1319 | sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) |
1320 | [ _map[s1] = as<int>(s2) ]; |
1321 | |
1322 | // The string to parse |
1323 | std::string str("aaa=>1 bbb=>23 ccc=>456"); |
1324 | |
1325 | // Here is the actual map to fill in: |
1326 | std::map<std::string, int> result; |
1327 | |
1328 | // Create a regex_iterator to find all the matches |
1329 | sregex_iterator it(str.begin(), str.end(), pair, let(_map=result)); |
1330 | sregex_iterator end; |
1331 | |
1332 | // step through all the matches, and fill in |
1333 | // the result map |
1334 | while(it != end) |
1335 | ++it; |
1336 | |
1337 | std::cout << result["aaa"] << '\n'; |
1338 | std::cout << result["bbb"] << '\n'; |
1339 | std::cout << result["ccc"] << '\n'; |
1340 | \endcode |
1341 | */ |
1342 | /// |
1343 | /// The above code displays: |
1344 | /// |
1345 | /** \code{.txt} |
1346 | 1 |
1347 | 23 |
1348 | 456 |
1349 | \endcode |
1350 | */ |
1351 | #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. |
1352 | template<typename...ArgBindings> |
1353 | detail::unspecified let(ArgBindings const &...args); |
1354 | #else |
1355 | detail::let_<proto::terminal<detail::let_tag>::type> const let = {.proto_expr_: {.child0: {}}}; |
1356 | #endif |
1357 | |
1358 | /// \brief For defining a placeholder to stand in for a variable a semantic action. |
1359 | /// |
1360 | /// Use \c placeholder\<\> to define a placeholder for use in semantic actions to stand |
1361 | /// in for real objects. The use of placeholders allows regular expressions with actions |
1362 | /// to be defined once and reused in many contexts to read and write from objects which |
1363 | /// were not available when the regex was defined. |
1364 | /// |
1365 | /// \tparam T The type of the object for which this placeholder stands in. |
1366 | /// \tparam I An optional identifier that can be used to distinguish this placeholder |
1367 | /// from others that may be used in the same semantic action that happen |
1368 | /// to have the same type. |
1369 | /// |
1370 | /// You can use \c placeholder\<\> by creating an object of type \c placeholder\<T\> |
1371 | /// and using that object in a semantic action exactly as you intend an object of |
1372 | /// type \c T to be used. |
1373 | /// |
1374 | /** |
1375 | \code |
1376 | placeholder<int> _i; |
1377 | placeholder<double> _d; |
1378 | |
1379 | sregex rex = ( some >> regex >> here ) |
1380 | [ ++_i, _d *= _d ]; |
1381 | \endcode |
1382 | */ |
1383 | /// |
1384 | /// Then, when doing a pattern match with either \c regex_search(), |
1385 | /// \c regex_match() or \c regex_replace(), pass a \c match_results\<\> object that |
1386 | /// contains bindings for the placeholders used in the regex object's semantic actions. |
1387 | /// You can create the bindings by calling \c match_results::let as follows: |
1388 | /// |
1389 | /** |
1390 | \code |
1391 | int i = 0; |
1392 | double d = 3.14; |
1393 | |
1394 | smatch what; |
1395 | what.let(_i = i) |
1396 | .let(_d = d); |
1397 | |
1398 | if(regex_match("some string", rex, what)) |
1399 | // i and d mutated here |
1400 | \endcode |
1401 | */ |
1402 | /// |
1403 | /// If a semantic action executes that contains an unbound placeholder, a exception of |
1404 | /// type \c regex_error is thrown. |
1405 | /// |
1406 | /// See the discussion for \c xpressive::let() and the |
1407 | /// \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.referring_to_non_local_variables, "Referring to Non-Local Variables"} |
1408 | /// section in the Users' Guide for more information. |
1409 | /// |
1410 | /// <em>Example:</em> |
1411 | /// |
1412 | /** |
1413 | \code |
1414 | // Define a placeholder for a map object: |
1415 | placeholder<std::map<std::string, int> > _map; |
1416 | |
1417 | // Match a word and an integer, separated by =>, |
1418 | // and then stuff the result into a std::map<> |
1419 | sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) |
1420 | [ _map[s1] = as<int>(s2) ]; |
1421 | |
1422 | // Match one or more word/integer pairs, separated |
1423 | // by whitespace. |
1424 | sregex rx = pair >> *(+_s >> pair); |
1425 | |
1426 | // The string to parse |
1427 | std::string str("aaa=>1 bbb=>23 ccc=>456"); |
1428 | |
1429 | // Here is the actual map to fill in: |
1430 | std::map<std::string, int> result; |
1431 | |
1432 | // Bind the _map placeholder to the actual map |
1433 | smatch what; |
1434 | what.let( _map = result ); |
1435 | |
1436 | // Execute the match and fill in result map |
1437 | if(regex_match(str, what, rx)) |
1438 | { |
1439 | std::cout << result["aaa"] << '\n'; |
1440 | std::cout << result["bbb"] << '\n'; |
1441 | std::cout << result["ccc"] << '\n'; |
1442 | } |
1443 | \endcode |
1444 | */ |
1445 | #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. |
1446 | template<typename T, int I = 0> |
1447 | struct placeholder |
1448 | { |
1449 | /// \param t The object to associate with this placeholder |
1450 | /// \return An object of unspecified type that records the association of \c t |
1451 | /// with \c *this. |
1452 | detail::unspecified operator=(T &t) const; |
1453 | /// \overload |
1454 | detail::unspecified operator=(T const &t) const; |
1455 | }; |
1456 | #else |
1457 | template<typename T, int I, typename Dummy> |
1458 | struct placeholder |
1459 | { |
1460 | typedef placeholder<T, I, Dummy> this_type; |
1461 | typedef |
1462 | typename proto::terminal<detail::action_arg<T, mpl::int_<I> > >::type |
1463 | action_arg_type; |
1464 | |
1465 | BOOST_PROTO_EXTENDS(action_arg_type, this_type, proto::default_domain) |
1466 | }; |
1467 | #endif |
1468 | |
1469 | /// \brief A lazy funtion for constructing objects objects of the specified type. |
1470 | /// \tparam T The type of object to construct. |
1471 | /// \param args The arguments to the constructor. |
1472 | /// \return A lazy object that, when evaluated, returns <tt>T(xs...)</tt>, where |
1473 | /// <tt>xs...</tt> is the result of evaluating the lazy arguments |
1474 | /// <tt>args...</tt>. |
1475 | #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. |
1476 | template<typename T, typename ...Args> |
1477 | detail::unspecified construct(Args const &...args); |
1478 | #else |
1479 | /// INTERNAL ONLY |
1480 | #define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, a) \ |
1481 | template<typename X2_0 BOOST_PP_COMMA_IF(N) typename_A(N)> \ |
1482 | typename detail::make_function::impl< \ |
1483 | op::construct<X2_0> const \ |
1484 | BOOST_PP_COMMA_IF(N) A_const_ref(N) \ |
1485 | >::result_type const \ |
1486 | construct(A_const_ref_a(N)) \ |
1487 | { \ |
1488 | return detail::make_function::impl< \ |
1489 | op::construct<X2_0> const \ |
1490 | BOOST_PP_COMMA_IF(N) A_const_ref(N) \ |
1491 | >()((op::construct<X2_0>()) BOOST_PP_COMMA_IF(N) a(N)); \ |
1492 | } \ |
1493 | \ |
1494 | template<typename X2_0 BOOST_PP_COMMA_IF(N) typename_A(N)> \ |
1495 | typename detail::make_function::impl< \ |
1496 | op::throw_<X2_0> const \ |
1497 | BOOST_PP_COMMA_IF(N) A_const_ref(N) \ |
1498 | >::result_type const \ |
1499 | throw_(A_const_ref_a(N)) \ |
1500 | { \ |
1501 | return detail::make_function::impl< \ |
1502 | op::throw_<X2_0> const \ |
1503 | BOOST_PP_COMMA_IF(N) A_const_ref(N) \ |
1504 | >()((op::throw_<X2_0>()) BOOST_PP_COMMA_IF(N) a(N)); \ |
1505 | } \ |
1506 | /**/ |
1507 | |
1508 | #define BOOST_PROTO_LOCAL_a BOOST_PROTO_a ///< INTERNAL ONLY |
1509 | #define BOOST_PROTO_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)) ///< INTERNAL ONLY |
1510 | #include BOOST_PROTO_LOCAL_ITERATE() |
1511 | #endif |
1512 | |
1513 | namespace detail |
1514 | { |
1515 | inline void ignore_unused_regex_actions() |
1516 | { |
1517 | detail::ignore_unused(xpressive::at); |
1518 | detail::ignore_unused(xpressive::push); |
1519 | detail::ignore_unused(xpressive::push_back); |
1520 | detail::ignore_unused(xpressive::push_front); |
1521 | detail::ignore_unused(xpressive::pop); |
1522 | detail::ignore_unused(xpressive::pop_back); |
1523 | detail::ignore_unused(xpressive::pop_front); |
1524 | detail::ignore_unused(xpressive::top); |
1525 | detail::ignore_unused(xpressive::back); |
1526 | detail::ignore_unused(xpressive::front); |
1527 | detail::ignore_unused(xpressive::first); |
1528 | detail::ignore_unused(xpressive::second); |
1529 | detail::ignore_unused(xpressive::matched); |
1530 | detail::ignore_unused(xpressive::length); |
1531 | detail::ignore_unused(xpressive::str); |
1532 | detail::ignore_unused(xpressive::insert); |
1533 | detail::ignore_unused(xpressive::make_pair); |
1534 | detail::ignore_unused(xpressive::unwrap_reference); |
1535 | detail::ignore_unused(xpressive::check); |
1536 | detail::ignore_unused(xpressive::let); |
1537 | } |
1538 | |
1539 | struct mark_nbr |
1540 | { |
1541 | BOOST_PROTO_CALLABLE() |
1542 | typedef int result_type; |
1543 | |
1544 | int operator()(mark_placeholder m) const |
1545 | { |
1546 | return m.mark_number_; |
1547 | } |
1548 | }; |
1549 | |
1550 | struct ReplaceAlgo |
1551 | : proto::or_< |
1552 | proto::when< |
1553 | proto::terminal<mark_placeholder> |
1554 | , op::at(proto::_data, proto::call<mark_nbr(proto::_value)>) |
1555 | > |
1556 | , proto::when< |
1557 | proto::terminal<any_matcher> |
1558 | , op::at(proto::_data, proto::size_t<0>) |
1559 | > |
1560 | , proto::when< |
1561 | proto::terminal<reference_wrapper<proto::_> > |
1562 | , op::unwrap_reference(proto::_value) |
1563 | > |
1564 | , proto::_default<ReplaceAlgo> |
1565 | > |
1566 | {}; |
1567 | } |
1568 | }} |
1569 | |
1570 | #if BOOST_MSVC |
1571 | #pragma warning(pop) |
1572 | #endif |
1573 | |
1574 | #endif // BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007 |
1575 | |