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 
castboost::xpressive::detail::action_arg73             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         {
value_wrapperboost::xpressive::detail::value_wrapper83             value_wrapper()
84               : value()
85             {}
86 
value_wrapperboost::xpressive::detail::value_wrapper87             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>
operator ()boost::xpressive::detail::BindArg110             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>
bind_args(let_<Args> const & args,match_results<BidiIter> & what)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>
operator ()boost::xpressive::op::at185             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>
operator ()boost::xpressive::op::at193             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>
operator ()boost::xpressive::op::push210             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>
operator ()boost::xpressive::op::push_back227             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>
operator ()boost::xpressive::op::push_front244             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>
operator ()boost::xpressive::op::pop260             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>
operator ()boost::xpressive::op::pop_back276             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>
operator ()boost::xpressive::op::pop_front292             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>
operator ()boost::xpressive::op::front321             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>
operator ()boost::xpressive::op::back350             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>
operator ()boost::xpressive::op::top379             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>
operator ()boost::xpressive::op::first401             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>
operator ()boost::xpressive::op::second423             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>
operator ()boost::xpressive::op::matched439             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>
operator ()boost::xpressive::op::length461             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>
operator ()boost::xpressive::op::str484             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
operator ()boost::xpressive::op::insert606             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
operator ()boost::xpressive::op::insert615             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
operator ()boost::xpressive::op::insert624             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
operator ()boost::xpressive::op::insert640             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>
operator ()boost::xpressive::op::make_pair667             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>
operator ()boost::xpressive::op::as684             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
operator ()boost::xpressive::op::as691             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
operator ()boost::xpressive::op::as700             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>
operator ()boost::xpressive::op::as710             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>
implboost::xpressive::op::as726             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>
implboost::xpressive::op::as735             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>
operator ()boost::xpressive::op::static_cast_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>
operator ()boost::xpressive::op::dynamic_cast_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>
operator ()boost::xpressive::op::const_cast_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
operator ()boost::xpressive::op::construct802             T operator()() const
803             {
804                 return T();
805             }
806 
807             /// \overload
808             template<typename A0>
operator ()boost::xpressive::op::construct809             T operator()(A0 const &a0) const
810             {
811                 return T(a0);
812             }
813 
814             /// \overload
815             template<typename A0, typename A1>
operator ()boost::xpressive::op::construct816             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>
operator ()boost::xpressive::op::construct826             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
operator ()boost::xpressive::op::throw_841             void operator()() const
842             {
843                 BOOST_THROW_EXCEPTION(Except());
844             }
845 
846             /// \overload
847             template<typename A0>
operator ()boost::xpressive::op::throw_848             void operator()(A0 const &a0) const
849             {
850                 BOOST_THROW_EXCEPTION(Except(a0));
851             }
852 
853             /// \overload
854             template<typename A0, typename A1>
operator ()boost::xpressive::op::throw_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>
operator ()boost::xpressive::op::throw_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>
operator ()boost::xpressive::op::unwrap_reference896             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
valueboost::xpressive::value1036         value()
1037           : base_type()
1038         {}
1039 
1040         /// \param t The initial value.
1041         /// \brief Store a copy of \c t.
valueboost::xpressive::value1042         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
getboost::xpressive::value1049         T &get()
1050         {
1051             return proto::value(*this);
1052         }
1053 
1054         /// \brief Fetch the stored value
getboost::xpressive::value1055         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
referenceboost::xpressive::reference1089         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
getboost::xpressive::reference1096         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
localboost::xpressive::local1135         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
localboost::xpressive::local1142         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.
getboost::xpressive::local1150         T &get()
1151         {
1152             return proto::value(*this);
1153         }
1154 
1155         /// \overload
getboost::xpressive::local1156         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
as(A const & a)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
static_cast_(A const & a)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
dynamic_cast_(A const & a)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
const_cast_(A const & a)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>
val(T const & 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>
ref(T & 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>
cref(T const & 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     {
ignore_unused_regex_actions()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 
operator ()boost::xpressive::detail::mark_nbr1544             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