Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/xpressive/regex_actions.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
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) && (_MSC_VER >= 1020) | |
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(val.first, 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(val.first, 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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{}}; | |
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 = {{{}}}; | |
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 |