Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:54

0001 ///////////////////////////////////////////////////////////////////////////////
0002 /// \file regex_actions.hpp
0003 /// Defines the syntax elements of xpressive's action expressions.
0004 //
0005 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0006 //  Software License, Version 1.0. (See accompanying file
0007 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 #ifndef BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
0010 #define BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
0011 
0012 // MS compatible compilers support #pragma once
0013 #if defined(_MSC_VER)
0014 # pragma once
0015 #endif
0016 
0017 #include <boost/config.hpp>
0018 #include <boost/preprocessor/punctuation/comma_if.hpp>
0019 #include <boost/ref.hpp>
0020 #include <boost/mpl/if.hpp>
0021 #include <boost/mpl/or.hpp>
0022 #include <boost/mpl/int.hpp>
0023 #include <boost/mpl/assert.hpp>
0024 #include <boost/noncopyable.hpp>
0025 #include <boost/lexical_cast.hpp>
0026 #include <boost/throw_exception.hpp>
0027 #include <boost/utility/enable_if.hpp>
0028 #include <boost/type_traits/is_same.hpp>
0029 #include <boost/type_traits/is_const.hpp>
0030 #include <boost/type_traits/is_integral.hpp>
0031 #include <boost/type_traits/decay.hpp>
0032 #include <boost/type_traits/remove_cv.hpp>
0033 #include <boost/type_traits/remove_reference.hpp>
0034 #include <boost/range/iterator_range.hpp>
0035 #include <boost/xpressive/detail/detail_fwd.hpp>
0036 #include <boost/xpressive/detail/core/state.hpp>
0037 #include <boost/xpressive/detail/core/matcher/attr_matcher.hpp>
0038 #include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp>
0039 #include <boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp>
0040 #include <boost/xpressive/detail/core/matcher/predicate_matcher.hpp>
0041 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
0042 #include <boost/xpressive/detail/static/type_traits.hpp>
0043 
0044 // These are very often needed by client code.
0045 #include <boost/typeof/std/map.hpp>
0046 #include <boost/typeof/std/string.hpp>
0047 
0048 // Doxygen can't handle proto :-(
0049 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
0050 # include <boost/proto/core.hpp>
0051 # include <boost/proto/transform.hpp>
0052 # include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
0053 #endif
0054 
0055 #if BOOST_MSVC
0056 #pragma warning(push)
0057 #pragma warning(disable : 4510) // default constructor could not be generated
0058 #pragma warning(disable : 4512) // assignment operator could not be generated
0059 #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
0060 #endif
0061 
0062 namespace boost { namespace xpressive
0063 {
0064 
0065     namespace detail
0066     {
0067         template<typename T, typename U>
0068         struct action_arg
0069         {
0070             typedef T type;
0071             typedef typename add_reference<T>::type reference;
0072 
0073             reference cast(void *pv) const
0074             {
0075                 return *static_cast<typename remove_reference<T>::type *>(pv);
0076             }
0077         };
0078 
0079         template<typename T>
0080         struct value_wrapper
0081           : private noncopyable
0082         {
0083             value_wrapper()
0084               : value()
0085             {}
0086 
0087             value_wrapper(T const &t)
0088               : value(t)
0089             {}
0090 
0091             T value;
0092         };
0093 
0094         struct check_tag
0095         {};
0096 
0097         struct BindArg
0098         {
0099             BOOST_PROTO_CALLABLE()
0100             template<typename Sig>
0101             struct result {};
0102 
0103             template<typename This, typename MatchResults, typename Expr>
0104             struct result<This(MatchResults, Expr)>
0105             {
0106                 typedef Expr type;
0107             };
0108 
0109             template<typename MatchResults, typename Expr>
0110             Expr const & operator ()(MatchResults &what, Expr const &expr) const
0111             {
0112                 what.let(expr);
0113                 return expr;
0114             }
0115         };
0116 
0117         struct let_tag
0118         {};
0119 
0120         // let(_a = b, _c = d)
0121         struct BindArgs
0122           : proto::function<
0123                 proto::terminal<let_tag>
0124               , proto::vararg<
0125                     proto::when<
0126                         proto::assign<proto::_, proto::_>
0127                       , proto::call<BindArg(proto::_data, proto::_)>
0128                     >
0129                 >
0130             >
0131         {};
0132 
0133         struct let_domain
0134           : boost::proto::domain<boost::proto::pod_generator<let_> >
0135         {};
0136 
0137         template<typename Expr>
0138         struct let_
0139         {
0140             BOOST_PROTO_BASIC_EXTENDS(Expr, let_<Expr>, let_domain)
0141             BOOST_PROTO_EXTENDS_FUNCTION()
0142         };
0143 
0144         template<typename Args, typename BidiIter>
0145         void bind_args(let_<Args> const &args, match_results<BidiIter> &what)
0146         {
0147             BindArgs()(args, 0, what);
0148         }
0149 
0150         typedef boost::proto::functional::make_expr<proto::tag::function, proto::default_domain> make_function;
0151     }
0152 
0153     namespace op
0154     {
0155         /// \brief \c at is a PolymorphicFunctionObject for indexing into a sequence
0156         struct at
0157         {
0158             BOOST_PROTO_CALLABLE()
0159             template<typename Sig>
0160             struct result {};
0161 
0162             template<typename This, typename Cont, typename Idx>
0163             struct result<This(Cont &, Idx)>
0164             {
0165                 typedef typename Cont::reference type;
0166             };
0167 
0168             template<typename This, typename Cont, typename Idx>
0169             struct result<This(Cont const &, Idx)>
0170             {
0171                 typedef typename Cont::const_reference type;
0172             };
0173 
0174             template<typename This, typename Cont, typename Idx>
0175             struct result<This(Cont, Idx)>
0176             {
0177                 typedef typename Cont::const_reference type;
0178             };
0179 
0180             /// \pre    \c Cont is a model of RandomAccessSequence
0181             /// \param  c The RandomAccessSequence to index into
0182             /// \param  idx The index
0183             /// \return <tt>c[idx]</tt>
0184             template<typename Cont, typename Idx>
0185             typename Cont::reference operator()(Cont &c, Idx idx BOOST_PROTO_DISABLE_IF_IS_CONST(Cont)) const
0186             {
0187                 return c[idx];
0188             }
0189 
0190             /// \overload
0191             ///
0192             template<typename Cont, typename Idx>
0193             typename Cont::const_reference operator()(Cont const &c, Idx idx) const
0194             {
0195                 return c[idx];
0196             }
0197         };
0198 
0199         /// \brief \c push is a PolymorphicFunctionObject for pushing an element into a container.
0200         struct push
0201         {
0202             BOOST_PROTO_CALLABLE()
0203             typedef void result_type;
0204 
0205             /// \param seq The sequence into which the value should be pushed.
0206             /// \param val The value to push into the sequence.
0207             /// \brief Equivalent to <tt>seq.push(val)</tt>.
0208             /// \return \c void
0209             template<typename Sequence, typename Value>
0210             void operator()(Sequence &seq, Value const &val) const
0211             {
0212                 seq.push(val);
0213             }
0214         };
0215 
0216         /// \brief \c push_back is a PolymorphicFunctionObject for pushing an element into the back of a container.
0217         struct push_back
0218         {
0219             BOOST_PROTO_CALLABLE()
0220             typedef void result_type;
0221 
0222             /// \param seq The sequence into which the value should be pushed.
0223             /// \param val The value to push into the sequence.
0224             /// \brief Equivalent to <tt>seq.push_back(val)</tt>.
0225             /// \return \c void
0226             template<typename Sequence, typename Value>
0227             void operator()(Sequence &seq, Value const &val) const
0228             {
0229                 seq.push_back(val);
0230             }
0231         };
0232 
0233         /// \brief \c push_front is a PolymorphicFunctionObject for pushing an element into the front of a container.
0234         struct push_front
0235         {
0236             BOOST_PROTO_CALLABLE()
0237             typedef void result_type;
0238 
0239             /// \param seq The sequence into which the value should be pushed.
0240             /// \param val The value to push into the sequence.
0241             /// \brief Equivalent to <tt>seq.push_front(val)</tt>.
0242             /// \return \c void
0243             template<typename Sequence, typename Value>
0244             void operator()(Sequence &seq, Value const &val) const
0245             {
0246                 seq.push_front(val);
0247             }
0248         };
0249 
0250         /// \brief \c pop is a PolymorphicFunctionObject for popping an element from a container.
0251         struct pop
0252         {
0253             BOOST_PROTO_CALLABLE()
0254             typedef void result_type;
0255 
0256             /// \param seq The sequence from which to pop.
0257             /// \brief Equivalent to <tt>seq.pop()</tt>.
0258             /// \return \c void
0259             template<typename Sequence>
0260             void operator()(Sequence &seq) const
0261             {
0262                 seq.pop();
0263             }
0264         };
0265 
0266         /// \brief \c pop_back is a PolymorphicFunctionObject for popping an element from the back of a container.
0267         struct pop_back
0268         {
0269             BOOST_PROTO_CALLABLE()
0270             typedef void result_type;
0271 
0272             /// \param seq The sequence from which to pop.
0273             /// \brief Equivalent to <tt>seq.pop_back()</tt>.
0274             /// \return \c void
0275             template<typename Sequence>
0276             void operator()(Sequence &seq) const
0277             {
0278                 seq.pop_back();
0279             }
0280         };
0281 
0282         /// \brief \c pop_front is a PolymorphicFunctionObject for popping an element from the front of a container.
0283         struct pop_front
0284         {
0285             BOOST_PROTO_CALLABLE()
0286             typedef void result_type;
0287 
0288             /// \param seq The sequence from which to pop.
0289             /// \brief Equivalent to <tt>seq.pop_front()</tt>.
0290             /// \return \c void
0291             template<typename Sequence>
0292             void operator()(Sequence &seq) const
0293             {
0294                 seq.pop_front();
0295             }
0296         };
0297 
0298         /// \brief \c front is a PolymorphicFunctionObject for fetching the front element of a container.
0299         struct front
0300         {
0301             BOOST_PROTO_CALLABLE()
0302             template<typename Sig>
0303             struct result {};
0304 
0305             template<typename This, typename Sequence>
0306             struct result<This(Sequence)>
0307             {
0308                 typedef typename remove_reference<Sequence>::type sequence_type;
0309                 typedef
0310                     typename mpl::if_c<
0311                         is_const<sequence_type>::value
0312                       , typename sequence_type::const_reference
0313                       , typename sequence_type::reference
0314                     >::type
0315                 type;
0316             };
0317 
0318             /// \param seq The sequence from which to fetch the front.
0319             /// \return <tt>seq.front()</tt>
0320             template<typename Sequence>
0321             typename result<front(Sequence &)>::type operator()(Sequence &seq) const
0322             {
0323                 return seq.front();
0324             }
0325         };
0326 
0327         /// \brief \c back is a PolymorphicFunctionObject for fetching the back element of a container.
0328         struct back
0329         {
0330             BOOST_PROTO_CALLABLE()
0331             template<typename Sig>
0332             struct result {};
0333 
0334             template<typename This, typename Sequence>
0335             struct result<This(Sequence)>
0336             {
0337                 typedef typename remove_reference<Sequence>::type sequence_type;
0338                 typedef
0339                     typename mpl::if_c<
0340                         is_const<sequence_type>::value
0341                       , typename sequence_type::const_reference
0342                       , typename sequence_type::reference
0343                     >::type
0344                 type;
0345             };
0346 
0347             /// \param seq The sequence from which to fetch the back.
0348             /// \return <tt>seq.back()</tt>
0349             template<typename Sequence>
0350             typename result<back(Sequence &)>::type operator()(Sequence &seq) const
0351             {
0352                 return seq.back();
0353             }
0354         };
0355 
0356         /// \brief \c top is a PolymorphicFunctionObject for fetching the top element of a stack.
0357         struct top
0358         {
0359             BOOST_PROTO_CALLABLE()
0360             template<typename Sig>
0361             struct result {};
0362 
0363             template<typename This, typename Sequence>
0364             struct result<This(Sequence)>
0365             {
0366                 typedef typename remove_reference<Sequence>::type sequence_type;
0367                 typedef
0368                     typename mpl::if_c<
0369                         is_const<sequence_type>::value
0370                       , typename sequence_type::value_type const &
0371                       , typename sequence_type::value_type &
0372                     >::type
0373                 type;
0374             };
0375 
0376             /// \param seq The sequence from which to fetch the top.
0377             /// \return <tt>seq.top()</tt>
0378             template<typename Sequence>
0379             typename result<top(Sequence &)>::type operator()(Sequence &seq) const
0380             {
0381                 return seq.top();
0382             }
0383         };
0384 
0385         /// \brief \c first is a PolymorphicFunctionObject for fetching the first element of a pair.
0386         struct first
0387         {
0388             BOOST_PROTO_CALLABLE()
0389             template<typename Sig>
0390             struct result {};
0391 
0392             template<typename This, typename Pair>
0393             struct result<This(Pair)>
0394             {
0395                 typedef typename remove_reference<Pair>::type::first_type type;
0396             };
0397 
0398             /// \param p The pair from which to fetch the first element.
0399             /// \return <tt>p.first</tt>
0400             template<typename Pair>
0401             typename Pair::first_type operator()(Pair const &p) const
0402             {
0403                 return p.first;
0404             }
0405         };
0406 
0407         /// \brief \c second is a PolymorphicFunctionObject for fetching the second element of a pair.
0408         struct second
0409         {
0410             BOOST_PROTO_CALLABLE()
0411             template<typename Sig>
0412             struct result {};
0413 
0414             template<typename This, typename Pair>
0415             struct result<This(Pair)>
0416             {
0417                 typedef typename remove_reference<Pair>::type::second_type type;
0418             };
0419 
0420             /// \param p The pair from which to fetch the second element.
0421             /// \return <tt>p.second</tt>
0422             template<typename Pair>
0423             typename Pair::second_type operator()(Pair const &p) const
0424             {
0425                 return p.second;
0426             }
0427         };
0428 
0429         /// \brief \c matched is a PolymorphicFunctionObject for assessing whether a \c sub_match object
0430         ///        matched or not.
0431         struct matched
0432         {
0433             BOOST_PROTO_CALLABLE()
0434             typedef bool result_type;
0435 
0436             /// \param sub The \c sub_match object.
0437             /// \return <tt>sub.matched</tt>
0438             template<typename Sub>
0439             bool operator()(Sub const &sub) const
0440             {
0441                 return sub.matched;
0442             }
0443         };
0444 
0445         /// \brief \c length is a PolymorphicFunctionObject for fetching the length of \c sub_match.
0446         struct length
0447         {
0448             BOOST_PROTO_CALLABLE()
0449             template<typename Sig>
0450             struct result {};
0451 
0452             template<typename This, typename Sub>
0453             struct result<This(Sub)>
0454             {
0455                 typedef typename remove_reference<Sub>::type::difference_type type;
0456             };
0457 
0458             /// \param sub The \c sub_match object.
0459             /// \return <tt>sub.length()</tt>
0460             template<typename Sub>
0461             typename Sub::difference_type operator()(Sub const &sub) const
0462             {
0463                 return sub.length();
0464             }
0465         };
0466 
0467         /// \brief \c str is a PolymorphicFunctionObject for turning a \c sub_match into an
0468         ///        equivalent \c std::string.
0469         struct str
0470         {
0471             BOOST_PROTO_CALLABLE()
0472             template<typename Sig>
0473             struct result {};
0474 
0475             template<typename This, typename Sub>
0476             struct result<This(Sub)>
0477             {
0478                 typedef typename remove_reference<Sub>::type::string_type type;
0479             };
0480 
0481             /// \param sub The \c sub_match object.
0482             /// \return <tt>sub.str()</tt>
0483             template<typename Sub>
0484             typename Sub::string_type operator()(Sub const &sub) const
0485             {
0486                 return sub.str();
0487             }
0488         };
0489 
0490         // This codifies the return types of the various insert member
0491         // functions found in sequence containers, the 2 flavors of
0492         // associative containers, and strings.
0493         //
0494         /// \brief \c insert is a PolymorphicFunctionObject for inserting a value or a
0495         ///        sequence of values into a sequence container, an associative
0496         ///        container, or a string.
0497         struct insert
0498         {
0499             BOOST_PROTO_CALLABLE()
0500 
0501             /// INTERNAL ONLY
0502             ///
0503             struct detail
0504             {
0505                 template<typename Sig, typename EnableIf = void>
0506                 struct result_detail
0507                 {};
0508 
0509                 // assoc containers
0510                 template<typename This, typename Cont, typename Value>
0511                 struct result_detail<This(Cont, Value), void>
0512                 {
0513                     typedef typename remove_reference<Cont>::type cont_type;
0514                     typedef typename remove_reference<Value>::type value_type;
0515                     static cont_type &scont_;
0516                     static value_type &svalue_;
0517                     typedef char yes_type;
0518                     typedef char (&no_type)[2];
0519                     static yes_type check_insert_return(typename cont_type::iterator);
0520                     static no_type check_insert_return(std::pair<typename cont_type::iterator, bool>);
0521                     BOOST_STATIC_CONSTANT(bool, is_iterator = (sizeof(yes_type) == sizeof(check_insert_return(scont_.insert(svalue_)))));
0522                     typedef
0523                         typename mpl::if_c<
0524                             is_iterator
0525                           , typename cont_type::iterator
0526                           , std::pair<typename cont_type::iterator, bool>
0527                         >::type
0528                     type;
0529                 };
0530 
0531                 // sequence containers, assoc containers, strings
0532                 template<typename This, typename Cont, typename It, typename Value>
0533                 struct result_detail<This(Cont, It, Value),
0534                     typename disable_if<
0535                         mpl::or_<
0536                             is_integral<typename remove_cv<typename remove_reference<It>::type>::type>
0537                           , is_same<
0538                                 typename remove_cv<typename remove_reference<It>::type>::type
0539                               , typename remove_cv<typename remove_reference<Value>::type>::type
0540                             >
0541                         >
0542                     >::type
0543                 >
0544                 {
0545                     typedef typename remove_reference<Cont>::type::iterator type;
0546                 };
0547 
0548                 // strings
0549                 template<typename This, typename Cont, typename Size, typename T>
0550                 struct result_detail<This(Cont, Size, T),
0551                     typename enable_if<
0552                         is_integral<typename remove_cv<typename remove_reference<Size>::type>::type>
0553                     >::type
0554                 >
0555                 {
0556                     typedef typename remove_reference<Cont>::type &type;
0557                 };
0558 
0559                 // assoc containers
0560                 template<typename This, typename Cont, typename It>
0561                 struct result_detail<This(Cont, It, It), void>
0562                 {
0563                     typedef void type;
0564                 };
0565 
0566                 // sequence containers, strings
0567                 template<typename This, typename Cont, typename It, typename Size, typename Value>
0568                 struct result_detail<This(Cont, It, Size, Value),
0569                     typename disable_if<
0570                         is_integral<typename remove_cv<typename remove_reference<It>::type>::type>
0571                     >::type
0572                 >
0573                 {
0574                     typedef void type;
0575                 };
0576 
0577                 // strings
0578                 template<typename This, typename Cont, typename Size, typename A0, typename A1>
0579                 struct result_detail<This(Cont, Size, A0, A1),
0580                     typename enable_if<
0581                         is_integral<typename remove_cv<typename remove_reference<Size>::type>::type>
0582                     >::type
0583                 >
0584                 {
0585                     typedef typename remove_reference<Cont>::type &type;
0586                 };
0587 
0588                 // strings
0589                 template<typename This, typename Cont, typename Pos0, typename String, typename Pos1, typename Length>
0590                 struct result_detail<This(Cont, Pos0, String, Pos1, Length)>
0591                 {
0592                     typedef typename remove_reference<Cont>::type &type;
0593                 };
0594             };
0595 
0596             template<typename Sig>
0597             struct result
0598             {
0599                 typedef typename detail::result_detail<Sig>::type type;
0600             };
0601 
0602             /// \overload
0603             ///
0604             template<typename Cont, typename A0>
0605             typename result<insert(Cont &, A0 const &)>::type
0606             operator()(Cont &cont, A0 const &a0) const
0607             {
0608                 return cont.insert(a0);
0609             }
0610 
0611             /// \overload
0612             ///
0613             template<typename Cont, typename A0, typename A1>
0614             typename result<insert(Cont &, A0 const &, A1 const &)>::type
0615             operator()(Cont &cont, A0 const &a0, A1 const &a1) const
0616             {
0617                 return cont.insert(a0, a1);
0618             }
0619 
0620             /// \overload
0621             ///
0622             template<typename Cont, typename A0, typename A1, typename A2>
0623             typename result<insert(Cont &, A0 const &, A1 const &, A2 const &)>::type
0624             operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2) const
0625             {
0626                 return cont.insert(a0, a1, a2);
0627             }
0628 
0629             /// \param cont The container into which to insert the element(s)
0630             /// \param a0 A value, iterator, or count
0631             /// \param a1 A value, iterator, string, count, or character
0632             /// \param a2 A value, iterator, or count
0633             /// \param a3 A count
0634             /// \return \li For the form <tt>insert()(cont, a0)</tt>, return <tt>cont.insert(a0)</tt>.
0635             ///         \li For the form <tt>insert()(cont, a0, a1)</tt>, return <tt>cont.insert(a0, a1)</tt>.
0636             ///         \li For the form <tt>insert()(cont, a0, a1, a2)</tt>, return <tt>cont.insert(a0, a1, a2)</tt>.
0637             ///         \li For the form <tt>insert()(cont, a0, a1, a2, a3)</tt>, return <tt>cont.insert(a0, a1, a2, a3)</tt>.
0638             template<typename Cont, typename A0, typename A1, typename A2, typename A3>
0639             typename result<insert(Cont &, A0 const &, A1 const &, A2 const &, A3 const &)>::type
0640             operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2, A3 const &a3) const
0641             {
0642                 return cont.insert(a0, a1, a2, a3);
0643             }
0644         };
0645 
0646         /// \brief \c make_pair is a PolymorphicFunctionObject for building a \c std::pair out of two parameters
0647         struct make_pair
0648         {
0649             BOOST_PROTO_CALLABLE()
0650             template<typename Sig>
0651             struct result {};
0652 
0653             template<typename This, typename First, typename Second>
0654             struct result<This(First, Second)>
0655             {
0656                 /// \brief For exposition only
0657                 typedef typename decay<First>::type first_type;
0658                 /// \brief For exposition only
0659                 typedef typename decay<Second>::type second_type;
0660                 typedef std::pair<first_type, second_type> type;
0661             };
0662 
0663             /// \param first The first element of the pair
0664             /// \param second The second element of the pair
0665             /// \return <tt>std::make_pair(first, second)</tt>
0666             template<typename First, typename Second>
0667             std::pair<First, Second> operator()(First const &first, Second const &second) const
0668             {
0669                 return std::make_pair(first, second);
0670             }
0671         };
0672 
0673         /// \brief \c as\<\> is a PolymorphicFunctionObject for lexically casting a parameter to a different type.
0674         /// \tparam T The type to which to lexically cast the parameter.
0675         template<typename T>
0676         struct as
0677         {
0678             BOOST_PROTO_CALLABLE()
0679             typedef T result_type;
0680 
0681             /// \param val The value to lexically cast.
0682             /// \return <tt>boost::lexical_cast\<T\>(val)</tt>
0683             template<typename Value>
0684             T operator()(Value const &val) const
0685             {
0686                 return boost::lexical_cast<T>(val);
0687             }
0688 
0689             // Hack around some limitations in boost::lexical_cast
0690             /// INTERNAL ONLY
0691             T operator()(csub_match const &val) const
0692             {
0693                 return val.matched
0694                   ? boost::lexical_cast<T>(boost::make_iterator_range(val.first, val.second))
0695                   : boost::lexical_cast<T>("");
0696             }
0697 
0698             #ifndef BOOST_XPRESSIVE_NO_WREGEX
0699             /// INTERNAL ONLY
0700             T operator()(wcsub_match const &val) const
0701             {
0702                 return val.matched
0703                   ? boost::lexical_cast<T>(boost::make_iterator_range(val.first, val.second))
0704                   : boost::lexical_cast<T>("");
0705             }
0706             #endif
0707 
0708             /// INTERNAL ONLY
0709             template<typename BidiIter>
0710             T operator()(sub_match<BidiIter> const &val) const
0711             {
0712                 // If this assert fires, you're trying to coerce a sequences of non-characters
0713                 // to some other type. Xpressive doesn't know how to do that.
0714                 typedef typename iterator_value<BidiIter>::type char_type;
0715                 BOOST_MPL_ASSERT_MSG(
0716                     (xpressive::detail::is_char<char_type>::value)
0717                   , CAN_ONLY_CONVERT_FROM_CHARACTER_SEQUENCES
0718                   , (char_type)
0719                 );
0720                 return this->impl(val, xpressive::detail::is_string_iterator<BidiIter>());
0721             }
0722 
0723         private:
0724             /// INTERNAL ONLY
0725             template<typename RandIter>
0726             T impl(sub_match<RandIter> const &val, mpl::true_) const
0727             {
0728                 return val.matched
0729                   ? boost::lexical_cast<T>(boost::make_iterator_range(&*val.first, &*val.first + (val.second - val.first)))
0730                   : boost::lexical_cast<T>("");
0731             }
0732 
0733             /// INTERNAL ONLY
0734             template<typename BidiIter>
0735             T impl(sub_match<BidiIter> const &val, mpl::false_) const
0736             {
0737                 return boost::lexical_cast<T>(val.str());
0738             }
0739         };
0740 
0741         /// \brief \c static_cast_\<\> is a PolymorphicFunctionObject for statically casting a parameter to a different type.
0742         /// \tparam T The type to which to statically cast the parameter.
0743         template<typename T>
0744         struct static_cast_
0745         {
0746             BOOST_PROTO_CALLABLE()
0747             typedef T result_type;
0748 
0749             /// \param val The value to statically cast.
0750             /// \return <tt>static_cast\<T\>(val)</tt>
0751             template<typename Value>
0752             T operator()(Value const &val) const
0753             {
0754                 return static_cast<T>(val);
0755             }
0756         };
0757 
0758         /// \brief \c dynamic_cast_\<\> is a PolymorphicFunctionObject for dynamically casting a parameter to a different type.
0759         /// \tparam T The type to which to dynamically cast the parameter.
0760         template<typename T>
0761         struct dynamic_cast_
0762         {
0763             BOOST_PROTO_CALLABLE()
0764             typedef T result_type;
0765 
0766             /// \param val The value to dynamically cast.
0767             /// \return <tt>dynamic_cast\<T\>(val)</tt>
0768             template<typename Value>
0769             T operator()(Value const &val) const
0770             {
0771                 return dynamic_cast<T>(val);
0772             }
0773         };
0774 
0775         /// \brief \c const_cast_\<\> is a PolymorphicFunctionObject for const-casting a parameter to a cv qualification.
0776         /// \tparam T The type to which to const-cast the parameter.
0777         template<typename T>
0778         struct const_cast_
0779         {
0780             BOOST_PROTO_CALLABLE()
0781             typedef T result_type;
0782 
0783             /// \param val The value to const-cast.
0784             /// \pre Types \c T and \c Value differ only in cv-qualification.
0785             /// \return <tt>const_cast\<T\>(val)</tt>
0786             template<typename Value>
0787             T operator()(Value const &val) const
0788             {
0789                 return const_cast<T>(val);
0790             }
0791         };
0792 
0793         /// \brief \c construct\<\> is a PolymorphicFunctionObject for constructing a new object.
0794         /// \tparam T The type of the object to construct.
0795         template<typename T>
0796         struct construct
0797         {
0798             BOOST_PROTO_CALLABLE()
0799             typedef T result_type;
0800 
0801             /// \overload
0802             T operator()() const
0803             {
0804                 return T();
0805             }
0806 
0807             /// \overload
0808             template<typename A0>
0809             T operator()(A0 const &a0) const
0810             {
0811                 return T(a0);
0812             }
0813 
0814             /// \overload
0815             template<typename A0, typename A1>
0816             T operator()(A0 const &a0, A1 const &a1) const
0817             {
0818                 return T(a0, a1);
0819             }
0820 
0821             /// \param a0 The first argument to the constructor
0822             /// \param a1 The second argument to the constructor
0823             /// \param a2 The third argument to the constructor
0824             /// \return <tt>T(a0,a1,...)</tt>
0825             template<typename A0, typename A1, typename A2>
0826             T operator()(A0 const &a0, A1 const &a1, A2 const &a2) const
0827             {
0828                 return T(a0, a1, a2);
0829             }
0830         };
0831 
0832         /// \brief \c throw_\<\> is a PolymorphicFunctionObject for throwing an exception.
0833         /// \tparam Except The type of the object to throw.
0834         template<typename Except>
0835         struct throw_
0836         {
0837             BOOST_PROTO_CALLABLE()
0838             typedef void result_type;
0839 
0840             /// \overload
0841             void operator()() const
0842             {
0843                 BOOST_THROW_EXCEPTION(Except());
0844             }
0845 
0846             /// \overload
0847             template<typename A0>
0848             void operator()(A0 const &a0) const
0849             {
0850                 BOOST_THROW_EXCEPTION(Except(a0));
0851             }
0852 
0853             /// \overload
0854             template<typename A0, typename A1>
0855             void operator()(A0 const &a0, A1 const &a1) const
0856             {
0857                 BOOST_THROW_EXCEPTION(Except(a0, a1));
0858             }
0859 
0860             /// \param a0 The first argument to the constructor
0861             /// \param a1 The second argument to the constructor
0862             /// \param a2 The third argument to the constructor
0863             /// \throw <tt>Except(a0,a1,...)</tt>
0864             /// \note This function makes use of the \c BOOST_THROW_EXCEPTION macro
0865             ///       to actually throw the exception. See the documentation for the
0866             ///       Boost.Exception library.
0867             template<typename A0, typename A1, typename A2>
0868             void operator()(A0 const &a0, A1 const &a1, A2 const &a2) const
0869             {
0870                 BOOST_THROW_EXCEPTION(Except(a0, a1, a2));
0871             }
0872         };
0873 
0874         /// \brief \c unwrap_reference is a PolymorphicFunctionObject for unwrapping a <tt>boost::reference_wrapper\<\></tt>.
0875         struct unwrap_reference
0876         {
0877             BOOST_PROTO_CALLABLE()
0878             template<typename Sig>
0879             struct result {};
0880 
0881             template<typename This, typename Ref>
0882             struct result<This(Ref)>
0883             {
0884                 typedef typename boost::unwrap_reference<Ref>::type &type;
0885             };
0886 
0887             template<typename This, typename Ref>
0888             struct result<This(Ref &)>
0889             {
0890                 typedef typename boost::unwrap_reference<Ref>::type &type;
0891             };
0892 
0893             /// \param r The <tt>boost::reference_wrapper\<T\></tt> to unwrap.
0894             /// \return <tt>static_cast\<T &\>(r)</tt>
0895             template<typename T>
0896             T &operator()(boost::reference_wrapper<T> r) const
0897             {
0898                 return static_cast<T &>(r);
0899             }
0900         };
0901     }
0902 
0903     /// \brief A unary metafunction that turns an ordinary function object type into the type of
0904     /// a deferred function object for use in xpressive semantic actions.
0905     ///
0906     /// Use \c xpressive::function\<\> to turn an ordinary polymorphic function object type
0907     /// into a type that can be used to declare an object for use in xpressive semantic actions.
0908     ///
0909     /// For example, the global object \c xpressive::push_back can be used to create deferred actions
0910     /// that have the effect of pushing a value into a container. It is defined with
0911     /// \c xpressive::function\<\> as follows:
0912     ///
0913     /** \code
0914         xpressive::function<xpressive::op::push_back>::type const push_back = {};
0915         \endcode
0916     */
0917     ///
0918     /// where \c op::push_back is an ordinary function object that pushes its second argument into
0919     /// its first. Thus defined, \c xpressive::push_back can be used in semantic actions as follows:
0920     ///
0921     /** \code
0922         namespace xp = boost::xpressive;
0923         using xp::_;
0924         std::list<int> result;
0925         std::string str("1 23 456 7890");
0926         xp::sregex rx = (+_d)[ xp::push_back(xp::ref(result), xp::as<int>(_) ]
0927             >> *(' ' >> (+_d)[ xp::push_back(xp::ref(result), xp::as<int>(_) ) ]);
0928         \endcode
0929     */
0930     template<typename PolymorphicFunctionObject>
0931     struct function
0932     {
0933         typedef typename proto::terminal<PolymorphicFunctionObject>::type type;
0934     };
0935 
0936     /// \brief \c at is a lazy PolymorphicFunctionObject for indexing into a sequence in an
0937     /// xpressive semantic action.
0938     function<op::at>::type const at = {{}};
0939 
0940     /// \brief \c push is a lazy PolymorphicFunctionObject for pushing a value into a container in an
0941     /// xpressive semantic action.
0942     function<op::push>::type const push = {{}};
0943 
0944     /// \brief \c push_back is a lazy PolymorphicFunctionObject for pushing a value into a container in an
0945     /// xpressive semantic action.
0946     function<op::push_back>::type const push_back = {{}};
0947 
0948     /// \brief \c push_front is a lazy PolymorphicFunctionObject for pushing a value into a container in an
0949     /// xpressive semantic action.
0950     function<op::push_front>::type const push_front = {{}};
0951 
0952     /// \brief \c pop is a lazy PolymorphicFunctionObject for popping the top element from a sequence in an
0953     /// xpressive semantic action.
0954     function<op::pop>::type const pop = {{}};
0955 
0956     /// \brief \c pop_back is a lazy PolymorphicFunctionObject for popping the back element from a sequence in an
0957     /// xpressive semantic action.
0958     function<op::pop_back>::type const pop_back = {{}};
0959 
0960     /// \brief \c pop_front is a lazy PolymorphicFunctionObject for popping the front element from a sequence in an
0961     /// xpressive semantic action.
0962     function<op::pop_front>::type const pop_front = {{}};
0963 
0964     /// \brief \c top is a lazy PolymorphicFunctionObject for accessing the top element from a stack in an
0965     /// xpressive semantic action.
0966     function<op::top>::type const top = {{}};
0967 
0968     /// \brief \c back is a lazy PolymorphicFunctionObject for fetching the back element of a sequence in an
0969     /// xpressive semantic action.
0970     function<op::back>::type const back = {{}};
0971 
0972     /// \brief \c front is a lazy PolymorphicFunctionObject for fetching the front element of a sequence in an
0973     /// xpressive semantic action.
0974     function<op::front>::type const front = {{}};
0975 
0976     /// \brief \c first is a lazy PolymorphicFunctionObject for accessing the first element of a \c std::pair\<\> in an
0977     /// xpressive semantic action.
0978     function<op::first>::type const first = {{}};
0979 
0980     /// \brief \c second is a lazy PolymorphicFunctionObject for accessing the second element of a \c std::pair\<\> in an
0981     /// xpressive semantic action.
0982     function<op::second>::type const second = {{}};
0983 
0984     /// \brief \c matched is a lazy PolymorphicFunctionObject for accessing the \c matched member of a \c xpressive::sub_match\<\> in an
0985     /// xpressive semantic action.
0986     function<op::matched>::type const matched = {{}};
0987 
0988     /// \brief \c length is a lazy PolymorphicFunctionObject for computing the length of a \c xpressive::sub_match\<\> in an
0989     /// xpressive semantic action.
0990     function<op::length>::type const length = {{}};
0991 
0992     /// \brief \c str is a lazy PolymorphicFunctionObject for converting a \c xpressive::sub_match\<\> to a \c std::basic_string\<\> in an
0993     /// xpressive semantic action.
0994     function<op::str>::type const str = {{}};
0995 
0996     /// \brief \c insert is a lazy PolymorphicFunctionObject for inserting a value or a range of values into a sequence in an
0997     /// xpressive semantic action.
0998     function<op::insert>::type const insert = {{}};
0999 
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