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