Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file regex_actions.hpp Chris@16: /// Defines the syntax elements of xpressive's action expressions. Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007 Chris@16: #define BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007 Chris@16: Chris@16: // MS compatible compilers support #pragma once Chris@101: #if defined(_MSC_VER) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // These are very often needed by client code. Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Doxygen can't handle proto :-( Chris@16: #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: #endif Chris@16: Chris@16: #if BOOST_MSVC Chris@16: #pragma warning(push) Chris@16: #pragma warning(disable : 4510) // default constructor could not be generated Chris@16: #pragma warning(disable : 4512) // assignment operator could not be generated Chris@16: #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace xpressive Chris@16: { Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct action_arg Chris@16: { Chris@16: typedef T type; Chris@16: typedef typename add_reference::type reference; Chris@16: Chris@16: reference cast(void *pv) const Chris@16: { Chris@16: return *static_cast::type *>(pv); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct value_wrapper Chris@16: : private noncopyable Chris@16: { Chris@16: value_wrapper() Chris@16: : value() Chris@16: {} Chris@16: Chris@16: value_wrapper(T const &t) Chris@16: : value(t) Chris@16: {} Chris@16: Chris@16: T value; Chris@16: }; Chris@16: Chris@16: struct check_tag Chris@16: {}; Chris@16: Chris@16: struct BindArg Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef Expr type; Chris@16: }; Chris@16: Chris@16: template Chris@16: Expr const & operator ()(MatchResults &what, Expr const &expr) const Chris@16: { Chris@16: what.let(expr); Chris@16: return expr; Chris@16: } Chris@16: }; Chris@16: Chris@16: struct let_tag Chris@16: {}; Chris@16: Chris@16: // let(_a = b, _c = d) Chris@16: struct BindArgs Chris@16: : proto::function< Chris@16: proto::terminal Chris@16: , proto::vararg< Chris@16: proto::when< Chris@16: proto::assign Chris@16: , proto::call Chris@16: > Chris@16: > Chris@16: > Chris@16: {}; Chris@16: Chris@16: struct let_domain Chris@16: : boost::proto::domain > Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct let_ Chris@16: { Chris@16: BOOST_PROTO_BASIC_EXTENDS(Expr, let_, let_domain) Chris@16: BOOST_PROTO_EXTENDS_FUNCTION() Chris@16: }; Chris@16: Chris@16: template Chris@16: void bind_args(let_ const &args, match_results &what) Chris@16: { Chris@16: BindArgs()(args, 0, what); Chris@16: } Chris@16: Chris@16: typedef boost::proto::functional::make_expr make_function; Chris@16: } Chris@16: Chris@16: namespace op Chris@16: { Chris@16: /// \brief \c at is a PolymorphicFunctionObject for indexing into a sequence Chris@16: struct at Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename Cont::reference type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename Cont::const_reference type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename Cont::const_reference type; Chris@16: }; Chris@16: Chris@16: /// \pre \c Cont is a model of RandomAccessSequence Chris@16: /// \param c The RandomAccessSequence to index into Chris@16: /// \param idx The index Chris@16: /// \return c[idx] Chris@16: template Chris@16: typename Cont::reference operator()(Cont &c, Idx idx BOOST_PROTO_DISABLE_IF_IS_CONST(Cont)) const Chris@16: { Chris@16: return c[idx]; Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: template Chris@16: typename Cont::const_reference operator()(Cont const &c, Idx idx) const Chris@16: { Chris@16: return c[idx]; Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c push is a PolymorphicFunctionObject for pushing an element into a container. Chris@16: struct push Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef void result_type; Chris@16: Chris@16: /// \param seq The sequence into which the value should be pushed. Chris@16: /// \param val The value to push into the sequence. Chris@16: /// \brief Equivalent to seq.push(val). Chris@16: /// \return \c void Chris@16: template Chris@16: void operator()(Sequence &seq, Value const &val) const Chris@16: { Chris@16: seq.push(val); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c push_back is a PolymorphicFunctionObject for pushing an element into the back of a container. Chris@16: struct push_back Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef void result_type; Chris@16: Chris@16: /// \param seq The sequence into which the value should be pushed. Chris@16: /// \param val The value to push into the sequence. Chris@16: /// \brief Equivalent to seq.push_back(val). Chris@16: /// \return \c void Chris@16: template Chris@16: void operator()(Sequence &seq, Value const &val) const Chris@16: { Chris@16: seq.push_back(val); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c push_front is a PolymorphicFunctionObject for pushing an element into the front of a container. Chris@16: struct push_front Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef void result_type; Chris@16: Chris@16: /// \param seq The sequence into which the value should be pushed. Chris@16: /// \param val The value to push into the sequence. Chris@16: /// \brief Equivalent to seq.push_front(val). Chris@16: /// \return \c void Chris@16: template Chris@16: void operator()(Sequence &seq, Value const &val) const Chris@16: { Chris@16: seq.push_front(val); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c pop is a PolymorphicFunctionObject for popping an element from a container. Chris@16: struct pop Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef void result_type; Chris@16: Chris@16: /// \param seq The sequence from which to pop. Chris@16: /// \brief Equivalent to seq.pop(). Chris@16: /// \return \c void Chris@16: template Chris@16: void operator()(Sequence &seq) const Chris@16: { Chris@16: seq.pop(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c pop_back is a PolymorphicFunctionObject for popping an element from the back of a container. Chris@16: struct pop_back Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef void result_type; Chris@16: Chris@16: /// \param seq The sequence from which to pop. Chris@16: /// \brief Equivalent to seq.pop_back(). Chris@16: /// \return \c void Chris@16: template Chris@16: void operator()(Sequence &seq) const Chris@16: { Chris@16: seq.pop_back(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c pop_front is a PolymorphicFunctionObject for popping an element from the front of a container. Chris@16: struct pop_front Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef void result_type; Chris@16: Chris@16: /// \param seq The sequence from which to pop. Chris@16: /// \brief Equivalent to seq.pop_front(). Chris@16: /// \return \c void Chris@16: template Chris@16: void operator()(Sequence &seq) const Chris@16: { Chris@16: seq.pop_front(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c front is a PolymorphicFunctionObject for fetching the front element of a container. Chris@16: struct front Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename remove_reference::type sequence_type; Chris@16: typedef Chris@16: typename mpl::if_c< Chris@16: is_const::value Chris@16: , typename sequence_type::const_reference Chris@16: , typename sequence_type::reference Chris@16: >::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: /// \param seq The sequence from which to fetch the front. Chris@16: /// \return seq.front() Chris@16: template Chris@16: typename result::type operator()(Sequence &seq) const Chris@16: { Chris@16: return seq.front(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c back is a PolymorphicFunctionObject for fetching the back element of a container. Chris@16: struct back Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename remove_reference::type sequence_type; Chris@16: typedef Chris@16: typename mpl::if_c< Chris@16: is_const::value Chris@16: , typename sequence_type::const_reference Chris@16: , typename sequence_type::reference Chris@16: >::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: /// \param seq The sequence from which to fetch the back. Chris@16: /// \return seq.back() Chris@16: template Chris@16: typename result::type operator()(Sequence &seq) const Chris@16: { Chris@16: return seq.back(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c top is a PolymorphicFunctionObject for fetching the top element of a stack. Chris@16: struct top Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename remove_reference::type sequence_type; Chris@16: typedef Chris@16: typename mpl::if_c< Chris@16: is_const::value Chris@16: , typename sequence_type::value_type const & Chris@16: , typename sequence_type::value_type & Chris@16: >::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: /// \param seq The sequence from which to fetch the top. Chris@16: /// \return seq.top() Chris@16: template Chris@16: typename result::type operator()(Sequence &seq) const Chris@16: { Chris@16: return seq.top(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c first is a PolymorphicFunctionObject for fetching the first element of a pair. Chris@16: struct first Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename remove_reference::type::first_type type; Chris@16: }; Chris@16: Chris@16: /// \param p The pair from which to fetch the first element. Chris@16: /// \return p.first Chris@16: template Chris@16: typename Pair::first_type operator()(Pair const &p) const Chris@16: { Chris@16: return p.first; Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c second is a PolymorphicFunctionObject for fetching the second element of a pair. Chris@16: struct second Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename remove_reference::type::second_type type; Chris@16: }; Chris@16: Chris@16: /// \param p The pair from which to fetch the second element. Chris@16: /// \return p.second Chris@16: template Chris@16: typename Pair::second_type operator()(Pair const &p) const Chris@16: { Chris@16: return p.second; Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c matched is a PolymorphicFunctionObject for assessing whether a \c sub_match object Chris@16: /// matched or not. Chris@16: struct matched Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef bool result_type; Chris@16: Chris@16: /// \param sub The \c sub_match object. Chris@16: /// \return sub.matched Chris@16: template Chris@16: bool operator()(Sub const &sub) const Chris@16: { Chris@16: return sub.matched; Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c length is a PolymorphicFunctionObject for fetching the length of \c sub_match. Chris@16: struct length Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename remove_reference::type::difference_type type; Chris@16: }; Chris@16: Chris@16: /// \param sub The \c sub_match object. Chris@16: /// \return sub.length() Chris@16: template Chris@16: typename Sub::difference_type operator()(Sub const &sub) const Chris@16: { Chris@16: return sub.length(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c str is a PolymorphicFunctionObject for turning a \c sub_match into an Chris@16: /// equivalent \c std::string. Chris@16: struct str Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename remove_reference::type::string_type type; Chris@16: }; Chris@16: Chris@16: /// \param sub The \c sub_match object. Chris@16: /// \return sub.str() Chris@16: template Chris@16: typename Sub::string_type operator()(Sub const &sub) const Chris@16: { Chris@16: return sub.str(); Chris@16: } Chris@16: }; Chris@16: Chris@16: // This codifies the return types of the various insert member Chris@16: // functions found in sequence containers, the 2 flavors of Chris@16: // associative containers, and strings. Chris@16: // Chris@16: /// \brief \c insert is a PolymorphicFunctionObject for inserting a value or a Chris@16: /// sequence of values into a sequence container, an associative Chris@16: /// container, or a string. Chris@16: struct insert Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: struct detail Chris@16: { Chris@16: template Chris@16: struct result_detail Chris@16: {}; Chris@16: Chris@16: // assoc containers Chris@16: template Chris@16: struct result_detail Chris@16: { Chris@16: typedef typename remove_reference::type cont_type; Chris@16: typedef typename remove_reference::type value_type; Chris@16: static cont_type &scont_; Chris@16: static value_type &svalue_; Chris@16: typedef char yes_type; Chris@16: typedef char (&no_type)[2]; Chris@16: static yes_type check_insert_return(typename cont_type::iterator); Chris@16: static no_type check_insert_return(std::pair); Chris@16: BOOST_STATIC_CONSTANT(bool, is_iterator = (sizeof(yes_type) == sizeof(check_insert_return(scont_.insert(svalue_))))); Chris@16: typedef Chris@16: typename mpl::if_c< Chris@16: is_iterator Chris@16: , typename cont_type::iterator Chris@16: , std::pair Chris@16: >::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: // sequence containers, assoc containers, strings Chris@16: template Chris@16: struct result_detail::type>::type> Chris@16: , is_same< Chris@16: typename remove_cv::type>::type Chris@16: , typename remove_cv::type>::type Chris@16: > Chris@16: > Chris@16: >::type Chris@16: > Chris@16: { Chris@16: typedef typename remove_reference::type::iterator type; Chris@16: }; Chris@16: Chris@16: // strings Chris@16: template Chris@16: struct result_detail::type>::type> Chris@16: >::type Chris@16: > Chris@16: { Chris@16: typedef typename remove_reference::type &type; Chris@16: }; Chris@16: Chris@16: // assoc containers Chris@16: template Chris@16: struct result_detail Chris@16: { Chris@16: typedef void type; Chris@16: }; Chris@16: Chris@16: // sequence containers, strings Chris@16: template Chris@16: struct result_detail::type>::type> Chris@16: >::type Chris@16: > Chris@16: { Chris@16: typedef void type; Chris@16: }; Chris@16: Chris@16: // strings Chris@16: template Chris@16: struct result_detail::type>::type> Chris@16: >::type Chris@16: > Chris@16: { Chris@16: typedef typename remove_reference::type &type; Chris@16: }; Chris@16: Chris@16: // strings Chris@16: template Chris@16: struct result_detail Chris@16: { Chris@16: typedef typename remove_reference::type &type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename detail::result_detail::type type; Chris@16: }; Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: template Chris@16: typename result::type Chris@16: operator()(Cont &cont, A0 const &a0) const Chris@16: { Chris@16: return cont.insert(a0); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: template Chris@16: typename result::type Chris@16: operator()(Cont &cont, A0 const &a0, A1 const &a1) const Chris@16: { Chris@16: return cont.insert(a0, a1); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: template Chris@16: typename result::type Chris@16: operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2) const Chris@16: { Chris@16: return cont.insert(a0, a1, a2); Chris@16: } Chris@16: Chris@16: /// \param cont The container into which to insert the element(s) Chris@16: /// \param a0 A value, iterator, or count Chris@16: /// \param a1 A value, iterator, string, count, or character Chris@16: /// \param a2 A value, iterator, or count Chris@16: /// \param a3 A count Chris@16: /// \return \li For the form insert()(cont, a0), return cont.insert(a0). Chris@16: /// \li For the form insert()(cont, a0, a1), return cont.insert(a0, a1). Chris@16: /// \li For the form insert()(cont, a0, a1, a2), return cont.insert(a0, a1, a2). Chris@16: /// \li For the form insert()(cont, a0, a1, a2, a3), return cont.insert(a0, a1, a2, a3). Chris@16: template Chris@16: typename result::type Chris@16: operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2, A3 const &a3) const Chris@16: { Chris@16: return cont.insert(a0, a1, a2, a3); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c make_pair is a PolymorphicFunctionObject for building a \c std::pair out of two parameters Chris@16: struct make_pair Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: /// \brief For exposition only Chris@16: typedef typename decay::type first_type; Chris@16: /// \brief For exposition only Chris@16: typedef typename decay::type second_type; Chris@16: typedef std::pair type; Chris@16: }; Chris@16: Chris@16: /// \param first The first element of the pair Chris@16: /// \param second The second element of the pair Chris@16: /// \return std::make_pair(first, second) Chris@16: template Chris@16: std::pair operator()(First const &first, Second const &second) const Chris@16: { Chris@16: return std::make_pair(first, second); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c as\<\> is a PolymorphicFunctionObject for lexically casting a parameter to a different type. Chris@16: /// \tparam T The type to which to lexically cast the parameter. Chris@16: template Chris@16: struct as Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef T result_type; Chris@16: Chris@16: /// \param val The value to lexically cast. Chris@16: /// \return boost::lexical_cast\(val) Chris@16: template Chris@16: T operator()(Value const &val) const Chris@16: { Chris@16: return boost::lexical_cast(val); Chris@16: } Chris@16: Chris@16: // Hack around some limitations in boost::lexical_cast Chris@16: /// INTERNAL ONLY Chris@16: T operator()(csub_match const &val) const Chris@16: { Chris@16: return val.matched Chris@16: ? boost::lexical_cast(boost::make_iterator_range(val.first, val.second)) Chris@16: : boost::lexical_cast(""); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_XPRESSIVE_NO_WREGEX Chris@16: /// INTERNAL ONLY Chris@16: T operator()(wcsub_match const &val) const Chris@16: { Chris@16: return val.matched Chris@16: ? boost::lexical_cast(boost::make_iterator_range(val.first, val.second)) Chris@16: : boost::lexical_cast(""); Chris@16: } Chris@16: #endif Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: T operator()(sub_match const &val) const Chris@16: { Chris@16: // If this assert fires, you're trying to coerce a sequences of non-characters Chris@16: // to some other type. Xpressive doesn't know how to do that. Chris@16: typedef typename iterator_value::type char_type; Chris@16: BOOST_MPL_ASSERT_MSG( Chris@16: (xpressive::detail::is_char::value) Chris@16: , CAN_ONLY_CONVERT_FROM_CHARACTER_SEQUENCES Chris@16: , (char_type) Chris@16: ); Chris@16: return this->impl(val, xpressive::detail::is_string_iterator()); Chris@16: } Chris@16: Chris@16: private: Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: T impl(sub_match const &val, mpl::true_) const Chris@16: { Chris@16: return val.matched Chris@16: ? boost::lexical_cast(boost::make_iterator_range(&*val.first, &*val.first + (val.second - val.first))) Chris@16: : boost::lexical_cast(""); Chris@16: } Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: T impl(sub_match const &val, mpl::false_) const Chris@16: { Chris@16: return boost::lexical_cast(val.str()); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c static_cast_\<\> is a PolymorphicFunctionObject for statically casting a parameter to a different type. Chris@16: /// \tparam T The type to which to statically cast the parameter. Chris@16: template Chris@16: struct static_cast_ Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef T result_type; Chris@16: Chris@16: /// \param val The value to statically cast. Chris@16: /// \return static_cast\(val) Chris@16: template Chris@16: T operator()(Value const &val) const Chris@16: { Chris@16: return static_cast(val); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c dynamic_cast_\<\> is a PolymorphicFunctionObject for dynamically casting a parameter to a different type. Chris@16: /// \tparam T The type to which to dynamically cast the parameter. Chris@16: template Chris@16: struct dynamic_cast_ Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef T result_type; Chris@16: Chris@16: /// \param val The value to dynamically cast. Chris@16: /// \return dynamic_cast\(val) Chris@16: template Chris@16: T operator()(Value const &val) const Chris@16: { Chris@16: return dynamic_cast(val); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c const_cast_\<\> is a PolymorphicFunctionObject for const-casting a parameter to a cv qualification. Chris@16: /// \tparam T The type to which to const-cast the parameter. Chris@16: template Chris@16: struct const_cast_ Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef T result_type; Chris@16: Chris@16: /// \param val The value to const-cast. Chris@16: /// \pre Types \c T and \c Value differ only in cv-qualification. Chris@16: /// \return const_cast\(val) Chris@16: template Chris@16: T operator()(Value const &val) const Chris@16: { Chris@16: return const_cast(val); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c construct\<\> is a PolymorphicFunctionObject for constructing a new object. Chris@16: /// \tparam T The type of the object to construct. Chris@16: template Chris@16: struct construct Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef T result_type; Chris@16: Chris@16: /// \overload Chris@16: T operator()() const Chris@16: { Chris@16: return T(); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: template Chris@16: T operator()(A0 const &a0) const Chris@16: { Chris@16: return T(a0); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: template Chris@16: T operator()(A0 const &a0, A1 const &a1) const Chris@16: { Chris@16: return T(a0, a1); Chris@16: } Chris@16: Chris@16: /// \param a0 The first argument to the constructor Chris@16: /// \param a1 The second argument to the constructor Chris@16: /// \param a2 The third argument to the constructor Chris@16: /// \return T(a0,a1,...) Chris@16: template Chris@16: T operator()(A0 const &a0, A1 const &a1, A2 const &a2) const Chris@16: { Chris@16: return T(a0, a1, a2); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c throw_\<\> is a PolymorphicFunctionObject for throwing an exception. Chris@16: /// \tparam Except The type of the object to throw. Chris@16: template Chris@16: struct throw_ Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef void result_type; Chris@16: Chris@16: /// \overload Chris@16: void operator()() const Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(Except()); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: template Chris@16: void operator()(A0 const &a0) const Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(Except(a0)); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: template Chris@16: void operator()(A0 const &a0, A1 const &a1) const Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(Except(a0, a1)); Chris@16: } Chris@16: Chris@16: /// \param a0 The first argument to the constructor Chris@16: /// \param a1 The second argument to the constructor Chris@16: /// \param a2 The third argument to the constructor Chris@16: /// \throw Except(a0,a1,...) Chris@16: /// \note This function makes use of the \c BOOST_THROW_EXCEPTION macro Chris@16: /// to actually throw the exception. See the documentation for the Chris@16: /// Boost.Exception library. Chris@16: template Chris@16: void operator()(A0 const &a0, A1 const &a1, A2 const &a2) const Chris@16: { Chris@16: BOOST_THROW_EXCEPTION(Except(a0, a1, a2)); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c unwrap_reference is a PolymorphicFunctionObject for unwrapping a boost::reference_wrapper\<\>. Chris@16: struct unwrap_reference Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: template Chris@16: struct result {}; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename boost::unwrap_reference::type &type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename boost::unwrap_reference::type &type; Chris@16: }; Chris@16: Chris@16: /// \param r The boost::reference_wrapper\ to unwrap. Chris@16: /// \return static_cast\(r) Chris@16: template Chris@16: T &operator()(boost::reference_wrapper r) const Chris@16: { Chris@16: return static_cast(r); Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: /// \brief A unary metafunction that turns an ordinary function object type into the type of Chris@16: /// a deferred function object for use in xpressive semantic actions. Chris@16: /// Chris@16: /// Use \c xpressive::function\<\> to turn an ordinary polymorphic function object type Chris@16: /// into a type that can be used to declare an object for use in xpressive semantic actions. Chris@16: /// Chris@16: /// For example, the global object \c xpressive::push_back can be used to create deferred actions Chris@16: /// that have the effect of pushing a value into a container. It is defined with Chris@16: /// \c xpressive::function\<\> as follows: Chris@16: /// Chris@16: /** \code Chris@16: xpressive::function::type const push_back = {}; Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// where \c op::push_back is an ordinary function object that pushes its second argument into Chris@16: /// its first. Thus defined, \c xpressive::push_back can be used in semantic actions as follows: Chris@16: /// Chris@16: /** \code Chris@16: namespace xp = boost::xpressive; Chris@16: using xp::_; Chris@16: std::list result; Chris@16: std::string str("1 23 456 7890"); Chris@16: xp::sregex rx = (+_d)[ xp::push_back(xp::ref(result), xp::as(_) ] Chris@16: >> *(' ' >> (+_d)[ xp::push_back(xp::ref(result), xp::as(_) ) ]); Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct function Chris@16: { Chris@16: typedef typename proto::terminal::type type; Chris@16: }; Chris@16: Chris@16: /// \brief \c at is a lazy PolymorphicFunctionObject for indexing into a sequence in an Chris@16: /// xpressive semantic action. Chris@16: function::type const at = {{}}; Chris@16: Chris@16: /// \brief \c push is a lazy PolymorphicFunctionObject for pushing a value into a container in an Chris@16: /// xpressive semantic action. Chris@16: function::type const push = {{}}; Chris@16: Chris@16: /// \brief \c push_back is a lazy PolymorphicFunctionObject for pushing a value into a container in an Chris@16: /// xpressive semantic action. Chris@16: function::type const push_back = {{}}; Chris@16: Chris@16: /// \brief \c push_front is a lazy PolymorphicFunctionObject for pushing a value into a container in an Chris@16: /// xpressive semantic action. Chris@16: function::type const push_front = {{}}; Chris@16: Chris@16: /// \brief \c pop is a lazy PolymorphicFunctionObject for popping the top element from a sequence in an Chris@16: /// xpressive semantic action. Chris@16: function::type const pop = {{}}; Chris@16: Chris@16: /// \brief \c pop_back is a lazy PolymorphicFunctionObject for popping the back element from a sequence in an Chris@16: /// xpressive semantic action. Chris@16: function::type const pop_back = {{}}; Chris@16: Chris@16: /// \brief \c pop_front is a lazy PolymorphicFunctionObject for popping the front element from a sequence in an Chris@16: /// xpressive semantic action. Chris@16: function::type const pop_front = {{}}; Chris@16: Chris@16: /// \brief \c top is a lazy PolymorphicFunctionObject for accessing the top element from a stack in an Chris@16: /// xpressive semantic action. Chris@16: function::type const top = {{}}; Chris@16: Chris@16: /// \brief \c back is a lazy PolymorphicFunctionObject for fetching the back element of a sequence in an Chris@16: /// xpressive semantic action. Chris@16: function::type const back = {{}}; Chris@16: Chris@16: /// \brief \c front is a lazy PolymorphicFunctionObject for fetching the front element of a sequence in an Chris@16: /// xpressive semantic action. Chris@16: function::type const front = {{}}; Chris@16: Chris@16: /// \brief \c first is a lazy PolymorphicFunctionObject for accessing the first element of a \c std::pair\<\> in an Chris@16: /// xpressive semantic action. Chris@16: function::type const first = {{}}; Chris@16: Chris@16: /// \brief \c second is a lazy PolymorphicFunctionObject for accessing the second element of a \c std::pair\<\> in an Chris@16: /// xpressive semantic action. Chris@16: function::type const second = {{}}; Chris@16: Chris@16: /// \brief \c matched is a lazy PolymorphicFunctionObject for accessing the \c matched member of a \c xpressive::sub_match\<\> in an Chris@16: /// xpressive semantic action. Chris@16: function::type const matched = {{}}; Chris@16: Chris@16: /// \brief \c length is a lazy PolymorphicFunctionObject for computing the length of a \c xpressive::sub_match\<\> in an Chris@16: /// xpressive semantic action. Chris@16: function::type const length = {{}}; Chris@16: Chris@16: /// \brief \c str is a lazy PolymorphicFunctionObject for converting a \c xpressive::sub_match\<\> to a \c std::basic_string\<\> in an Chris@16: /// xpressive semantic action. Chris@16: function::type const str = {{}}; Chris@16: Chris@16: /// \brief \c insert is a lazy PolymorphicFunctionObject for inserting a value or a range of values into a sequence in an Chris@16: /// xpressive semantic action. Chris@16: function::type const insert = {{}}; Chris@16: Chris@16: /// \brief \c make_pair is a lazy PolymorphicFunctionObject for making a \c std::pair\<\> in an Chris@16: /// xpressive semantic action. Chris@16: function::type const make_pair = {{}}; Chris@16: Chris@16: /// \brief \c unwrap_reference is a lazy PolymorphicFunctionObject for unwrapping a \c boost::reference_wrapper\<\> in an Chris@16: /// xpressive semantic action. Chris@16: function::type const unwrap_reference = {{}}; Chris@16: Chris@16: /// \brief \c value\<\> is a lazy wrapper for a value that can be used in xpressive semantic actions. Chris@16: /// \tparam T The type of the value to store. Chris@16: /// Chris@16: /// Below is an example that shows where \c value\<\> is useful. Chris@16: /// Chris@16: /** \code Chris@16: sregex good_voodoo(boost::shared_ptr pi) Chris@16: { Chris@16: using namespace boost::xpressive; Chris@16: // Use val() to hold the shared_ptr by value: Chris@16: sregex rex = +( _d [ ++*val(pi) ] >> '!' ); Chris@16: // OK, rex holds a reference count to the integer. Chris@16: return rex; Chris@16: } Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// In the above code, \c xpressive::val() is a function that returns a \c value\<\> object. Had Chris@16: /// \c val() not been used here, the operation ++*pi would have been evaluated eagerly Chris@16: /// once, instead of lazily when the regex match happens. Chris@16: template Chris@16: struct value Chris@16: : proto::extends::type, value > Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: typedef proto::extends::type, value > base_type; Chris@16: Chris@16: /// \brief Store a default-constructed \c T Chris@16: value() Chris@16: : base_type() Chris@16: {} Chris@16: Chris@16: /// \param t The initial value. Chris@16: /// \brief Store a copy of \c t. Chris@16: explicit value(T const &t) Chris@16: : base_type(base_type::proto_base_expr::make(t)) Chris@16: {} Chris@16: Chris@16: using base_type::operator=; Chris@16: Chris@16: /// \overload Chris@16: T &get() Chris@16: { Chris@16: return proto::value(*this); Chris@16: } Chris@16: Chris@16: /// \brief Fetch the stored value Chris@16: T const &get() const Chris@16: { Chris@16: return proto::value(*this); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c reference\<\> is a lazy wrapper for a reference that can be used in Chris@16: /// xpressive semantic actions. Chris@16: /// Chris@16: /// \tparam T The type of the referent. Chris@16: /// Chris@16: /// Here is an example of how to use \c reference\<\> to create a lazy reference to Chris@16: /// an existing object so it can be read and written in an xpressive semantic action. Chris@16: /// Chris@16: /** \code Chris@16: using namespace boost::xpressive; Chris@16: std::map result; Chris@16: reference > result_ref(result); Chris@16: Chris@16: // Match a word and an integer, separated by =>, Chris@16: // and then stuff the result into a std::map<> Chris@16: sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) Chris@16: [ result_ref[s1] = as(s2) ]; Chris@16: \endcode Chris@16: */ Chris@16: template Chris@16: struct reference Chris@16: : proto::extends >::type, reference > Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: typedef proto::extends >::type, reference > base_type; Chris@16: Chris@16: /// \param t Reference to object Chris@16: /// \brief Store a reference to \c t Chris@16: explicit reference(T &t) Chris@16: : base_type(base_type::proto_base_expr::make(boost::ref(t))) Chris@16: {} Chris@16: Chris@16: using base_type::operator=; Chris@16: Chris@16: /// \brief Fetch the stored value Chris@16: T &get() const Chris@16: { Chris@16: return proto::value(*this).get(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c local\<\> is a lazy wrapper for a reference to a value that is stored within the local itself. Chris@16: /// It is for use within xpressive semantic actions. Chris@16: /// Chris@16: /// \tparam T The type of the local variable. Chris@16: /// Chris@16: /// Below is an example of how to use \c local\<\> in semantic actions. Chris@16: /// Chris@16: /** \code Chris@16: using namespace boost::xpressive; Chris@16: local i(0); Chris@16: std::string str("1!2!3?"); Chris@16: // count the exciting digits, but not the Chris@16: // questionable ones. Chris@16: sregex rex = +( _d [ ++i ] >> '!' ); Chris@16: regex_search(str, rex); Chris@16: assert( i.get() == 2 ); Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// \note As the name "local" suggests, \c local\<\> objects and the regexes Chris@16: /// that refer to them should never leave the local scope. The value stored Chris@16: /// within the local object will be destroyed at the end of the \c local\<\>'s Chris@16: /// lifetime, and any regex objects still holding the \c local\<\> will be Chris@16: /// left with a dangling reference. Chris@16: template Chris@16: struct local Chris@16: : detail::value_wrapper Chris@16: , proto::terminal >::type Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: typedef typename proto::terminal >::type base_type; Chris@16: Chris@16: /// \brief Store a default-constructed value of type \c T Chris@16: local() Chris@16: : detail::value_wrapper() Chris@16: , base_type(base_type::make(boost::ref(detail::value_wrapper::value))) Chris@16: {} Chris@16: Chris@16: /// \param t The initial value. Chris@16: /// \brief Store a default-constructed value of type \c T Chris@16: explicit local(T const &t) Chris@16: : detail::value_wrapper(t) Chris@16: , base_type(base_type::make(boost::ref(detail::value_wrapper::value))) Chris@16: {} Chris@16: Chris@16: using base_type::operator=; Chris@16: Chris@16: /// Fetch the wrapped value. Chris@16: T &get() Chris@16: { Chris@16: return proto::value(*this); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: T const &get() const Chris@16: { Chris@16: return proto::value(*this); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// \brief \c as() is a lazy funtion for lexically casting a parameter to a different type. Chris@16: /// \tparam T The type to which to lexically cast the parameter. Chris@16: /// \param a The lazy value to lexically cast. Chris@16: /// \return A lazy object that, when evaluated, lexically casts its argument to the desired type. Chris@16: template Chris@16: typename detail::make_function::impl const, A const &>::result_type const Chris@16: as(A const &a) Chris@16: { Chris@16: return detail::make_function::impl const, A const &>()((op::as()), a); Chris@16: } Chris@16: Chris@16: /// \brief \c static_cast_ is a lazy funtion for statically casting a parameter to a different type. Chris@16: /// \tparam T The type to which to statically cast the parameter. Chris@16: /// \param a The lazy value to statically cast. Chris@16: /// \return A lazy object that, when evaluated, statically casts its argument to the desired type. Chris@16: template Chris@16: typename detail::make_function::impl const, A const &>::result_type const Chris@16: static_cast_(A const &a) Chris@16: { Chris@16: return detail::make_function::impl const, A const &>()((op::static_cast_()), a); Chris@16: } Chris@16: Chris@16: /// \brief \c dynamic_cast_ is a lazy funtion for dynamically casting a parameter to a different type. Chris@16: /// \tparam T The type to which to dynamically cast the parameter. Chris@16: /// \param a The lazy value to dynamically cast. Chris@16: /// \return A lazy object that, when evaluated, dynamically casts its argument to the desired type. Chris@16: template Chris@16: typename detail::make_function::impl const, A const &>::result_type const Chris@16: dynamic_cast_(A const &a) Chris@16: { Chris@16: return detail::make_function::impl const, A const &>()((op::dynamic_cast_()), a); Chris@16: } Chris@16: Chris@16: /// \brief \c dynamic_cast_ is a lazy funtion for const-casting a parameter to a different type. Chris@16: /// \tparam T The type to which to const-cast the parameter. Chris@16: /// \param a The lazy value to const-cast. Chris@16: /// \return A lazy object that, when evaluated, const-casts its argument to the desired type. Chris@16: template Chris@16: typename detail::make_function::impl const, A const &>::result_type const Chris@16: const_cast_(A const &a) Chris@16: { Chris@16: return detail::make_function::impl const, A const &>()((op::const_cast_()), a); Chris@16: } Chris@16: Chris@16: /// \brief Helper for constructing \c value\<\> objects. Chris@16: /// \return value\(t) Chris@16: template Chris@16: value const val(T const &t) Chris@16: { Chris@16: return value(t); Chris@16: } Chris@16: Chris@16: /// \brief Helper for constructing \c reference\<\> objects. Chris@16: /// \return reference\(t) Chris@16: template Chris@16: reference const ref(T &t) Chris@16: { Chris@16: return reference(t); Chris@16: } Chris@16: Chris@16: /// \brief Helper for constructing \c reference\<\> objects that Chris@16: /// store a reference to const. Chris@16: /// \return reference\(t) Chris@16: template Chris@16: reference const cref(T const &t) Chris@16: { Chris@16: return reference(t); Chris@16: } Chris@16: Chris@16: /// \brief For adding user-defined assertions to your regular expressions. Chris@16: /// Chris@16: /// \param t The UnaryPredicate object or Boolean semantic action. Chris@16: /// Chris@16: /// A \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.user_defined_assertions,user-defined assertion} Chris@16: /// is a kind of semantic action that evaluates Chris@16: /// a Boolean lambda and, if it evaluates to false, causes the match to Chris@16: /// fail at that location in the string. This will cause backtracking, Chris@16: /// so the match may ultimately succeed. Chris@16: /// Chris@16: /// To use \c check() to specify a user-defined assertion in a regex, use the Chris@16: /// following syntax: Chris@16: /// Chris@16: /** \code Chris@16: sregex s = (_d >> _d)[check( XXX )]; // XXX is a custom assertion Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// The assertion is evaluated with a \c sub_match\<\> object that delineates Chris@16: /// what part of the string matched the sub-expression to which the assertion Chris@16: /// was attached. Chris@16: /// Chris@16: /// \c check() can be used with an ordinary predicate that takes a Chris@16: /// \c sub_match\<\> object as follows: Chris@16: /// Chris@16: /** \code Chris@16: // A predicate that is true IFF a sub-match is Chris@16: // either 3 or 6 characters long. Chris@16: struct three_or_six Chris@16: { Chris@16: bool operator()(ssub_match const &sub) const Chris@16: { Chris@16: return sub.length() == 3 || sub.length() == 6; Chris@16: } Chris@16: }; Chris@16: Chris@16: // match words of 3 characters or 6 characters. Chris@16: sregex rx = (bow >> +_w >> eow)[ check(three_or_six()) ] ; Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// Alternately, \c check() can be used to define inline custom Chris@16: /// assertions with the same syntax as is used to define semantic Chris@16: /// actions. The following code is equivalent to above: Chris@16: /// Chris@16: /** \code Chris@16: // match words of 3 characters or 6 characters. Chris@16: sregex rx = (bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ] ; Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// Within a custom assertion, \c _ is a placeholder for the \c sub_match\<\> Chris@16: /// That delineates the part of the string matched by the sub-expression to Chris@16: /// which the custom assertion was attached. Chris@16: #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. Chris@16: template Chris@16: detail::unspecified check(T const &t); Chris@16: #else Chris@16: proto::terminal::type const check = {{}}; Chris@16: #endif Chris@16: Chris@16: /// \brief For binding local variables to placeholders in semantic actions when Chris@16: /// constructing a \c regex_iterator or a \c regex_token_iterator. Chris@16: /// Chris@16: /// \param args A set of argument bindings, where each argument binding is an assignment Chris@16: /// expression, the left hand side of which must be an instance of \c placeholder\ Chris@16: /// for some \c X, and the right hand side is an lvalue of type \c X. Chris@16: /// Chris@16: /// \c xpressive::let() serves the same purpose as match_results::let(); Chris@16: /// that is, it binds a placeholder to a local value. The purpose is to allow a Chris@16: /// regex with semantic actions to be defined that refers to objects that do not yet exist. Chris@16: /// Rather than referring directly to an object, a semantic action can refer to a placeholder, Chris@16: /// and the value of the placeholder can be specified later with a let expression. Chris@16: /// The let expression created with \c let() is passed to the constructor of either Chris@16: /// \c regex_iterator or \c regex_token_iterator. Chris@16: /// Chris@16: /// See the section \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.referring_to_non_local_variables, "Referring to Non-Local Variables"} Chris@16: /// in the Users' Guide for more discussion. Chris@16: /// Chris@16: /// \em Example: Chris@16: /// Chris@16: /** Chris@16: \code Chris@16: // Define a placeholder for a map object: Chris@16: placeholder > _map; Chris@16: Chris@16: // Match a word and an integer, separated by =>, Chris@16: // and then stuff the result into a std::map<> Chris@16: sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) Chris@16: [ _map[s1] = as(s2) ]; Chris@16: Chris@16: // The string to parse Chris@16: std::string str("aaa=>1 bbb=>23 ccc=>456"); Chris@16: Chris@16: // Here is the actual map to fill in: Chris@16: std::map result; Chris@16: Chris@16: // Create a regex_iterator to find all the matches Chris@16: sregex_iterator it(str.begin(), str.end(), pair, let(_map=result)); Chris@16: sregex_iterator end; Chris@16: Chris@16: // step through all the matches, and fill in Chris@16: // the result map Chris@16: while(it != end) Chris@16: ++it; Chris@16: Chris@16: std::cout << result["aaa"] << '\n'; Chris@16: std::cout << result["bbb"] << '\n'; Chris@16: std::cout << result["ccc"] << '\n'; Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// The above code displays: Chris@16: /// Chris@16: /** \code{.txt} Chris@16: 1 Chris@16: 23 Chris@16: 456 Chris@16: \endcode Chris@16: */ Chris@16: #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. Chris@16: template Chris@16: detail::unspecified let(ArgBindings const &...args); Chris@16: #else Chris@16: detail::let_::type> const let = {{{}}}; Chris@16: #endif Chris@16: Chris@16: /// \brief For defining a placeholder to stand in for a variable a semantic action. Chris@16: /// Chris@16: /// Use \c placeholder\<\> to define a placeholder for use in semantic actions to stand Chris@16: /// in for real objects. The use of placeholders allows regular expressions with actions Chris@16: /// to be defined once and reused in many contexts to read and write from objects which Chris@16: /// were not available when the regex was defined. Chris@16: /// Chris@16: /// \tparam T The type of the object for which this placeholder stands in. Chris@16: /// \tparam I An optional identifier that can be used to distinguish this placeholder Chris@16: /// from others that may be used in the same semantic action that happen Chris@16: /// to have the same type. Chris@16: /// Chris@16: /// You can use \c placeholder\<\> by creating an object of type \c placeholder\ Chris@16: /// and using that object in a semantic action exactly as you intend an object of Chris@16: /// type \c T to be used. Chris@16: /// Chris@16: /** Chris@16: \code Chris@16: placeholder _i; Chris@16: placeholder _d; Chris@16: Chris@16: sregex rex = ( some >> regex >> here ) Chris@16: [ ++_i, _d *= _d ]; Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// Then, when doing a pattern match with either \c regex_search(), Chris@16: /// \c regex_match() or \c regex_replace(), pass a \c match_results\<\> object that Chris@16: /// contains bindings for the placeholders used in the regex object's semantic actions. Chris@16: /// You can create the bindings by calling \c match_results::let as follows: Chris@16: /// Chris@16: /** Chris@16: \code Chris@16: int i = 0; Chris@16: double d = 3.14; Chris@16: Chris@16: smatch what; Chris@16: what.let(_i = i) Chris@16: .let(_d = d); Chris@16: Chris@16: if(regex_match("some string", rex, what)) Chris@16: // i and d mutated here Chris@16: \endcode Chris@16: */ Chris@16: /// Chris@16: /// If a semantic action executes that contains an unbound placeholder, a exception of Chris@16: /// type \c regex_error is thrown. Chris@16: /// Chris@16: /// See the discussion for \c xpressive::let() and the Chris@16: /// \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.referring_to_non_local_variables, "Referring to Non-Local Variables"} Chris@16: /// section in the Users' Guide for more information. Chris@16: /// Chris@16: /// Example: Chris@16: /// Chris@16: /** Chris@16: \code Chris@16: // Define a placeholder for a map object: Chris@16: placeholder > _map; Chris@16: Chris@16: // Match a word and an integer, separated by =>, Chris@16: // and then stuff the result into a std::map<> Chris@16: sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) Chris@16: [ _map[s1] = as(s2) ]; Chris@16: Chris@16: // Match one or more word/integer pairs, separated Chris@16: // by whitespace. Chris@16: sregex rx = pair >> *(+_s >> pair); Chris@16: Chris@16: // The string to parse Chris@16: std::string str("aaa=>1 bbb=>23 ccc=>456"); Chris@16: Chris@16: // Here is the actual map to fill in: Chris@16: std::map result; Chris@16: Chris@16: // Bind the _map placeholder to the actual map Chris@16: smatch what; Chris@16: what.let( _map = result ); Chris@16: Chris@16: // Execute the match and fill in result map Chris@16: if(regex_match(str, what, rx)) Chris@16: { Chris@16: std::cout << result["aaa"] << '\n'; Chris@16: std::cout << result["bbb"] << '\n'; Chris@16: std::cout << result["ccc"] << '\n'; Chris@16: } Chris@16: \endcode Chris@16: */ Chris@16: #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. Chris@16: template Chris@16: struct placeholder Chris@16: { Chris@16: /// \param t The object to associate with this placeholder Chris@16: /// \return An object of unspecified type that records the association of \c t Chris@16: /// with \c *this. Chris@16: detail::unspecified operator=(T &t) const; Chris@16: /// \overload Chris@16: detail::unspecified operator=(T const &t) const; Chris@16: }; Chris@16: #else Chris@16: template Chris@16: struct placeholder Chris@16: { Chris@16: typedef placeholder this_type; Chris@16: typedef Chris@16: typename proto::terminal > >::type Chris@16: action_arg_type; Chris@16: Chris@16: BOOST_PROTO_EXTENDS(action_arg_type, this_type, proto::default_domain) Chris@16: }; Chris@16: #endif Chris@16: Chris@16: /// \brief A lazy funtion for constructing objects objects of the specified type. Chris@16: /// \tparam T The type of object to construct. Chris@16: /// \param args The arguments to the constructor. Chris@16: /// \return A lazy object that, when evaluated, returns T(xs...), where Chris@16: /// xs... is the result of evaluating the lazy arguments Chris@16: /// args.... Chris@16: #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. Chris@16: template Chris@16: detail::unspecified construct(Args const &...args); Chris@16: #else Chris@16: /// INTERNAL ONLY Chris@16: #define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, a) \ Chris@16: template \ Chris@16: typename detail::make_function::impl< \ Chris@16: op::construct const \ Chris@16: BOOST_PP_COMMA_IF(N) A_const_ref(N) \ Chris@16: >::result_type const \ Chris@16: construct(A_const_ref_a(N)) \ Chris@16: { \ Chris@16: return detail::make_function::impl< \ Chris@16: op::construct const \ Chris@16: BOOST_PP_COMMA_IF(N) A_const_ref(N) \ Chris@16: >()((op::construct()) BOOST_PP_COMMA_IF(N) a(N)); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: typename detail::make_function::impl< \ Chris@16: op::throw_ const \ Chris@16: BOOST_PP_COMMA_IF(N) A_const_ref(N) \ Chris@16: >::result_type const \ Chris@16: throw_(A_const_ref_a(N)) \ Chris@16: { \ Chris@16: return detail::make_function::impl< \ Chris@16: op::throw_ const \ Chris@16: BOOST_PP_COMMA_IF(N) A_const_ref(N) \ Chris@16: >()((op::throw_()) BOOST_PP_COMMA_IF(N) a(N)); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_PROTO_LOCAL_a BOOST_PROTO_a ///< INTERNAL ONLY Chris@16: #define BOOST_PROTO_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)) ///< INTERNAL ONLY Chris@16: #include BOOST_PROTO_LOCAL_ITERATE() Chris@16: #endif Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: inline void ignore_unused_regex_actions() Chris@16: { Chris@16: detail::ignore_unused(xpressive::at); Chris@16: detail::ignore_unused(xpressive::push); Chris@16: detail::ignore_unused(xpressive::push_back); Chris@16: detail::ignore_unused(xpressive::push_front); Chris@16: detail::ignore_unused(xpressive::pop); Chris@16: detail::ignore_unused(xpressive::pop_back); Chris@16: detail::ignore_unused(xpressive::pop_front); Chris@16: detail::ignore_unused(xpressive::top); Chris@16: detail::ignore_unused(xpressive::back); Chris@16: detail::ignore_unused(xpressive::front); Chris@16: detail::ignore_unused(xpressive::first); Chris@16: detail::ignore_unused(xpressive::second); Chris@16: detail::ignore_unused(xpressive::matched); Chris@16: detail::ignore_unused(xpressive::length); Chris@16: detail::ignore_unused(xpressive::str); Chris@16: detail::ignore_unused(xpressive::insert); Chris@16: detail::ignore_unused(xpressive::make_pair); Chris@16: detail::ignore_unused(xpressive::unwrap_reference); Chris@16: detail::ignore_unused(xpressive::check); Chris@16: detail::ignore_unused(xpressive::let); Chris@16: } Chris@16: Chris@16: struct mark_nbr Chris@16: { Chris@16: BOOST_PROTO_CALLABLE() Chris@16: typedef int result_type; Chris@16: Chris@16: int operator()(mark_placeholder m) const Chris@16: { Chris@16: return m.mark_number_; Chris@16: } Chris@16: }; Chris@16: Chris@16: struct ReplaceAlgo Chris@16: : proto::or_< Chris@16: proto::when< Chris@16: proto::terminal Chris@16: , op::at(proto::_data, proto::call) Chris@16: > Chris@16: , proto::when< Chris@16: proto::terminal Chris@16: , op::at(proto::_data, proto::size_t<0>) Chris@16: > Chris@16: , proto::when< Chris@16: proto::terminal > Chris@16: , op::unwrap_reference(proto::_value) Chris@16: > Chris@16: , proto::_default Chris@16: > Chris@16: {}; Chris@16: } Chris@16: }} Chris@16: Chris@16: #if BOOST_MSVC Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: #endif // BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007