Imported existing code
This commit is contained in:
194
libraries/include/boost/proto/args.hpp
Normal file
194
libraries/include/boost/proto/args.hpp
Normal file
@@ -0,0 +1,194 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file args.hpp
|
||||
/// Contains definition of \c term\<\>, \c list1\<\>, \c list2\<\>, ...
|
||||
/// class templates.
|
||||
//
|
||||
// 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_PROTO_ARGS_HPP_EAN_04_01_2005
|
||||
#define BOOST_PROTO_ARGS_HPP_EAN_04_01_2005
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/void.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr>
|
||||
struct expr_traits
|
||||
{
|
||||
typedef Expr value_type;
|
||||
typedef Expr &reference;
|
||||
typedef Expr const &const_reference;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr>
|
||||
struct expr_traits<Expr &>
|
||||
{
|
||||
typedef Expr value_type;
|
||||
typedef Expr &reference;
|
||||
typedef Expr &const_reference;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr>
|
||||
struct expr_traits<Expr const &>
|
||||
{
|
||||
typedef Expr value_type;
|
||||
typedef Expr const &reference;
|
||||
typedef Expr const &const_reference;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename T>
|
||||
struct term_traits
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T &reference;
|
||||
typedef T const &const_reference;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename T>
|
||||
struct term_traits<T &>
|
||||
{
|
||||
typedef typename mpl::if_c<is_function<T>::value, T &, T>::type value_type;
|
||||
typedef T &reference;
|
||||
typedef T &const_reference;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename T>
|
||||
struct term_traits<T const &>
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T const &reference;
|
||||
typedef T const &const_reference;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename T, std::size_t N>
|
||||
struct term_traits<T (&)[N]>
|
||||
{
|
||||
typedef T value_type[N];
|
||||
typedef T (&reference)[N];
|
||||
typedef T (&const_reference)[N];
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename T, std::size_t N>
|
||||
struct term_traits<T const (&)[N]>
|
||||
{
|
||||
typedef T value_type[N];
|
||||
typedef T const (&reference)[N];
|
||||
typedef T const (&const_reference)[N];
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename T, std::size_t N>
|
||||
struct term_traits<T[N]>
|
||||
{
|
||||
typedef T value_type[N];
|
||||
typedef T (&reference)[N];
|
||||
typedef T const (&const_reference)[N];
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename T, std::size_t N>
|
||||
struct term_traits<T const[N]>
|
||||
{
|
||||
typedef T value_type[N];
|
||||
typedef T const (&reference)[N];
|
||||
typedef T const (&const_reference)[N];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(argsns_)
|
||||
|
||||
#define BOOST_PROTO_DEFINE_CHILD_N(Z, N, DATA) \
|
||||
typedef BOOST_PP_CAT(Arg, N) BOOST_PP_CAT(child, N); \
|
||||
/**< INTERNAL ONLY */
|
||||
|
||||
#define BOOST_PROTO_DEFINE_VOID_N(z, n, data) \
|
||||
typedef mpl::void_ BOOST_PP_CAT(child, n); \
|
||||
/**< INTERNAL ONLY */
|
||||
|
||||
/// \brief A type sequence, for use as the 2nd parameter to the \c expr\<\> class template.
|
||||
///
|
||||
/// A type sequence, for use as the 2nd parameter to the \c expr\<\> class template.
|
||||
/// The types in the sequence correspond to the children of a node in an expression tree.
|
||||
template< typename Arg0 >
|
||||
struct term
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(long, arity = 0);
|
||||
typedef Arg0 child0;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_DEFINE_VOID_N, ~)
|
||||
#endif
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
typedef Arg0 back_;
|
||||
};
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/args.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_PROTO_DEFINE_CHILD_N
|
||||
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(argsns_)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_PROTO_BUILDING_DOCS
|
||||
using namespace argsns_;
|
||||
#endif
|
||||
}}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
/// \brief A type sequence, for use as the 2nd parameter to the \c expr\<\> class template.
|
||||
///
|
||||
/// A type sequence, for use as the 2nd parameter to the \c expr\<\> class template.
|
||||
/// The types in the sequence correspond to the children of a node in an expression tree.
|
||||
template< BOOST_PP_ENUM_PARAMS(N, typename Arg) >
|
||||
struct BOOST_PP_CAT(list, N)
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(long, arity = N);
|
||||
BOOST_PP_REPEAT(N, BOOST_PROTO_DEFINE_CHILD_N, ~)
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
|
||||
BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_DEFINE_VOID_N, ~)
|
||||
#endif
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
typedef BOOST_PP_CAT(Arg, BOOST_PP_DEC(N)) back_;
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
18
libraries/include/boost/proto/context.hpp
Normal file
18
libraries/include/boost/proto/context.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file context.hpp
|
||||
/// Includes all the context classes in the context/ sub-directory.
|
||||
//
|
||||
// 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_PROTO_CONTEXT_HPP_EAN_06_23_2007
|
||||
#define BOOST_PROTO_CONTEXT_HPP_EAN_06_23_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp> // must be first include
|
||||
#include <boost/proto/context/null.hpp>
|
||||
#include <boost/proto/context/default.hpp>
|
||||
#include <boost/proto/context/callable.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp> // must be last include
|
||||
|
||||
#endif
|
||||
329
libraries/include/boost/proto/context/callable.hpp
Normal file
329
libraries/include/boost/proto/context/callable.hpp
Normal file
@@ -0,0 +1,329 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file callable.hpp
|
||||
/// Definintion of callable_context\<\>, an evaluation context for
|
||||
/// proto::eval() that explodes each node and calls the derived context
|
||||
/// type with the expressions constituents. If the derived context doesn't
|
||||
/// have an overload that handles this node, fall back to some other
|
||||
/// context.
|
||||
//
|
||||
// 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_PROTO_CONTEXT_CALLABLE_HPP_EAN_06_23_2007
|
||||
#define BOOST_PROTO_CONTEXT_CALLABLE_HPP_EAN_06_23_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp> // must be first include
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/selection/max.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp> // for child_c
|
||||
#include <boost/proto/detail/suffix.hpp> // must be last include
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
yes_type check_is_expr_handled(T const &);
|
||||
|
||||
no_type check_is_expr_handled(private_type_ const &);
|
||||
|
||||
template<typename Context, long Arity>
|
||||
struct callable_context_wrapper;
|
||||
|
||||
template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
|
||||
struct is_expr_handled;
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct is_expr_handled<Expr, Context, 0>
|
||||
{
|
||||
static callable_context_wrapper<Context, 1> &sctx_;
|
||||
static Expr &sexpr_;
|
||||
static typename Expr::proto_tag &stag_;
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value =
|
||||
(
|
||||
sizeof(yes_type) ==
|
||||
sizeof(
|
||||
detail::check_is_expr_handled(
|
||||
(sctx_(stag_, proto::value(sexpr_)), 0)
|
||||
)
|
||||
)));
|
||||
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace context
|
||||
{
|
||||
/// \brief A BinaryFunction that accepts a Proto expression and a
|
||||
/// callable context and calls the context with the expression tag
|
||||
/// and children as arguments, effectively fanning the expression
|
||||
/// out.
|
||||
///
|
||||
/// <tt>callable_eval\<\></tt> requires that \c Context is a
|
||||
/// PolymorphicFunctionObject that can be invoked with \c Expr's
|
||||
/// tag and children as expressions, as follows:
|
||||
///
|
||||
/// \code
|
||||
/// context(Expr::proto_tag(), child_c<0>(expr), child_c<1>(expr), ...)
|
||||
/// \endcode
|
||||
template<
|
||||
typename Expr
|
||||
, typename Context
|
||||
, long Arity BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity_c)
|
||||
>
|
||||
struct callable_eval
|
||||
{};
|
||||
|
||||
/// \brief A BinaryFunction that accepts a Proto expression and a
|
||||
/// callable context and calls the context with the expression tag
|
||||
/// and children as arguments, effectively fanning the expression
|
||||
/// out.
|
||||
///
|
||||
/// <tt>callable_eval\<\></tt> requires that \c Context is a
|
||||
/// PolymorphicFunctionObject that can be invoked with \c Expr's
|
||||
/// tag and children as expressions, as follows:
|
||||
///
|
||||
/// \code
|
||||
/// context(Expr::proto_tag(), value(expr))
|
||||
/// \endcode
|
||||
template<typename Expr, typename Context>
|
||||
struct callable_eval<Expr, Context, 0>
|
||||
{
|
||||
typedef typename proto::result_of::value<Expr const &>::type value_type;
|
||||
|
||||
typedef
|
||||
typename boost::result_of<
|
||||
Context(typename Expr::proto_tag, value_type)
|
||||
>::type
|
||||
result_type;
|
||||
|
||||
/// \param expr The current expression
|
||||
/// \param context The callable evaluation context
|
||||
/// \return <tt>context(Expr::proto_tag(), value(expr))</tt>
|
||||
result_type operator ()(Expr &expr, Context &context) const
|
||||
{
|
||||
return context(typename Expr::proto_tag(), proto::value(expr));
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief An evaluation context adaptor that makes authoring a
|
||||
/// context a simple matter of writing function overloads, rather
|
||||
/// then writing template specializations.
|
||||
///
|
||||
/// <tt>callable_context\<\></tt> is a base class that implements
|
||||
/// the context protocol by passing fanned-out expression nodes to
|
||||
/// the derived context, making it easy to customize the handling
|
||||
/// of expression types by writing function overloads. Only those
|
||||
/// expression types needing special handling require explicit
|
||||
/// handling. All others are dispatched to a user-specified
|
||||
/// default context, \c DefaultCtx.
|
||||
///
|
||||
/// <tt>callable_context\<\></tt> is defined simply as:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename Context, typename DefaultCtx = default_context>
|
||||
/// struct callable_context
|
||||
/// {
|
||||
/// template<typename Expr, typename ThisContext = Context>
|
||||
/// struct eval
|
||||
/// : mpl::if_<
|
||||
/// is_expr_handled_<Expr, Context> // For exposition
|
||||
/// , callable_eval<Expr, ThisContext>
|
||||
/// , typename DefaultCtx::template eval<Expr, Context>
|
||||
/// >::type
|
||||
/// {};
|
||||
/// };
|
||||
/// \endcode
|
||||
///
|
||||
/// The Boolean metafunction <tt>is_expr_handled_\<\></tt> uses
|
||||
/// metaprogramming tricks to determine whether \c Context has
|
||||
/// an overloaded function call operator that accepts the
|
||||
/// fanned-out constituents of an expression of type \c Expr.
|
||||
/// If so, the handling of the expression is dispatched to
|
||||
/// <tt>callable_eval\<\></tt>. If not, it is dispatched to
|
||||
/// the user-specified \c DefaultCtx.
|
||||
///
|
||||
/// Below is an example of how to use <tt>callable_context\<\></tt>:
|
||||
///
|
||||
/// \code
|
||||
/// // An evaluation context that increments all
|
||||
/// // integer terminals in-place.
|
||||
/// struct increment_ints
|
||||
/// : callable_context<
|
||||
/// increment_ints const // derived context
|
||||
/// , null_context const // fall-back context
|
||||
/// >
|
||||
/// {
|
||||
/// typedef void result_type;
|
||||
///
|
||||
/// // Handle int terminals here:
|
||||
/// void operator()(proto::tag::terminal, int &i) const
|
||||
/// {
|
||||
/// ++i;
|
||||
/// }
|
||||
/// };
|
||||
/// \endcode
|
||||
///
|
||||
/// With \c increment_ints, we can do the following:
|
||||
///
|
||||
/// \code
|
||||
/// literal<int> i = 0, j = 10;
|
||||
/// proto::eval( i - j * 3.14, increment_ints() );
|
||||
///
|
||||
/// assert( i.get() == 1 && j.get() == 11 );
|
||||
/// \endcode
|
||||
template<
|
||||
typename Context
|
||||
, typename DefaultCtx BOOST_PROTO_WHEN_BUILDING_DOCS(= default_context)
|
||||
>
|
||||
struct callable_context
|
||||
{
|
||||
/// A BinaryFunction that accepts an \c Expr and a
|
||||
/// \c Context, and either fans out the expression and passes
|
||||
/// it to the context, or else hands off the expression to
|
||||
/// \c DefaultCtx.
|
||||
///
|
||||
/// If \c Context is a PolymorphicFunctionObject such that
|
||||
/// it can be invoked with the tag and children of \c Expr,
|
||||
/// as <tt>ctx(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr)...)</tt>,
|
||||
/// then <tt>eval\<Expr, ThisContext\></tt> inherits from
|
||||
/// <tt>callable_eval\<Expr, ThisContext\></tt>. Otherwise,
|
||||
/// <tt>eval\<Expr, ThisContext\></tt> inherits from
|
||||
/// <tt>DefaultCtx::eval\<Expr, Context\></tt>.
|
||||
template<typename Expr, typename ThisContext = Context>
|
||||
struct eval
|
||||
: mpl::if_<
|
||||
detail::is_expr_handled<Expr, Context>
|
||||
, callable_eval<Expr, ThisContext>
|
||||
, typename DefaultCtx::template eval<Expr, Context>
|
||||
>::type
|
||||
{};
|
||||
};
|
||||
}
|
||||
|
||||
#define BOOST_PROTO_CHILD_N_TYPE(Z, N, Expr) \
|
||||
typedef typename proto::result_of::child_c<Expr const &, N>::type BOOST_PP_CAT(child, N); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_CHILD_N(Z, N, expr) \
|
||||
proto::child_c<N>(expr) \
|
||||
/**/
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/context/callable.hpp>)) \
|
||||
/**/
|
||||
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_PROTO_CHILD_N_TYPE
|
||||
#undef BOOST_PROTO_CHILD_N
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Context>
|
||||
struct callable_context_wrapper<Context, N>
|
||||
: remove_cv<Context>::type
|
||||
{
|
||||
callable_context_wrapper();
|
||||
typedef
|
||||
private_type_ const &fun_type(
|
||||
BOOST_PP_ENUM_PARAMS(
|
||||
BOOST_PP_INC(N)
|
||||
, detail::dont_care BOOST_PP_INTERCEPT
|
||||
)
|
||||
);
|
||||
operator fun_type *() const;
|
||||
};
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct is_expr_handled<Expr, Context, N>
|
||||
{
|
||||
static callable_context_wrapper<Context, N> &sctx_;
|
||||
static Expr &sexpr_;
|
||||
static typename Expr::proto_tag &stag_;
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value =
|
||||
(
|
||||
sizeof(yes_type) ==
|
||||
sizeof(
|
||||
detail::check_is_expr_handled(
|
||||
(sctx_(
|
||||
stag_
|
||||
BOOST_PP_ENUM_TRAILING(N, BOOST_PROTO_CHILD_N, sexpr_)
|
||||
), 0)
|
||||
)
|
||||
)));
|
||||
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace context
|
||||
{
|
||||
/// \brief A BinaryFunction that accepts a Proto expression and a
|
||||
/// callable context and calls the context with the expression tag
|
||||
/// and children as arguments, effectively fanning the expression
|
||||
/// out.
|
||||
///
|
||||
/// <tt>callable_eval\<\></tt> requires that \c Context is a
|
||||
/// PolymorphicFunctionObject that can be invoked with \c Expr's
|
||||
/// tag and children as expressions, as follows:
|
||||
///
|
||||
/// \code
|
||||
/// context(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr), ...)
|
||||
/// \endcode
|
||||
template<typename Expr, typename Context>
|
||||
struct callable_eval<Expr, Context, N>
|
||||
{
|
||||
BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD_N_TYPE, Expr)
|
||||
|
||||
typedef
|
||||
typename boost::result_of<
|
||||
Context(
|
||||
typename Expr::proto_tag
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(N, child)
|
||||
)
|
||||
>::type
|
||||
result_type;
|
||||
|
||||
/// \param expr The current expression
|
||||
/// \param context The callable evaluation context
|
||||
/// \return <tt>context(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr), ...)</tt>
|
||||
result_type operator ()(Expr &expr, Context &context) const
|
||||
{
|
||||
return context(
|
||||
typename Expr::proto_tag()
|
||||
BOOST_PP_ENUM_TRAILING(N, BOOST_PROTO_CHILD_N, expr)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
434
libraries/include/boost/proto/context/default.hpp
Normal file
434
libraries/include/boost/proto/context/default.hpp
Normal file
@@ -0,0 +1,434 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file default.hpp
|
||||
/// Definintion of default_context, a default evaluation context for
|
||||
/// proto::eval() that uses Boost.Typeof to deduce return types
|
||||
/// of the built-in operators.
|
||||
//
|
||||
// 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_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
|
||||
#define BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp> // must be first include
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_member_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_object_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_function_pointer.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/tags.hpp>
|
||||
#include <boost/proto/eval.hpp>
|
||||
#include <boost/proto/traits.hpp> // for proto::child_c()
|
||||
#include <boost/proto/detail/decltype.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp> // must be last include
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define UNREF(x) typename boost::remove_reference<x>::type
|
||||
|
||||
namespace context
|
||||
{
|
||||
template<
|
||||
typename Expr
|
||||
, typename Context
|
||||
, typename Tag BOOST_PROTO_WHEN_BUILDING_DOCS(= typename Expr::proto_tag)
|
||||
, long Arity BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity_c)
|
||||
>
|
||||
struct default_eval
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_UNARY_OP_RESULT(OP, TAG, MAKE) \
|
||||
template<typename Expr, typename Context> \
|
||||
struct default_eval<Expr, Context, TAG, 1> \
|
||||
{ \
|
||||
private: \
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type e0; \
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0; \
|
||||
public: \
|
||||
BOOST_PROTO_DECLTYPE_(OP proto::detail::MAKE<r0>(), result_type) \
|
||||
result_type operator ()(Expr &expr, Context &ctx) const \
|
||||
{ \
|
||||
return OP proto::eval(proto::child_c<0>(expr), ctx); \
|
||||
} \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_BINARY_OP_RESULT(OP, TAG, LMAKE, RMAKE) \
|
||||
template<typename Expr, typename Context> \
|
||||
struct default_eval<Expr, Context, TAG, 2> \
|
||||
{ \
|
||||
private: \
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type e0; \
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type e1; \
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0; \
|
||||
typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1; \
|
||||
public: \
|
||||
BOOST_PROTO_DECLTYPE_( \
|
||||
proto::detail::LMAKE<r0>() OP proto::detail::RMAKE<r1>() \
|
||||
, result_type \
|
||||
) \
|
||||
result_type operator ()(Expr &expr, Context &ctx) const \
|
||||
{ \
|
||||
return proto::eval( \
|
||||
proto::child_c<0>(expr), ctx) OP proto::eval(proto::child_c<1>(expr) \
|
||||
, ctx \
|
||||
); \
|
||||
} \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
BOOST_PROTO_UNARY_OP_RESULT(+, proto::tag::unary_plus, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(-, proto::tag::negate, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(*, proto::tag::dereference, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(~, proto::tag::complement, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(&, proto::tag::address_of, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(!, proto::tag::logical_not, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(++, proto::tag::pre_inc, make_mutable)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(--, proto::tag::pre_dec, make_mutable)
|
||||
|
||||
BOOST_PROTO_BINARY_OP_RESULT(<<, proto::tag::shift_left, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(>>, proto::tag::shift_right, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(*, proto::tag::multiplies, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(/, proto::tag::divides, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(%, proto::tag::modulus, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(+, proto::tag::plus, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(-, proto::tag::minus, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(<, proto::tag::less, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(>, proto::tag::greater, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(<=, proto::tag::less_equal, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(>=, proto::tag::greater_equal, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(==, proto::tag::equal_to, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(!=, proto::tag::not_equal_to, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(||, proto::tag::logical_or, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(&&, proto::tag::logical_and, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(&, proto::tag::bitwise_and, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(|, proto::tag::bitwise_or, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(^, proto::tag::bitwise_xor, make, make)
|
||||
|
||||
BOOST_PROTO_BINARY_OP_RESULT(=, proto::tag::assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(<<=, proto::tag::shift_left_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(>>=, proto::tag::shift_right_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(*=, proto::tag::multiplies_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(/=, proto::tag::divides_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(%=, proto::tag::modulus_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(+=, proto::tag::plus_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(-=, proto::tag::minus_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(&=, proto::tag::bitwise_and_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(|=, proto::tag::bitwise_or_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(^=, proto::tag::bitwise_xor_assign, make_mutable, make)
|
||||
|
||||
#undef BOOST_PROTO_UNARY_OP_RESULT
|
||||
#undef BOOST_PROTO_BINARY_OP_RESULT
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr, typename Context>
|
||||
struct is_member_function_eval
|
||||
{
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
|
||||
typedef typename remove_const<typename remove_reference<r1>::type>::type uncvref_r1;
|
||||
typedef typename is_member_function_pointer<uncvref_r1>::type type;
|
||||
BOOST_STATIC_CONSTANT(bool, value = type::value);
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr, typename Context, bool IsMemFunCall>
|
||||
struct memfun_eval
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
|
||||
typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
|
||||
public:
|
||||
typedef typename detail::mem_ptr_fun<r0, r1>::result_type result_type;
|
||||
result_type operator ()(Expr &expr, Context &ctx) const
|
||||
{
|
||||
return detail::mem_ptr_fun<r0, r1>()(
|
||||
proto::eval(proto::child_c<0>(expr), ctx)
|
||||
, proto::eval(proto::child_c<1>(expr), ctx)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr, typename Context>
|
||||
struct memfun_eval<Expr, Context, true>
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
|
||||
typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
|
||||
public:
|
||||
typedef detail::memfun<r0, r1> result_type;
|
||||
result_type const operator ()(Expr &expr, Context &ctx) const
|
||||
{
|
||||
return detail::memfun<r0, r1>(
|
||||
proto::eval(proto::child_c<0>(expr), ctx)
|
||||
, proto::eval(proto::child_c<1>(expr), ctx)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, tag::mem_ptr, 2>
|
||||
: memfun_eval<Expr, Context, is_member_function_eval<Expr, Context>::value>
|
||||
{};
|
||||
|
||||
template<typename Expr, typename Context, typename Tag>
|
||||
struct default_eval<Expr, Context, Tag, 0>
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::value<Expr &>::type
|
||||
result_type;
|
||||
|
||||
result_type operator ()(Expr &expr, Context &) const
|
||||
{
|
||||
return proto::value(expr);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle post-increment specially.
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, proto::tag::post_inc, 1>
|
||||
{
|
||||
private:
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
|
||||
public:
|
||||
BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() ++, result_type)
|
||||
result_type operator ()(Expr &expr, Context &ctx) const
|
||||
{
|
||||
return proto::eval(proto::child_c<0>(expr), ctx) ++;
|
||||
}
|
||||
};
|
||||
|
||||
// Handle post-decrement specially.
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, proto::tag::post_dec, 1>
|
||||
{
|
||||
private:
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
|
||||
public:
|
||||
BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() --, result_type)
|
||||
result_type operator ()(Expr &expr, Context &ctx) const
|
||||
{
|
||||
return proto::eval(proto::child_c<0>(expr), ctx) --;
|
||||
}
|
||||
};
|
||||
|
||||
// Handle subscript specially.
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, proto::tag::subscript, 2>
|
||||
{
|
||||
private:
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
|
||||
typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
|
||||
public:
|
||||
BOOST_PROTO_DECLTYPE_(proto::detail::make_subscriptable<r0>()[proto::detail::make<r1>()], result_type)
|
||||
result_type operator ()(Expr &expr, Context &ctx) const
|
||||
{
|
||||
return proto::eval(proto::child_c<0>(expr), ctx)[proto::eval(proto::child_c<1>(expr), ctx)];
|
||||
}
|
||||
};
|
||||
|
||||
// Handle if_else_ specially.
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, proto::tag::if_else_, 3>
|
||||
{
|
||||
private:
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename proto::result_of::child_c<Expr, 2>::type e2;
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
|
||||
typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
|
||||
typedef typename proto::result_of::eval<UNREF(e2), Context>::type r2;
|
||||
public:
|
||||
BOOST_PROTO_DECLTYPE_(
|
||||
proto::detail::make<r0>()
|
||||
? proto::detail::make<r1>()
|
||||
: proto::detail::make<r2>()
|
||||
, result_type
|
||||
)
|
||||
result_type operator ()(Expr &expr, Context &ctx) const
|
||||
{
|
||||
return proto::eval(proto::child_c<0>(expr), ctx)
|
||||
? proto::eval(proto::child_c<1>(expr), ctx)
|
||||
: proto::eval(proto::child_c<2>(expr), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle comma specially.
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, proto::tag::comma, 2>
|
||||
{
|
||||
private:
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
|
||||
typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
|
||||
public:
|
||||
typedef typename proto::detail::comma_result<r0, r1>::type result_type;
|
||||
result_type operator ()(Expr &expr, Context &ctx) const
|
||||
{
|
||||
return proto::eval(proto::child_c<0>(expr), ctx), proto::eval(proto::child_c<1>(expr), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle function specially
|
||||
#define EVAL_TYPE(Z, N, DATA) \
|
||||
typename proto::result_of::eval< \
|
||||
typename remove_reference< \
|
||||
typename proto::result_of::child_c<DATA, N>::type \
|
||||
>::type \
|
||||
, Context \
|
||||
>::type \
|
||||
/**/
|
||||
|
||||
#define EVAL(Z, N, DATA) \
|
||||
proto::eval(proto::child_c<N>(DATA), context) \
|
||||
/**/
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, proto::tag::function, 1>
|
||||
{
|
||||
typedef
|
||||
typename proto::detail::result_of_fixup<EVAL_TYPE(~, 0, Expr)>::type
|
||||
function_type;
|
||||
|
||||
typedef
|
||||
typename boost::result_of<function_type()>::type
|
||||
result_type;
|
||||
|
||||
result_type operator ()(Expr &expr, Context &context) const
|
||||
{
|
||||
return EVAL(~, 0, expr)();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, proto::tag::function, 2>
|
||||
{
|
||||
typedef
|
||||
typename proto::detail::result_of_fixup<EVAL_TYPE(~, 0, Expr)>::type
|
||||
function_type;
|
||||
|
||||
typedef
|
||||
typename detail::result_of_<function_type(EVAL_TYPE(~, 1, Expr))>::type
|
||||
result_type;
|
||||
|
||||
result_type operator ()(Expr &expr, Context &context) const
|
||||
{
|
||||
return this->invoke(
|
||||
expr
|
||||
, context
|
||||
, is_member_function_pointer<function_type>()
|
||||
, is_member_object_pointer<function_type>()
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type invoke(Expr &expr, Context &context, mpl::false_, mpl::false_) const
|
||||
{
|
||||
return EVAL(~, 0, expr)(EVAL(~, 1, expr));
|
||||
}
|
||||
|
||||
result_type invoke(Expr &expr, Context &context, mpl::true_, mpl::false_) const
|
||||
{
|
||||
using namespace detail::get_pointer_;
|
||||
return (get_pointer(EVAL(~, 1, expr)) ->* EVAL(~, 0, expr))();
|
||||
}
|
||||
|
||||
result_type invoke(Expr &expr, Context &context, mpl::false_, mpl::true_) const
|
||||
{
|
||||
using namespace detail::get_pointer_;
|
||||
return (get_pointer(EVAL(~, 1, expr)) ->* EVAL(~, 0, expr));
|
||||
}
|
||||
};
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (3, BOOST_PROTO_MAX_ARITY, <boost/proto/context/default.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef EVAL_TYPE
|
||||
#undef EVAL
|
||||
|
||||
/// default_context
|
||||
///
|
||||
struct default_context
|
||||
{
|
||||
/// default_context::eval
|
||||
///
|
||||
template<typename Expr, typename ThisContext = default_context const>
|
||||
struct eval
|
||||
: default_eval<Expr, ThisContext>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace context
|
||||
|
||||
}} // namespace boost::proto
|
||||
|
||||
#undef UNREF
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct default_eval<Expr, Context, proto::tag::function, N>
|
||||
{
|
||||
typedef
|
||||
typename proto::detail::result_of_fixup<EVAL_TYPE(~, 0, Expr)>::type
|
||||
function_type;
|
||||
|
||||
typedef
|
||||
typename boost::result_of<
|
||||
function_type(BOOST_PP_ENUM_SHIFTED(N, EVAL_TYPE, Expr))
|
||||
>::type
|
||||
result_type;
|
||||
|
||||
result_type operator ()(Expr &expr, Context &context) const
|
||||
{
|
||||
return this->invoke(expr, context, is_member_function_pointer<function_type>());
|
||||
}
|
||||
|
||||
private:
|
||||
result_type invoke(Expr &expr, Context &context, mpl::false_) const
|
||||
{
|
||||
return EVAL(~, 0, expr)(BOOST_PP_ENUM_SHIFTED(N, EVAL, expr));
|
||||
}
|
||||
|
||||
result_type invoke(Expr &expr, Context &context, mpl::true_) const
|
||||
{
|
||||
#define M0(Z, M, expr) BOOST_PP_COMMA_IF(BOOST_PP_SUB(M, 2)) EVAL(Z, M, expr)
|
||||
using namespace detail::get_pointer_;
|
||||
return (get_pointer(EVAL(~, 1, expr)) ->* EVAL(~, 0, expr))(
|
||||
BOOST_PP_REPEAT_FROM_TO(2, N, M0, expr)
|
||||
);
|
||||
#undef M0
|
||||
}
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
87
libraries/include/boost/proto/context/null.hpp
Normal file
87
libraries/include/boost/proto/context/null.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file null.hpp
|
||||
/// Definintion of null_context\<\>, an evaluation context for
|
||||
/// proto::eval() that simply evaluates each child expression, doesn't
|
||||
/// combine the results at all, and returns void.
|
||||
//
|
||||
// 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_PROTO_CONTEXT_NULL_HPP_EAN_06_24_2007
|
||||
#define BOOST_PROTO_CONTEXT_NULL_HPP_EAN_06_24_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp> // must be first include
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/eval.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp> // must be last include
|
||||
|
||||
namespace boost { namespace proto { namespace context
|
||||
{
|
||||
|
||||
template<
|
||||
typename Expr
|
||||
, typename Context
|
||||
, long Arity BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity_c)
|
||||
>
|
||||
struct null_eval
|
||||
{};
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct null_eval<Expr, Context, 0>
|
||||
{
|
||||
typedef void result_type;
|
||||
void operator()(Expr &, Context &) const
|
||||
{}
|
||||
};
|
||||
|
||||
#define BOOST_PROTO_EVAL_N(Z, N, DATA) \
|
||||
proto::eval(proto::child_c<N>(expr), ctx); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/context/null.hpp>)) \
|
||||
/**/
|
||||
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_PROTO_EVAL_N
|
||||
|
||||
/// null_context
|
||||
///
|
||||
struct null_context
|
||||
{
|
||||
/// null_context::eval
|
||||
///
|
||||
template<typename Expr, typename ThisContext = null_context const>
|
||||
struct eval
|
||||
: null_eval<Expr, ThisContext>
|
||||
{};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct null_eval<Expr, Context, N>
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
void operator ()(Expr &expr, Context &ctx) const
|
||||
{
|
||||
BOOST_PP_REPEAT(N, BOOST_PROTO_EVAL_N, ~)
|
||||
}
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
32
libraries/include/boost/proto/core.hpp
Normal file
32
libraries/include/boost/proto/core.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file core.hpp
|
||||
/// Includes the core of Proto. Not included are the contexts, transforms and
|
||||
/// debugging utilities.
|
||||
//
|
||||
// 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_PROTO_CORE_HPP_EAN_04_01_2005
|
||||
#define BOOST_PROTO_CORE_HPP_EAN_04_01_2005
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/args.hpp>
|
||||
#include <boost/proto/tags.hpp>
|
||||
#include <boost/proto/eval.hpp>
|
||||
#include <boost/proto/expr.hpp>
|
||||
#include <boost/proto/repeat.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/domain.hpp>
|
||||
#include <boost/proto/fusion.hpp>
|
||||
#include <boost/proto/matches.hpp>
|
||||
#include <boost/proto/extends.hpp>
|
||||
#include <boost/proto/literal.hpp>
|
||||
#include <boost/proto/generate.hpp>
|
||||
#include <boost/proto/operators.hpp>
|
||||
#include <boost/proto/deep_copy.hpp>
|
||||
#include <boost/proto/make_expr.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
#endif
|
||||
213
libraries/include/boost/proto/debug.hpp
Normal file
213
libraries/include/boost/proto/debug.hpp
Normal file
@@ -0,0 +1,213 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file debug.hpp
|
||||
/// Utilities for debugging Proto expression trees
|
||||
//
|
||||
// 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_PROTO_DEBUG_HPP_EAN_12_31_2006
|
||||
#define BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/expr.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/detail/dont_care.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace tag
|
||||
{
|
||||
namespace hidden_detail_
|
||||
{
|
||||
typedef char (¬_ostream)[sizeof(std::ostream)+1];
|
||||
not_ostream operator<<(std::ostream &, detail::dont_care);
|
||||
|
||||
template<typename Tag, std::size_t S>
|
||||
struct printable_tag_
|
||||
{
|
||||
typedef char const *type;
|
||||
static type call() { return typeid(Tag).name(); }
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct printable_tag_<Tag, sizeof(std::ostream)>
|
||||
{
|
||||
typedef Tag type;
|
||||
static type call() { return Tag(); }
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct printable_tag
|
||||
: printable_tag_<Tag, sizeof(std::cout << Tag())>
|
||||
{};
|
||||
}
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Tag>
|
||||
inline typename hidden_detail_::printable_tag<Tag>::type proto_tag_name(Tag)
|
||||
{
|
||||
return hidden_detail_::printable_tag<Tag>::call();
|
||||
}
|
||||
|
||||
#define BOOST_PROTO_DEFINE_TAG_NAME(Tag) \
|
||||
/** \brief INTERNAL ONLY */ \
|
||||
inline char const *proto_tag_name(tag::Tag) \
|
||||
{ \
|
||||
return #Tag; \
|
||||
} \
|
||||
/**/
|
||||
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(terminal)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(unary_plus)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(negate)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(dereference)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(complement)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(address_of)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(logical_not)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(pre_inc)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(pre_dec)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(post_inc)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(post_dec)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(shift_left)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(shift_right)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(multiplies)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(divides)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(modulus)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(plus)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(minus)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(less)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(greater)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(less_equal)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(greater_equal)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(equal_to)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(not_equal_to)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(logical_or)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(logical_and)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(bitwise_and)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(bitwise_or)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(bitwise_xor)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(comma)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(mem_ptr)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(shift_left_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(shift_right_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(multiplies_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(divides_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(modulus_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(plus_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(minus_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(bitwise_and_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(bitwise_or_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(bitwise_xor_assign)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(subscript)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(member)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(if_else_)
|
||||
BOOST_PROTO_DEFINE_TAG_NAME(function)
|
||||
|
||||
#undef BOOST_PROTO_DEFINE_TAG_NAME
|
||||
}
|
||||
|
||||
namespace functional
|
||||
{
|
||||
/// \brief Pretty-print a Proto expression tree.
|
||||
///
|
||||
/// A PolymorphicFunctionObject which accepts a Proto expression
|
||||
/// tree and pretty-prints it to an \c ostream for debugging
|
||||
/// purposes.
|
||||
struct display_expr
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
/// \param sout The \c ostream to which the expression tree
|
||||
/// will be written.
|
||||
/// \param depth The starting indentation depth for this node.
|
||||
/// Children nodes will be displayed at a starting
|
||||
/// depth of <tt>depth+4</tt>.
|
||||
explicit display_expr(std::ostream &sout = std::cout, int depth = 0)
|
||||
: depth_(depth)
|
||||
, first_(true)
|
||||
, sout_(sout)
|
||||
{}
|
||||
|
||||
/// \brief Pretty-print the current node in a Proto expression
|
||||
/// tree.
|
||||
template<typename Tag, typename Args>
|
||||
void operator()(proto::expr<Tag, Args, 0> const &expr) const
|
||||
{
|
||||
using namespace tag;
|
||||
this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", ")
|
||||
<< proto_tag_name(Tag()) << "(" << proto::value(expr) << ")\n";
|
||||
this->first_ = false;
|
||||
}
|
||||
|
||||
#define BOOST_PROTO_CHILD(Z, N, DATA) \
|
||||
display(proto::child_c<N>(expr)); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(N) \
|
||||
/** \overload */ \
|
||||
template<typename Tag, typename Args> \
|
||||
void operator()(proto::expr<Tag, Args, N> const &expr) const \
|
||||
{ \
|
||||
using namespace tag; \
|
||||
this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", ") \
|
||||
<< proto_tag_name(Tag()) << "(\n"; \
|
||||
display_expr display(this->sout_, this->depth_ + 4); \
|
||||
BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, _) \
|
||||
this->sout_ << std::setw(this->depth_) << "" << ")\n"; \
|
||||
this->first_ = false; \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_PROTO_MAX_ARITY)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
#undef BOOST_PROTO_CHILD
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename T>
|
||||
void operator()(T const &t) const
|
||||
{
|
||||
(*this)(t.proto_base());
|
||||
}
|
||||
|
||||
private:
|
||||
display_expr &operator =(display_expr const &);
|
||||
int depth_;
|
||||
mutable bool first_;
|
||||
std::ostream &sout_;
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief Pretty-print a Proto expression tree.
|
||||
///
|
||||
/// \note Equivalent to <tt>functional::display_expr(0, sout)(expr)</tt>
|
||||
/// \param expr The Proto expression tree to pretty-print
|
||||
/// \param sout The \c ostream to which the output should be
|
||||
/// written. If not specified, defaults to
|
||||
/// <tt>std::cout</tt>.
|
||||
template<typename Expr>
|
||||
void display_expr(Expr const &expr, std::ostream &sout)
|
||||
{
|
||||
functional::display_expr(sout, 0)(expr);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename Expr>
|
||||
void display_expr(Expr const &expr)
|
||||
{
|
||||
functional::display_expr()(expr);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
191
libraries/include/boost/proto/deep_copy.hpp
Normal file
191
libraries/include/boost/proto/deep_copy.hpp
Normal file
@@ -0,0 +1,191 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file deep_copy.hpp
|
||||
/// Replace all nodes stored by reference by nodes stored by value.
|
||||
//
|
||||
// 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_PROTO_DEEP_COPY_HPP_EAN_11_21_2006
|
||||
#define BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/expr.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Expr, long Arity = Expr::proto_arity_c>
|
||||
struct deep_copy_impl;
|
||||
|
||||
template<typename Expr>
|
||||
struct deep_copy_impl<Expr, 0>
|
||||
{
|
||||
typedef BOOST_PROTO_UNCVREF(typename Expr::proto_child0) raw_terminal_type;
|
||||
// can't store a function type in a terminal.
|
||||
typedef
|
||||
typename mpl::if_c<
|
||||
is_function<raw_terminal_type>::value
|
||||
, typename Expr::proto_child0
|
||||
, raw_terminal_type
|
||||
>::type
|
||||
actual_terminal_type;
|
||||
typedef typename terminal<actual_terminal_type>::type expr_type;
|
||||
typedef typename Expr::proto_domain::template result<void(expr_type)>::type type;
|
||||
|
||||
template<typename Expr2>
|
||||
static type call(Expr2 const &expr)
|
||||
{
|
||||
return typename Expr::proto_domain()(expr_type::make(expr.proto_base().child0));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
/// \brief A metafunction for calculating the return type
|
||||
/// of \c proto::deep_copy().
|
||||
///
|
||||
/// A metafunction for calculating the return type
|
||||
/// of \c proto::deep_copy(). The type parameter \c Expr
|
||||
/// should be the type of a Proto expression tree.
|
||||
/// It should not be a reference type, nor should it
|
||||
/// be cv-qualified.
|
||||
template<typename Expr>
|
||||
struct deep_copy
|
||||
{
|
||||
typedef
|
||||
typename detail::deep_copy_impl<
|
||||
BOOST_PROTO_UNCVREF(Expr)
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace functional
|
||||
{
|
||||
/// \brief A PolymorphicFunctionObject type for deep-copying
|
||||
/// Proto expression trees.
|
||||
///
|
||||
/// A PolymorphicFunctionObject type for deep-copying
|
||||
/// Proto expression trees. When a tree is deep-copied,
|
||||
/// all internal nodes and most terminals held by reference
|
||||
/// are instead held by value.
|
||||
///
|
||||
/// \attention Terminals of reference-to-function type are
|
||||
/// left unchanged. Terminals of reference-to-array type are
|
||||
/// stored by value, which can cause a large amount of data
|
||||
/// to be passed by value and stored on the stack.
|
||||
struct deep_copy
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef
|
||||
typename result_of::deep_copy<Expr>::type
|
||||
type;
|
||||
};
|
||||
|
||||
/// \brief Deep-copies a Proto expression tree, turning all
|
||||
/// nodes and terminals held by reference into ones held by
|
||||
/// value.
|
||||
template<typename Expr>
|
||||
typename result_of::deep_copy<Expr>::type
|
||||
operator()(Expr const &expr) const
|
||||
{
|
||||
return proto::detail::deep_copy_impl<Expr>::call(expr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief A function for deep-copying
|
||||
/// Proto expression trees.
|
||||
///
|
||||
/// A function for deep-copying
|
||||
/// Proto expression trees. When a tree is deep-copied,
|
||||
/// all internal nodes and most terminals held by reference
|
||||
/// are instead held by value.
|
||||
///
|
||||
/// \attention Terminals of reference-to-array type and of
|
||||
/// reference-to-function type are left unchanged.
|
||||
///
|
||||
/// \sa proto::functional::deep_copy.
|
||||
template<typename Expr>
|
||||
typename proto::result_of::deep_copy<Expr>::type
|
||||
deep_copy(Expr const &expr)
|
||||
{
|
||||
return proto::detail::deep_copy_impl<Expr>::call(expr);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#define BOOST_PROTO_DEFINE_DEEP_COPY_TYPE(Z, N, DATA) \
|
||||
typename deep_copy_impl< \
|
||||
typename remove_reference< \
|
||||
typename Expr::BOOST_PP_CAT(proto_child, N) \
|
||||
>::type::proto_derived_expr \
|
||||
>::type \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_DEFINE_DEEP_COPY_FUN(Z, N, DATA) \
|
||||
proto::deep_copy(expr.proto_base().BOOST_PP_CAT(child, N)) \
|
||||
/**/
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/deep_copy.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_PROTO_DEFINE_DEEP_COPY_FUN
|
||||
#undef BOOST_PROTO_DEFINE_DEEP_COPY_TYPE
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_PROTO_COMPILER_DEEP_COPY_HPP_EAN_11_21_2006
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<typename Expr>
|
||||
struct deep_copy_impl<Expr, N>
|
||||
{
|
||||
typedef
|
||||
proto::expr<
|
||||
typename Expr::proto_tag
|
||||
, BOOST_PP_CAT(list, N)<
|
||||
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_TYPE, ~)
|
||||
>
|
||||
>
|
||||
expr_type;
|
||||
|
||||
typedef typename Expr::proto_domain::template result<void(expr_type)>::type type;
|
||||
|
||||
template<typename Expr2>
|
||||
static type call(Expr2 const &expr)
|
||||
{
|
||||
expr_type that = {
|
||||
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_FUN, ~)
|
||||
};
|
||||
|
||||
return typename Expr::proto_domain()(that);
|
||||
}
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
34
libraries/include/boost/proto/detail/as_lvalue.hpp
Normal file
34
libraries/include/boost/proto/detail/as_lvalue.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file as_lvalue.hpp
|
||||
/// Contains definition the as_lvalue() functions.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_AS_LVALUE_HPP_EAN_12_27_2007
|
||||
#define BOOST_PROTO_TRANSFORM_AS_LVALUE_HPP_EAN_12_27_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
T &as_lvalue(T &t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T const &as_lvalue(T const &t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
459
libraries/include/boost/proto/detail/decltype.hpp
Normal file
459
libraries/include/boost/proto/detail/decltype.hpp
Normal file
@@ -0,0 +1,459 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file decltype.hpp
|
||||
/// Contains definition the BOOST_PROTO_DECLTYPE_() macro and assorted helpers
|
||||
//
|
||||
// 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_PROTO_DETAIL_DECLTYPE_HPP_EAN_04_04_2008
|
||||
#define BOOST_PROTO_DETAIL_DECLTYPE_HPP_EAN_04_04_2008
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp> // must be first include
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/get_pointer.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/is_member_object_pointer.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp> // must be last include
|
||||
|
||||
// If we're generating doxygen documentation, hide all the nasty
|
||||
// Boost.Typeof gunk.
|
||||
#ifndef BOOST_PROTO_BUILDING_DOCS
|
||||
# ifdef BOOST_HAS_DECLTYPE
|
||||
# define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) typedef decltype(EXPR) TYPE;
|
||||
# else
|
||||
# define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(NESTED, EXPR) \
|
||||
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, NESTED), EXPR) \
|
||||
static int const sz = sizeof(boost::proto::detail::check_reference(EXPR)); \
|
||||
struct NESTED \
|
||||
: boost::mpl::if_c< \
|
||||
1==sz \
|
||||
, typename BOOST_PP_CAT(nested_and_hidden_, NESTED)::type & \
|
||||
, typename BOOST_PP_CAT(nested_and_hidden_, NESTED)::type \
|
||||
> \
|
||||
{};
|
||||
# define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) \
|
||||
BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(BOOST_PP_CAT(nested_, TYPE), (EXPR)) \
|
||||
typedef typename BOOST_PP_CAT(nested_, TYPE)::type TYPE;
|
||||
# endif
|
||||
#else
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
# define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) \
|
||||
typedef detail::unspecified TYPE;
|
||||
#endif
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace anyns
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct any
|
||||
{
|
||||
any(...);
|
||||
any operator=(any);
|
||||
any operator[](any);
|
||||
#define M0(Z, N, DATA) any operator()(BOOST_PP_ENUM_PARAMS_Z(Z, N, any BOOST_PP_INTERCEPT));
|
||||
BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, M0, ~)
|
||||
#undef M0
|
||||
|
||||
template<typename T>
|
||||
operator T &() const volatile;
|
||||
|
||||
any operator+();
|
||||
any operator-();
|
||||
any operator*();
|
||||
any operator&();
|
||||
any operator~();
|
||||
any operator!();
|
||||
any operator++();
|
||||
any operator--();
|
||||
any operator++(int);
|
||||
any operator--(int);
|
||||
|
||||
friend any operator<<(any, any);
|
||||
friend any operator>>(any, any);
|
||||
friend any operator*(any, any);
|
||||
friend any operator/(any, any);
|
||||
friend any operator%(any, any);
|
||||
friend any operator+(any, any);
|
||||
friend any operator-(any, any);
|
||||
friend any operator<(any, any);
|
||||
friend any operator>(any, any);
|
||||
friend any operator<=(any, any);
|
||||
friend any operator>=(any, any);
|
||||
friend any operator==(any, any);
|
||||
friend any operator!=(any, any);
|
||||
friend any operator||(any, any);
|
||||
friend any operator&&(any, any);
|
||||
friend any operator&(any, any);
|
||||
friend any operator|(any, any);
|
||||
friend any operator^(any, any);
|
||||
friend any operator,(any, any);
|
||||
friend any operator->*(any, any);
|
||||
|
||||
friend any operator<<=(any, any);
|
||||
friend any operator>>=(any, any);
|
||||
friend any operator*=(any, any);
|
||||
friend any operator/=(any, any);
|
||||
friend any operator%=(any, any);
|
||||
friend any operator+=(any, any);
|
||||
friend any operator-=(any, any);
|
||||
friend any operator&=(any, any);
|
||||
friend any operator|=(any, any);
|
||||
friend any operator^=(any, any);
|
||||
};
|
||||
}
|
||||
|
||||
using anyns::any;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
struct as_mutable
|
||||
{
|
||||
typedef T &type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct as_mutable<T &>
|
||||
{
|
||||
typedef T &type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct as_mutable<T const &>
|
||||
{
|
||||
typedef T &type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
T make();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
typename as_mutable<T>::type make_mutable();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
struct subscript_wrapper
|
||||
: T
|
||||
{
|
||||
using T::operator[];
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
|
||||
any operator[](any const volatile &) const volatile;
|
||||
#else
|
||||
any operator[](any const &) const volatile;
|
||||
#endif
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
struct as_subscriptable
|
||||
{
|
||||
typedef
|
||||
typename mpl::if_c<
|
||||
is_class<T>::value
|
||||
, subscript_wrapper<T>
|
||||
, T
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct as_subscriptable<T const>
|
||||
{
|
||||
typedef
|
||||
typename mpl::if_c<
|
||||
is_class<T>::value
|
||||
, subscript_wrapper<T> const
|
||||
, T const
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct as_subscriptable<T &>
|
||||
{
|
||||
typedef
|
||||
typename mpl::if_c<
|
||||
is_class<T>::value
|
||||
, subscript_wrapper<T> &
|
||||
, T &
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct as_subscriptable<T const &>
|
||||
{
|
||||
typedef
|
||||
typename mpl::if_c<
|
||||
is_class<T>::value
|
||||
, subscript_wrapper<T> const &
|
||||
, T const &
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
typename as_subscriptable<T>::type make_subscriptable();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
char check_reference(T &);
|
||||
|
||||
template<typename T>
|
||||
char (&check_reference(T const &))[2];
|
||||
|
||||
namespace has_get_pointer_
|
||||
{
|
||||
using boost::get_pointer;
|
||||
void *(&get_pointer(...))[2];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
struct has_get_pointer
|
||||
{
|
||||
static T &t;
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(void *) == sizeof(get_pointer(t)));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
}
|
||||
|
||||
using has_get_pointer_::has_get_pointer;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
namespace get_pointer_
|
||||
{
|
||||
using boost::get_pointer;
|
||||
|
||||
template<typename T>
|
||||
typename disable_if<has_get_pointer<T>, T *>::type
|
||||
get_pointer(T &t)
|
||||
{
|
||||
return boost::addressof(t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename disable_if<has_get_pointer<T>, T const *>::type
|
||||
get_pointer(T const &t)
|
||||
{
|
||||
return boost::addressof(t);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<
|
||||
typename T
|
||||
, typename U
|
||||
, bool IsMemPtr = is_member_object_pointer<
|
||||
typename remove_reference<U>::type
|
||||
>::value
|
||||
>
|
||||
struct mem_ptr_fun
|
||||
{
|
||||
BOOST_PROTO_DECLTYPE_(
|
||||
proto::detail::make_mutable<T>() ->* proto::detail::make<U>()
|
||||
, result_type
|
||||
)
|
||||
|
||||
result_type operator()(
|
||||
typename add_reference<typename add_const<T>::type>::type t
|
||||
, typename add_reference<typename add_const<U>::type>::type u
|
||||
) const
|
||||
{
|
||||
return t ->* u;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T, typename U>
|
||||
struct mem_ptr_fun<T, U, true>
|
||||
{
|
||||
BOOST_PROTO_DECLTYPE_(
|
||||
get_pointer(proto::detail::make_mutable<T>()) ->* proto::detail::make<U>()
|
||||
, result_type
|
||||
)
|
||||
|
||||
result_type operator()(
|
||||
typename add_reference<typename add_const<T>::type>::type t
|
||||
, typename add_reference<typename add_const<U>::type>::type u
|
||||
) const
|
||||
{
|
||||
return get_pointer(t) ->* u;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
using get_pointer_::mem_ptr_fun;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename A0, typename A1>
|
||||
struct comma_result
|
||||
{
|
||||
BOOST_PROTO_DECLTYPE_((proto::detail::make<A0>(), proto::detail::make<A1>()), type)
|
||||
};
|
||||
|
||||
template<typename A0>
|
||||
struct comma_result<A0, void>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<typename A1>
|
||||
struct comma_result<void, A1>
|
||||
{
|
||||
typedef A1 type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct comma_result<void, void>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
struct result_of_member;
|
||||
|
||||
template<typename T, typename U>
|
||||
struct result_of_member<T U::*>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T, typename Void = void>
|
||||
struct result_of_
|
||||
: boost::result_of<T>
|
||||
{};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct result_of_<T(U), typename enable_if<is_member_object_pointer<T> >::type>
|
||||
{
|
||||
typedef
|
||||
typename result_of_member<T>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct result_of_<T(U &), typename enable_if<is_member_object_pointer<T> >::type>
|
||||
{
|
||||
typedef
|
||||
typename add_reference<
|
||||
typename result_of_member<T>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct result_of_<T(U const &), typename enable_if<is_member_object_pointer<T> >::type>
|
||||
{
|
||||
typedef
|
||||
typename add_reference<
|
||||
typename add_const<
|
||||
typename result_of_member<T>::type
|
||||
>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T, typename U = T>
|
||||
struct result_of_fixup
|
||||
: mpl::if_c<is_function<T>::value, T *, U>
|
||||
{};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct result_of_fixup<T &, U>
|
||||
: result_of_fixup<T, T>
|
||||
{};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct result_of_fixup<T const &, U>
|
||||
: result_of_fixup<T, T>
|
||||
{};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct result_of_fixup<T *, U>
|
||||
: result_of_fixup<T, U>
|
||||
{};
|
||||
|
||||
template<typename R, typename T, typename U>
|
||||
struct result_of_fixup<R T::*, U>
|
||||
{
|
||||
typedef R T::*type;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct result_of_fixup<T const, U>
|
||||
: result_of_fixup<T, U>
|
||||
{};
|
||||
|
||||
//// Tests for result_of_fixup
|
||||
//struct bar {};
|
||||
//BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar>::type>));
|
||||
//BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const>::type>));
|
||||
//BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar &>::type>));
|
||||
//BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const &>::type>));
|
||||
//BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(*)()>::type>));
|
||||
//BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const)()>::type>));
|
||||
//BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const &)()>::type>));
|
||||
//BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(&)()>::type>));
|
||||
|
||||
template<typename T, typename PMF>
|
||||
struct memfun
|
||||
{
|
||||
typedef typename remove_const<typename remove_reference<PMF>::type>::type pmf_type;
|
||||
typedef typename boost::result_of<pmf_type(T)>::type result_type;
|
||||
|
||||
memfun(T t, PMF p)
|
||||
: obj(t)
|
||||
, pmf(p)
|
||||
{}
|
||||
|
||||
result_type operator()() const
|
||||
{
|
||||
using namespace get_pointer_;
|
||||
return (get_pointer(obj) ->* pmf)();
|
||||
}
|
||||
|
||||
#define M0(Z, N, DATA) \
|
||||
template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
|
||||
result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) const \
|
||||
{ \
|
||||
using namespace get_pointer_; \
|
||||
return (get_pointer(obj) ->* pmf)(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \
|
||||
} \
|
||||
/**/
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0, ~)
|
||||
#undef M0
|
||||
|
||||
private:
|
||||
T obj;
|
||||
PMF pmf;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
}}
|
||||
|
||||
#endif
|
||||
249
libraries/include/boost/proto/detail/deprecated.hpp
Normal file
249
libraries/include/boost/proto/detail/deprecated.hpp
Normal file
@@ -0,0 +1,249 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file deprecated.hpp
|
||||
/// Definition of the deprecated BOOST_PROTO_DEFINE_FUCTION_TEMPLATE and
|
||||
/// BOOST_PROTO_DEFINE_VARARG_FUCTION_TEMPLATE macros
|
||||
//
|
||||
// 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_PROTO_DETAIL_DEPRECATED_HPP_EAN_11_25_2008
|
||||
#define BOOST_PROTO_DETAIL_DEPRECATED_HPP_EAN_11_25_2008
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
#include <boost/preprocessor/arithmetic/sub.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/control/expr_if.hpp>
|
||||
#include <boost/preprocessor/comparison/greater.hpp>
|
||||
#include <boost/preprocessor/tuple/elem.hpp>
|
||||
#include <boost/preprocessor/tuple/to_list.hpp>
|
||||
#include <boost/preprocessor/logical/and.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/seq/seq.hpp>
|
||||
#include <boost/preprocessor/seq/to_tuple.hpp>
|
||||
#include <boost/preprocessor/seq/for_each_i.hpp>
|
||||
#include <boost/preprocessor/seq/pop_back.hpp>
|
||||
#include <boost/preprocessor/seq/push_back.hpp>
|
||||
#include <boost/preprocessor/seq/push_front.hpp>
|
||||
#include <boost/preprocessor/list/for_each_i.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_TEMPLATE_AUX_(R, DATA, I, ELEM) \
|
||||
(ELEM BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I))) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_TEMPLATE_YES_(R, DATA, I, ELEM) \
|
||||
BOOST_PP_LIST_FOR_EACH_I_R( \
|
||||
R \
|
||||
, BOOST_PROTO_VARARG_TEMPLATE_AUX_ \
|
||||
, I \
|
||||
, BOOST_PP_TUPLE_TO_LIST( \
|
||||
BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
|
||||
, BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM)) \
|
||||
) \
|
||||
) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_TEMPLATE_NO_(R, DATA, I, ELEM) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_TEMPLATE_(R, DATA, I, ELEM) \
|
||||
BOOST_PP_IF( \
|
||||
BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
|
||||
, BOOST_PROTO_VARARG_TEMPLATE_YES_ \
|
||||
, BOOST_PROTO_VARARG_TEMPLATE_NO_ \
|
||||
)(R, DATA, I, ELEM) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_TYPE_AUX_(R, DATA, I, ELEM) \
|
||||
(BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I))) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_TEMPLATE_PARAMS_YES_(R, DATA, I, ELEM) \
|
||||
< \
|
||||
BOOST_PP_SEQ_ENUM( \
|
||||
BOOST_PP_LIST_FOR_EACH_I_R( \
|
||||
R \
|
||||
, BOOST_PROTO_VARARG_TYPE_AUX_ \
|
||||
, I \
|
||||
, BOOST_PP_TUPLE_TO_LIST( \
|
||||
BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
|
||||
, BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM)) \
|
||||
) \
|
||||
) \
|
||||
) \
|
||||
> \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_TEMPLATE_PARAMS_NO_(R, DATA, I, ELEM) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_TYPE_(R, DATA, I, ELEM) \
|
||||
BOOST_PP_COMMA_IF(I) \
|
||||
BOOST_PP_SEQ_HEAD(ELEM) \
|
||||
BOOST_PP_IF( \
|
||||
BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
|
||||
, BOOST_PROTO_TEMPLATE_PARAMS_YES_ \
|
||||
, BOOST_PROTO_TEMPLATE_PARAMS_NO_ \
|
||||
)(R, DATA, I, ELEM) BOOST_PP_EXPR_IF(BOOST_PP_GREATER(I, 1), const) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_AS_EXPR_(R, DATA, I, ELEM) \
|
||||
BOOST_PP_EXPR_IF( \
|
||||
BOOST_PP_GREATER(I, 1) \
|
||||
, (( \
|
||||
BOOST_PP_SEQ_HEAD(ELEM) \
|
||||
BOOST_PP_IF( \
|
||||
BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
|
||||
, BOOST_PROTO_TEMPLATE_PARAMS_YES_ \
|
||||
, BOOST_PROTO_TEMPLATE_PARAMS_NO_ \
|
||||
)(R, DATA, I, ELEM)() \
|
||||
)) \
|
||||
) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_AS_CHILD_(Z, N, DATA) \
|
||||
(BOOST_PP_CAT(DATA, N)) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_SEQ_PUSH_FRONT(SEQ, ELEM) \
|
||||
BOOST_PP_SEQ_POP_BACK(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_BACK(SEQ, _dummy_), ELEM)) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_AS_PARAM_(Z, N, DATA) \
|
||||
(BOOST_PP_CAT(DATA, N)) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VARARG_FUN_(Z, N, DATA) \
|
||||
template< \
|
||||
BOOST_PP_SEQ_ENUM( \
|
||||
BOOST_PP_SEQ_FOR_EACH_I( \
|
||||
BOOST_PROTO_VARARG_TEMPLATE_, ~ \
|
||||
, BOOST_PP_SEQ_PUSH_FRONT( \
|
||||
BOOST_PROTO_SEQ_PUSH_FRONT( \
|
||||
BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
|
||||
, (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
|
||||
) \
|
||||
, BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
|
||||
) \
|
||||
) \
|
||||
BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_PARAM_, typename A) \
|
||||
) \
|
||||
> \
|
||||
typename boost::proto::result_of::make_expr< \
|
||||
BOOST_PP_SEQ_FOR_EACH_I( \
|
||||
BOOST_PROTO_VARARG_TYPE_, ~ \
|
||||
, BOOST_PP_SEQ_PUSH_FRONT( \
|
||||
BOOST_PROTO_SEQ_PUSH_FRONT( \
|
||||
BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
|
||||
, (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
|
||||
) \
|
||||
, BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
|
||||
) \
|
||||
) \
|
||||
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \
|
||||
>::type const \
|
||||
BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) \
|
||||
{ \
|
||||
return boost::proto::detail::make_expr_< \
|
||||
BOOST_PP_SEQ_FOR_EACH_I( \
|
||||
BOOST_PROTO_VARARG_TYPE_, ~ \
|
||||
, BOOST_PP_SEQ_PUSH_FRONT( \
|
||||
BOOST_PROTO_SEQ_PUSH_FRONT( \
|
||||
BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
|
||||
, (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
|
||||
) \
|
||||
, BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
|
||||
) \
|
||||
) \
|
||||
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \
|
||||
>()( \
|
||||
BOOST_PP_SEQ_ENUM( \
|
||||
BOOST_PP_SEQ_FOR_EACH_I( \
|
||||
BOOST_PROTO_VARARG_AS_EXPR_, ~ \
|
||||
, BOOST_PP_SEQ_PUSH_FRONT( \
|
||||
BOOST_PROTO_SEQ_PUSH_FRONT( \
|
||||
BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
|
||||
, (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
|
||||
) \
|
||||
, BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
|
||||
) \
|
||||
) \
|
||||
BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_CHILD_, a) \
|
||||
) \
|
||||
); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
/// \code
|
||||
/// BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
|
||||
/// 1
|
||||
/// , construct
|
||||
/// , boost::proto::default_domain
|
||||
/// , (boost::proto::tag::function)
|
||||
/// , ((op::construct)(typename)(int))
|
||||
/// )
|
||||
/// \endcode
|
||||
#define BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(ARGCOUNT, NAME, DOMAIN, TAG, BOUNDARGS) \
|
||||
BOOST_PP_REPEAT_FROM_TO( \
|
||||
ARGCOUNT \
|
||||
, BOOST_PP_INC(ARGCOUNT) \
|
||||
, BOOST_PROTO_VARARG_FUN_ \
|
||||
, (NAME, TAG, BOUNDARGS, DOMAIN) \
|
||||
)\
|
||||
/**/
|
||||
|
||||
/// \code
|
||||
/// BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(
|
||||
/// construct
|
||||
/// , boost::proto::default_domain
|
||||
/// , (boost::proto::tag::function)
|
||||
/// , ((op::construct)(typename)(int))
|
||||
/// )
|
||||
/// \endcode
|
||||
#define BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(NAME, DOMAIN, TAG, BOUNDARGS) \
|
||||
BOOST_PP_REPEAT( \
|
||||
BOOST_PP_SUB(BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), BOOST_PP_SEQ_SIZE(BOUNDARGS)) \
|
||||
, BOOST_PROTO_VARARG_FUN_ \
|
||||
, (NAME, TAG, BOUNDARGS, DOMAIN) \
|
||||
) \
|
||||
/**/
|
||||
|
||||
#endif
|
||||
23
libraries/include/boost/proto/detail/dont_care.hpp
Normal file
23
libraries/include/boost/proto/detail/dont_care.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file dont_care.hpp
|
||||
/// Definintion of dont_care, a dummy parameter
|
||||
//
|
||||
// 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_PROTO_DETAIL_DONT_CARE_HPP_EAN_11_07_2007
|
||||
#define BOOST_PROTO_DETAIL_DONT_CARE_HPP_EAN_11_07_2007
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct dont_care
|
||||
{
|
||||
dont_care(...);
|
||||
};
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
78
libraries/include/boost/proto/detail/funop.hpp
Normal file
78
libraries/include/boost/proto/detail/funop.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// funop.hpp
|
||||
// Contains definition of funop[n]\<\> class template.
|
||||
//
|
||||
// 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_PP_IS_ITERATING
|
||||
#error Do not include this file directly
|
||||
#endif
|
||||
|
||||
#define M0(Z, N, DATA) \
|
||||
typename proto::result_of::as_child<BOOST_PP_CAT(A, N), Domain>::type \
|
||||
/**/
|
||||
|
||||
#define M1(Z, N, DATA) \
|
||||
proto::as_child<Domain>(BOOST_PP_CAT(a, N)) \
|
||||
/**/
|
||||
|
||||
/// \brief A helper metafunction for computing the
|
||||
/// return type of \c proto::expr\<\>::operator().
|
||||
template<typename Expr, typename Domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A)>
|
||||
struct BOOST_PP_CAT(funop, BOOST_PP_ITERATION())
|
||||
{
|
||||
typedef proto::expr<
|
||||
tag::function
|
||||
, BOOST_PP_CAT(list, BOOST_PP_INC(BOOST_PP_ITERATION()))<
|
||||
Expr &
|
||||
BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), M0, ~)
|
||||
>
|
||||
> type;
|
||||
|
||||
static type const call(
|
||||
Expr &expr
|
||||
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), A, &a)
|
||||
)
|
||||
{
|
||||
type that = {
|
||||
expr
|
||||
BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), M1, ~)
|
||||
};
|
||||
return that;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A helper metafunction for computing the
|
||||
/// return type of \c proto::expr\<\>::operator().
|
||||
template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A), typename This, typename Domain>
|
||||
struct funop<Expr(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), This, Domain>
|
||||
: BOOST_PP_CAT(funop, BOOST_PP_ITERATION())<
|
||||
This
|
||||
, Domain
|
||||
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
|
||||
BOOST_PP_ITERATION()
|
||||
, typename remove_reference<A
|
||||
, >::type BOOST_PP_INTERCEPT
|
||||
)
|
||||
>
|
||||
{};
|
||||
|
||||
/// \brief A helper metafunction for computing the
|
||||
/// return type of \c proto::expr\<\>::operator().
|
||||
template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A), typename This, typename Domain>
|
||||
struct funop<Expr const(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), This, Domain>
|
||||
: BOOST_PP_CAT(funop, BOOST_PP_ITERATION())<
|
||||
This const
|
||||
, Domain
|
||||
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
|
||||
BOOST_PP_ITERATION()
|
||||
, typename remove_reference<A
|
||||
, >::type BOOST_PP_INTERCEPT
|
||||
)
|
||||
>
|
||||
{};
|
||||
|
||||
#undef M0
|
||||
#undef M1
|
||||
23
libraries/include/boost/proto/detail/ignore_unused.hpp
Normal file
23
libraries/include/boost/proto/detail/ignore_unused.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file ignore_unused.hpp
|
||||
/// Definintion of ignore_unused, a dummy function for suppressing compiler
|
||||
/// warnings
|
||||
//
|
||||
// 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_PROTO_DETAIL_IGNORE_UNUSED_HPP_EAN_03_03_2008
|
||||
#define BOOST_PROTO_DETAIL_IGNORE_UNUSED_HPP_EAN_03_03_2008
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
inline void ignore_unused(T const &)
|
||||
{}
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
52
libraries/include/boost/proto/detail/local.hpp
Normal file
52
libraries/include/boost/proto/detail/local.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file local.hpp
|
||||
/// Contains macros to ease the generation of repetitious code constructs
|
||||
//
|
||||
// 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_PROTO_LOCAL_MACRO
|
||||
# error "local iteration target macro is not defined"
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_LOCAL_LIMITS
|
||||
# define BOOST_PROTO_LOCAL_LIMITS (1, BOOST_PROTO_MAX_ARITY)
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_LOCAL_typename_A
|
||||
# define BOOST_PROTO_LOCAL_typename_A BOOST_PROTO_typename_A
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_LOCAL_A
|
||||
# define BOOST_PROTO_LOCAL_A BOOST_PROTO_A_const_ref
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_LOCAL_A_a
|
||||
# define BOOST_PROTO_LOCAL_A_a BOOST_PROTO_A_const_ref_a
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_LOCAL_a
|
||||
# define BOOST_PROTO_LOCAL_a BOOST_PROTO_ref_a
|
||||
#endif
|
||||
|
||||
#define BOOST_PP_LOCAL_LIMITS BOOST_PROTO_LOCAL_LIMITS
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(N) \
|
||||
BOOST_PROTO_LOCAL_MACRO( \
|
||||
N \
|
||||
, BOOST_PROTO_LOCAL_typename_A \
|
||||
, BOOST_PROTO_LOCAL_A \
|
||||
, BOOST_PROTO_LOCAL_A_a \
|
||||
, BOOST_PROTO_LOCAL_a \
|
||||
) \
|
||||
/**/
|
||||
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#undef BOOST_PROTO_LOCAL_MACRO
|
||||
#undef BOOST_PROTO_LOCAL_LIMITS
|
||||
#undef BOOST_PROTO_LOCAL_typename_A
|
||||
#undef BOOST_PROTO_LOCAL_A
|
||||
#undef BOOST_PROTO_LOCAL_A_a
|
||||
#undef BOOST_PROTO_LOCAL_a
|
||||
261
libraries/include/boost/proto/detail/poly_function.hpp
Normal file
261
libraries/include/boost/proto/detail/poly_function.hpp
Normal file
@@ -0,0 +1,261 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file poly_function.hpp
|
||||
/// A wrapper that makes a tr1-style function object that handles const
|
||||
/// and non-const refs and reference_wrapper arguments, too, and forwards
|
||||
/// the arguments on to the specified implementation.
|
||||
//
|
||||
// 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_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02
|
||||
#define BOOST_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/void.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4181) // const applied to reference type
|
||||
#endif
|
||||
|
||||
namespace boost { namespace proto { namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
struct normalize_arg
|
||||
{
|
||||
typedef T type;
|
||||
typedef T const &reference;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_arg<T &>
|
||||
{
|
||||
typedef T type;
|
||||
typedef T const &reference;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_arg<T const &>
|
||||
{
|
||||
typedef T type;
|
||||
typedef T const &reference;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_arg<boost::reference_wrapper<T> >
|
||||
{
|
||||
typedef T &type;
|
||||
typedef T &reference;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_arg<boost::reference_wrapper<T> &>
|
||||
{
|
||||
typedef T &type;
|
||||
typedef T &reference;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_arg<boost::reference_wrapper<T> const &>
|
||||
{
|
||||
typedef T &type;
|
||||
typedef T &reference;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
struct arg
|
||||
{
|
||||
typedef T const &type;
|
||||
|
||||
arg(type t)
|
||||
: value(t)
|
||||
{}
|
||||
|
||||
operator type() const
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
type operator()() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
arg &operator =(arg const &);
|
||||
type value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct arg<T &>
|
||||
{
|
||||
typedef T &type;
|
||||
|
||||
arg(type t)
|
||||
: value(t)
|
||||
{}
|
||||
|
||||
operator type() const
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
type operator()() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
arg &operator =(arg const &);
|
||||
type value;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T, typename Void = void>
|
||||
struct is_poly_function
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename T>
|
||||
struct is_poly_function<T, typename T::is_poly_function_base_>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PROTO_POLY_FUNCTION() \
|
||||
typedef void is_poly_function_base_; \
|
||||
/**/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct poly_function_base
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
BOOST_PROTO_POLY_FUNCTION()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Derived, typename NullaryResult = void>
|
||||
struct poly_function
|
||||
: poly_function_base
|
||||
{
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This>
|
||||
struct result<This()>
|
||||
: Derived::template impl<>
|
||||
{
|
||||
typedef typename result::result_type type;
|
||||
};
|
||||
|
||||
NullaryResult operator()() const
|
||||
{
|
||||
result<Derived const()> impl;
|
||||
return impl();
|
||||
}
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/poly_function.hpp>, 0))
|
||||
#include BOOST_PP_ITERATE()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFunSig, bool IsPoly>
|
||||
struct as_mono_function_impl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFunSig>
|
||||
struct as_mono_function;
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/poly_function.hpp>, 1))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
}}} // namespace boost::proto::detail
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#elif 0 == BOOST_PP_ITERATION_FLAGS()
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
|
||||
struct result<This(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
: Derived::template impl<
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(
|
||||
N
|
||||
, typename normalize_arg<A
|
||||
, >::type BOOST_PP_INTERCEPT
|
||||
)
|
||||
>
|
||||
{
|
||||
typedef typename result::result_type type;
|
||||
};
|
||||
|
||||
template<BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
typename result<
|
||||
Derived const(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, A, const & BOOST_PP_INTERCEPT)
|
||||
)
|
||||
>::type
|
||||
operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const &a)) const
|
||||
{
|
||||
result<
|
||||
Derived const(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, A, const & BOOST_PP_INTERCEPT)
|
||||
)
|
||||
> impl;
|
||||
|
||||
#define M0(Z, N, DATA) \
|
||||
static_cast<typename normalize_arg<BOOST_PP_CAT(A, N) const &> \
|
||||
::reference>(BOOST_PP_CAT(a, N))
|
||||
return impl(BOOST_PP_ENUM(N, M0, ~));
|
||||
#undef M0
|
||||
}
|
||||
|
||||
#undef N
|
||||
|
||||
#elif 1 == BOOST_PP_ITERATION_FLAGS()
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
struct as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), true>
|
||||
{
|
||||
typedef typename PolyFun::template impl<BOOST_PP_ENUM_PARAMS(N, const A)> type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
struct as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), false>
|
||||
{
|
||||
typedef PolyFun type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
struct as_mono_function<PolyFun(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
: as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), is_poly_function<PolyFun>::value>
|
||||
{};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
43
libraries/include/boost/proto/detail/pop_front.hpp
Normal file
43
libraries/include/boost/proto/detail/pop_front.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2006 Joel de Guzman
|
||||
Copyright (c) 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_PROTO_DETAIL_FUSION_POP_FRONT_EAH_01_22_2008
|
||||
#define BOOST_PROTO_DETAIL_FUSION_POP_FRONT_EAH_01_22_2008
|
||||
|
||||
#include <boost/spirit/fusion/sequence/range.hpp>
|
||||
#include <boost/spirit/fusion/sequence/begin.hpp>
|
||||
#include <boost/spirit/fusion/sequence/end.hpp>
|
||||
#include <boost/spirit/fusion/iterator/next.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
namespace meta
|
||||
{
|
||||
template <typename Sequence>
|
||||
struct pop_front
|
||||
{
|
||||
typedef
|
||||
range<
|
||||
typename next<
|
||||
typename begin<Sequence>::type
|
||||
>::type
|
||||
, typename end<Sequence>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Sequence>
|
||||
inline typename meta::pop_front<Sequence const>::type
|
||||
pop_front(Sequence const& seq)
|
||||
{
|
||||
typedef typename meta::pop_front<Sequence const>::type result;
|
||||
return result(fusion::next(fusion::begin(seq)), fusion::end(seq));
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
10
libraries/include/boost/proto/detail/prefix.hpp
Normal file
10
libraries/include/boost/proto/detail/prefix.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#if defined(__WAVE__) && defined(BOOST_PROTO_BUILDING_DOCS)
|
||||
#pragma wave option(output:push)
|
||||
#pragma wave option(output:null)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
189
libraries/include/boost/proto/detail/reverse.hpp
Normal file
189
libraries/include/boost/proto/detail/reverse.hpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2006 Joel de Guzman
|
||||
Copyright (c) 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_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008
|
||||
#define BOOST_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008
|
||||
|
||||
#include <boost/spirit/fusion/detail/access.hpp>
|
||||
#include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp>
|
||||
#include <boost/spirit/fusion/iterator/detail/iterator_base.hpp>
|
||||
#include <boost/spirit/fusion/sequence/detail/sequence_base.hpp>
|
||||
#include <boost/spirit/fusion/iterator/next.hpp>
|
||||
#include <boost/spirit/fusion/iterator/prior.hpp>
|
||||
#include <boost/spirit/fusion/iterator/deref.hpp>
|
||||
#include <boost/spirit/fusion/iterator/value_of.hpp>
|
||||
#include <boost/spirit/fusion/sequence/begin.hpp>
|
||||
#include <boost/spirit/fusion/sequence/end.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
struct reverse_view_tag;
|
||||
struct reverse_view_iterator_tag;
|
||||
|
||||
template <typename First>
|
||||
struct reverse_view_iterator
|
||||
: iterator_base<reverse_view_iterator<First> >
|
||||
{
|
||||
typedef as_fusion_iterator<First> converter;
|
||||
typedef typename converter::type first_type;
|
||||
typedef reverse_view_iterator_tag tag;
|
||||
|
||||
reverse_view_iterator(First const& first)
|
||||
: first(converter::convert(first)) {}
|
||||
|
||||
first_type first;
|
||||
};
|
||||
|
||||
template <typename Sequence>
|
||||
struct reverse_view : sequence_base<reverse_view<Sequence> >
|
||||
{
|
||||
typedef as_fusion_sequence<Sequence> seq_converter;
|
||||
typedef typename seq_converter::type seq;
|
||||
|
||||
typedef reverse_view_tag tag;
|
||||
typedef typename meta::begin<seq>::type first_type;
|
||||
typedef typename meta::end<seq>::type last_type;
|
||||
|
||||
reverse_view(Sequence& seq)
|
||||
: first(fusion::begin(seq))
|
||||
, last(fusion::end(seq))
|
||||
{}
|
||||
|
||||
first_type first;
|
||||
last_type last;
|
||||
};
|
||||
|
||||
namespace meta
|
||||
{
|
||||
template <>
|
||||
struct deref_impl<reverse_view_iterator_tag>
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct apply
|
||||
{
|
||||
typedef typename
|
||||
meta::deref<
|
||||
typename meta::prior<
|
||||
typename Iterator::first_type
|
||||
>::type
|
||||
>::type
|
||||
type;
|
||||
|
||||
static type
|
||||
call(Iterator const& i)
|
||||
{
|
||||
return *fusion::prior(i.first);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct prior_impl<reverse_view_iterator_tag>
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct apply
|
||||
{
|
||||
typedef typename Iterator::first_type first_type;
|
||||
typedef typename next_impl<typename first_type::tag>::
|
||||
template apply<first_type>
|
||||
wrapped;
|
||||
|
||||
typedef reverse_view_iterator<typename wrapped::type> type;
|
||||
|
||||
static type
|
||||
call(Iterator const& i)
|
||||
{
|
||||
return type(wrapped::call(i.first));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct next_impl<reverse_view_iterator_tag>
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct apply
|
||||
{
|
||||
typedef typename Iterator::first_type first_type;
|
||||
typedef typename prior_impl<typename first_type::tag>::
|
||||
template apply<first_type>
|
||||
wrapped;
|
||||
|
||||
typedef reverse_view_iterator<typename wrapped::type> type;
|
||||
|
||||
static type
|
||||
call(Iterator const& i)
|
||||
{
|
||||
return type(wrapped::call(i.first));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct value_impl<reverse_view_iterator_tag>
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct apply
|
||||
{
|
||||
typedef typename
|
||||
meta::value_of<
|
||||
typename meta::prior<
|
||||
typename Iterator::first_type
|
||||
>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct begin_impl<reverse_view_tag>
|
||||
{
|
||||
template <typename Sequence>
|
||||
struct apply
|
||||
{
|
||||
typedef reverse_view_iterator<typename Sequence::last_type> type;
|
||||
|
||||
static type
|
||||
call(Sequence const& s)
|
||||
{
|
||||
return type(s.last);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct end_impl<reverse_view_tag>
|
||||
{
|
||||
template <typename Sequence>
|
||||
struct apply
|
||||
{
|
||||
typedef reverse_view_iterator<typename Sequence::first_type> type;
|
||||
|
||||
static type
|
||||
call(Sequence const& s)
|
||||
{
|
||||
return type(s.first);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Sequence>
|
||||
struct reverse
|
||||
{
|
||||
typedef reverse_view<Sequence> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Sequence>
|
||||
inline reverse_view<Sequence const>
|
||||
reverse(Sequence const& view)
|
||||
{
|
||||
return reverse_view<Sequence const>(view);
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
16
libraries/include/boost/proto/detail/suffix.hpp
Normal file
16
libraries/include/boost/proto/detail/suffix.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__WAVE__) && defined(BOOST_PROTO_BUILDING_DOCS)
|
||||
#pragma wave option(output:pop)
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_SUFFIX_DUMMY_STRUCT_DEFINED
|
||||
#define BOOST_PROTO_SUFFIX_DUMMY_STRUCT_DEFINED
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
struct a_dummy_struct;
|
||||
#endif
|
||||
176
libraries/include/boost/proto/domain.hpp
Normal file
176
libraries/include/boost/proto/domain.hpp
Normal file
@@ -0,0 +1,176 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file domain.hpp
|
||||
/// Contains definition of domain\<\> class template and helpers for
|
||||
/// defining domains with a generator and a grammar for controlling
|
||||
/// operator overloading.
|
||||
//
|
||||
// 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_PROTO_DOMAIN_HPP_EAN_02_13_2007
|
||||
#define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/generate.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct not_a_generator
|
||||
{};
|
||||
|
||||
struct not_a_grammar
|
||||
{};
|
||||
}
|
||||
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(domainns_)
|
||||
|
||||
/// \brief For use in defining domain tags to be used
|
||||
/// with \c proto::extends\<\>. A \e Domain associates
|
||||
/// an expression type with a \e Generator, and optionally
|
||||
/// a \e Grammar.
|
||||
///
|
||||
/// The Generator determines how new expressions in the
|
||||
/// domain are constructed. Typically, a generator wraps
|
||||
/// all new expressions in a wrapper that imparts
|
||||
/// domain-specific behaviors to expressions within its
|
||||
/// domain. (See \c proto::extends\<\>.)
|
||||
///
|
||||
/// The Grammar determines whether a given expression is
|
||||
/// valid within the domain, and automatically disables
|
||||
/// any operator overloads which would cause an invalid
|
||||
/// expression to be created. By default, the Grammar
|
||||
/// parameter defaults to the wildcard, \c proto::_, which
|
||||
/// makes all expressions valid within the domain.
|
||||
///
|
||||
/// Example:
|
||||
/// \code
|
||||
/// template<typename Expr>
|
||||
/// struct MyExpr;
|
||||
///
|
||||
/// struct MyGrammar
|
||||
/// : or_< terminal<_>, plus<MyGrammar, MyGrammar> >
|
||||
/// {};
|
||||
///
|
||||
/// // Define MyDomain, in which all expressions are
|
||||
/// // wrapped in MyExpr<> and only expressions that
|
||||
/// // conform to MyGrammar are allowed.
|
||||
/// struct MyDomain
|
||||
/// : domain<generator<MyExpr>, MyGrammar>
|
||||
/// {};
|
||||
///
|
||||
/// // Use MyDomain to define MyExpr
|
||||
/// template<typename Expr>
|
||||
/// struct MyExpr
|
||||
/// : extends<Expr, MyExpr<Expr>, MyDomain>
|
||||
/// {
|
||||
/// // ...
|
||||
/// };
|
||||
/// \endcode
|
||||
///
|
||||
template<
|
||||
typename Generator BOOST_PROTO_WHEN_BUILDING_DOCS(= default_generator)
|
||||
, typename Grammar BOOST_PROTO_WHEN_BUILDING_DOCS(= proto::_)
|
||||
>
|
||||
struct domain
|
||||
: Generator
|
||||
{
|
||||
typedef Grammar proto_grammar;
|
||||
|
||||
/// INTERNAL ONLY
|
||||
typedef void proto_is_domain_;
|
||||
};
|
||||
|
||||
/// \brief The domain expressions have by default, if
|
||||
/// \c proto::extends\<\> has not been used to associate
|
||||
/// a domain with an expression.
|
||||
///
|
||||
struct default_domain
|
||||
: domain<>
|
||||
{};
|
||||
|
||||
/// \brief A pseudo-domain for use in functions and
|
||||
/// metafunctions that require a domain parameter. It
|
||||
/// indicates that the domain of the parent node should
|
||||
/// be inferred from the domains of the child nodes.
|
||||
///
|
||||
/// \attention \c deduce_domain is not itself a valid domain.
|
||||
///
|
||||
struct deduce_domain
|
||||
: domain<detail::not_a_generator, detail::not_a_grammar>
|
||||
{};
|
||||
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(domainns_)
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
/// A metafunction that returns \c mpl::true_
|
||||
/// if the type \c T is the type of a Proto domain;
|
||||
/// \c mpl::false_ otherwise. If \c T inherits from
|
||||
/// \c proto::domain\<\>, \c is_domain\<T\> is
|
||||
/// \c mpl::true_.
|
||||
template<typename T, typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
|
||||
struct is_domain
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename T>
|
||||
struct is_domain<T, typename T::proto_is_domain_>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// A metafunction that returns the domain of
|
||||
/// a given type. If \c T is a Proto expression
|
||||
/// type, it returns that expression's associated
|
||||
/// domain. If not, it returns
|
||||
/// \c proto::default_domain.
|
||||
template<typename T, typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
|
||||
struct domain_of
|
||||
{
|
||||
typedef default_domain type;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename T>
|
||||
struct domain_of<T, typename T::proto_is_expr_>
|
||||
{
|
||||
typedef typename T::proto_domain type;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename T>
|
||||
struct domain_of<T &, void>
|
||||
{
|
||||
typedef typename domain_of<T>::type type;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename T>
|
||||
struct domain_of<boost::reference_wrapper<T>, void>
|
||||
{
|
||||
typedef typename domain_of<T>::type type;
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename T>
|
||||
struct domain_of<boost::reference_wrapper<T> const, void>
|
||||
{
|
||||
typedef typename domain_of<T>::type type;
|
||||
};
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
106
libraries/include/boost/proto/eval.hpp
Normal file
106
libraries/include/boost/proto/eval.hpp
Normal file
@@ -0,0 +1,106 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file eval.hpp
|
||||
/// Contains the eval() expression evaluator.
|
||||
//
|
||||
// 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_PROTO_EVAL_HPP_EAN_03_29_2007
|
||||
#define BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp> // must be first include
|
||||
#include <boost/proto/proto_fwd.hpp> // BOOST_PROTO_CALLABLE
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp> // must be last include
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
/// \brief A metafunction for calculating the return type
|
||||
/// of \c proto::eval() given a certain \c Expr and \c Context
|
||||
/// types.
|
||||
///
|
||||
/// \note The types \c Expr and \c Context should not be
|
||||
/// reference types. They may be cv-qualified, but the
|
||||
/// cv-qualification on the \c Context parameter is ignored.
|
||||
template<typename Expr, typename Context>
|
||||
struct eval
|
||||
{
|
||||
typedef typename Context::template eval<Expr>::result_type type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace functional
|
||||
{
|
||||
/// \brief A PolymorphicFunctionObject type for
|
||||
/// evaluating a given Proto expression with a given
|
||||
/// context.
|
||||
struct eval
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr, typename Context>
|
||||
struct result<This(Expr, Context)>
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::eval<
|
||||
typename remove_reference<Expr>::type
|
||||
, typename remove_reference<Context>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
/// \brief Evaluate a given Proto expression with a given
|
||||
/// context.
|
||||
/// \param expr The Proto expression to evaluate
|
||||
/// \param context The context in which the expression should be
|
||||
/// evaluated.
|
||||
/// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
|
||||
template<typename Expr, typename Context>
|
||||
typename proto::result_of::eval<Expr, Context>::type
|
||||
operator ()(Expr &expr, Context &context) const
|
||||
{
|
||||
return typename Context::template eval<Expr>()(expr, context);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename Expr, typename Context>
|
||||
typename proto::result_of::eval<Expr, Context>::type
|
||||
operator ()(Expr &expr, Context const &context) const
|
||||
{
|
||||
return typename Context::template eval<Expr>()(expr, context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief Evaluate a given Proto expression with a given
|
||||
/// context.
|
||||
/// \param expr The Proto expression to evaluate
|
||||
/// \param context The context in which the expression should be
|
||||
/// evaluated.
|
||||
/// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
|
||||
template<typename Expr, typename Context>
|
||||
typename proto::result_of::eval<Expr, Context>::type
|
||||
eval(Expr &expr, Context &context)
|
||||
{
|
||||
return typename Context::template eval<Expr>()(expr, context);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename Expr, typename Context>
|
||||
typename proto::result_of::eval<Expr, Context>::type
|
||||
eval(Expr &expr, Context const &context)
|
||||
{
|
||||
return typename Context::template eval<Expr>()(expr, context);
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
486
libraries/include/boost/proto/expr.hpp
Normal file
486
libraries/include/boost/proto/expr.hpp
Normal file
@@ -0,0 +1,486 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file expr.hpp
|
||||
/// Contains definition of expr\<\> class template.
|
||||
//
|
||||
// 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_PROTO_EXPR_HPP_EAN_04_01_2005
|
||||
#define BOOST_PROTO_EXPR_HPP_EAN_04_01_2005
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
#include <boost/preprocessor/selection/max.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/args.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# 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) // user defined constructor required
|
||||
#endif
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_CHILD(Z, N, DATA) \
|
||||
typedef typename Args::BOOST_PP_CAT(child, N) BOOST_PP_CAT(proto_child, N); \
|
||||
BOOST_PP_CAT(proto_child, N) BOOST_PP_CAT(child, N); \
|
||||
/**< INTERNAL ONLY */
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_VOID(Z, N, DATA) \
|
||||
typedef void BOOST_PP_CAT(proto_child, N); \
|
||||
/**< INTERNAL ONLY */
|
||||
|
||||
struct not_a_valid_type
|
||||
{
|
||||
private:
|
||||
not_a_valid_type()
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Tag, typename Arg>
|
||||
struct address_of_hack
|
||||
{
|
||||
typedef not_a_valid_type type;
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
struct address_of_hack<proto::tag::address_of, Expr &>
|
||||
{
|
||||
typedef Expr *type;
|
||||
};
|
||||
|
||||
template<typename X, std::size_t N, typename Y>
|
||||
void checked_copy(X (&x)[N], Y (&y)[N])
|
||||
{
|
||||
for(std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
y[i] = x[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct if_is_array
|
||||
{};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct if_is_array<T[N], N>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
/// \brief A helper metafunction for computing the
|
||||
/// return type of \c proto::expr\<\>::operator().
|
||||
template<typename Sig, typename This, typename Domain>
|
||||
struct funop;
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY), <boost/proto/detail/funop.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
}
|
||||
|
||||
// TODO consider adding a basic_expr<> that doesn't have operator=,
|
||||
// operator[] or operator() for use by BOOST_PROTO_BASIC_EXTENDS().
|
||||
// Those member functions are unused in that case, and only slow
|
||||
// down instantiations. basic_expr::proto_base_expr can still be
|
||||
// expr<> because uses of proto_base_expr in proto::matches<> shouldn't
|
||||
// case the expr<> type to be instantiated. (<-- Check that assumtion!)
|
||||
// OR, should expr<>::proto_base_expr be a typedef for basic_expr<>?
|
||||
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(exprns_)
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/expr.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(exprns_)
|
||||
|
||||
#undef BOOST_PROTO_CHILD
|
||||
#undef BOOST_PROTO_VOID
|
||||
|
||||
/// \brief Lets you inherit the interface of an expression
|
||||
/// while hiding from Proto the fact that the type is a Proto
|
||||
/// expression.
|
||||
template<typename Expr>
|
||||
struct unexpr
|
||||
: Expr
|
||||
{
|
||||
BOOST_PROTO_UNEXPR()
|
||||
|
||||
explicit unexpr(Expr const &expr)
|
||||
: Expr(expr)
|
||||
{}
|
||||
|
||||
using Expr::operator =;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_PROTO_EXPR_HPP_EAN_04_01_2005
|
||||
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
|
||||
#define ARG_COUNT BOOST_PP_MAX(1, BOOST_PP_ITERATION())
|
||||
#define IS_TERMINAL 0 == BOOST_PP_ITERATION()
|
||||
|
||||
/// \brief Representation of a node in an expression tree.
|
||||
///
|
||||
/// \c proto::expr\<\> is a node in an expression template tree. It
|
||||
/// is a container for its child sub-trees. It also serves as
|
||||
/// the terminal nodes of the tree.
|
||||
///
|
||||
/// \c Tag is type that represents the operation encoded by
|
||||
/// this expression. It is typically one of the structs
|
||||
/// in the \c boost::proto::tag namespace, but it doesn't
|
||||
/// have to be.
|
||||
///
|
||||
/// \c Args is a type list representing the type of the children
|
||||
/// of this expression. It is an instantiation of one
|
||||
/// of \c proto::list1\<\>, \c proto::list2\<\>, etc. The
|
||||
/// child types must all themselves be either \c expr\<\>
|
||||
/// or <tt>proto::expr\<\>&</tt>. If \c Args is an
|
||||
/// instantiation of \c proto::term\<\> then this
|
||||
/// \c expr\<\> type represents a terminal expression;
|
||||
/// the parameter to the \c proto::term\<\> template
|
||||
/// represents the terminal's value type.
|
||||
///
|
||||
/// \c Arity is an integral constant representing the number of child
|
||||
/// nodes this node contains. If \c Arity is 0, then this
|
||||
/// node is a terminal.
|
||||
///
|
||||
/// \c proto::expr\<\> is a valid Fusion random-access sequence, where
|
||||
/// the elements of the sequence are the child expressions.
|
||||
template<typename Tag, typename Args>
|
||||
struct expr<Tag, Args, BOOST_PP_ITERATION() >
|
||||
{
|
||||
typedef Tag proto_tag;
|
||||
BOOST_STATIC_CONSTANT(long, proto_arity_c = BOOST_PP_ITERATION());
|
||||
typedef mpl::long_<BOOST_PP_ITERATION() > proto_arity;
|
||||
typedef expr proto_base_expr;
|
||||
typedef Args proto_args;
|
||||
typedef default_domain proto_domain;
|
||||
BOOST_PROTO_FUSION_DEFINE_TAG(proto::tag::proto_expr)
|
||||
typedef expr proto_derived_expr;
|
||||
typedef void proto_is_expr_; /**< INTERNAL ONLY */
|
||||
|
||||
BOOST_PP_REPEAT(ARG_COUNT, BOOST_PROTO_CHILD, ~)
|
||||
BOOST_PP_REPEAT_FROM_TO(ARG_COUNT, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_VOID, ~)
|
||||
|
||||
/// \return *this
|
||||
///
|
||||
expr const &proto_base() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
expr &proto_base()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \return A new \c expr\<\> object initialized with the specified
|
||||
/// arguments.
|
||||
///
|
||||
template<BOOST_PP_ENUM_PARAMS(ARG_COUNT, typename A)>
|
||||
static expr const make(BOOST_PP_ENUM_BINARY_PARAMS(ARG_COUNT, A, const &a))
|
||||
{
|
||||
expr that = {BOOST_PP_ENUM_PARAMS(ARG_COUNT, a)};
|
||||
return that;
|
||||
}
|
||||
|
||||
#if IS_TERMINAL
|
||||
/// \overload
|
||||
///
|
||||
template<typename A0>
|
||||
static expr const make(A0 &a0)
|
||||
{
|
||||
expr that = {a0};
|
||||
return that;
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename A0, std::size_t N>
|
||||
static expr const make(A0 (&a0)[N], typename detail::if_is_array<proto_child0, N>::type = 0)
|
||||
{
|
||||
expr that;
|
||||
detail::checked_copy(a0, that.child0);
|
||||
return that;
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename A0, std::size_t N>
|
||||
static expr const make(A0 const (&a0)[N], typename detail::if_is_array<proto_child0, N>::type = 0)
|
||||
{
|
||||
expr that;
|
||||
detail::checked_copy(a0, that.child0);
|
||||
return that;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1 == BOOST_PP_ITERATION()
|
||||
/// If \c Tag is \c boost::proto::tag::address_of and \c proto_child0 is
|
||||
/// <tt>T&</tt>, then \c address_of_hack_type_ is <tt>T*</tt>.
|
||||
/// Otherwise, it is some undefined type.
|
||||
typedef typename detail::address_of_hack<Tag, proto_child0>::type address_of_hack_type_;
|
||||
|
||||
/// \return The address of <tt>this->child0</tt> if \c Tag is
|
||||
/// \c boost::proto::tag::address_of. Otherwise, this function will
|
||||
/// fail to compile.
|
||||
///
|
||||
/// \attention Proto overloads <tt>operator&</tt>, which means that
|
||||
/// proto-ified objects cannot have their addresses taken, unless we use
|
||||
/// the following hack to make \c &x implicitly convertible to \c X*.
|
||||
operator address_of_hack_type_() const
|
||||
{
|
||||
return boost::addressof(this->child0);
|
||||
}
|
||||
#else
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
typedef detail::not_a_valid_type address_of_hack_type_;
|
||||
#endif
|
||||
|
||||
/// Assignment
|
||||
///
|
||||
/// \param a The rhs.
|
||||
/// \return A new \c expr\<\> node representing an assignment of \c a to \c *this.
|
||||
template<typename A>
|
||||
proto::expr<
|
||||
proto::tag::assign
|
||||
, list2<expr const &, typename result_of::as_child<A>::type>
|
||||
> const
|
||||
operator =(A &a) const
|
||||
{
|
||||
proto::expr<
|
||||
proto::tag::assign
|
||||
, list2<expr const &, typename result_of::as_child<A>::type>
|
||||
> that = {*this, proto::as_child(a)};
|
||||
return that;
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename A>
|
||||
proto::expr<
|
||||
proto::tag::assign
|
||||
, list2<expr const &, typename result_of::as_child<A const>::type>
|
||||
> const
|
||||
operator =(A const &a) const
|
||||
{
|
||||
proto::expr<
|
||||
proto::tag::assign
|
||||
, list2<expr const &, typename result_of::as_child<A const>::type>
|
||||
> that = {*this, proto::as_child(a)};
|
||||
return that;
|
||||
}
|
||||
|
||||
#if IS_TERMINAL
|
||||
/// \overload
|
||||
///
|
||||
template<typename A>
|
||||
proto::expr<
|
||||
proto::tag::assign
|
||||
, list2<expr &, typename result_of::as_child<A>::type>
|
||||
> const
|
||||
operator =(A &a)
|
||||
{
|
||||
proto::expr<
|
||||
proto::tag::assign
|
||||
, list2<expr &, typename result_of::as_child<A>::type>
|
||||
> that = {*this, proto::as_child(a)};
|
||||
return that;
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename A>
|
||||
proto::expr<
|
||||
proto::tag::assign
|
||||
, list2<expr &, typename result_of::as_child<A const>::type>
|
||||
> const
|
||||
operator =(A const &a)
|
||||
{
|
||||
proto::expr<
|
||||
proto::tag::assign
|
||||
, list2<expr &, typename result_of::as_child<A const>::type>
|
||||
> that = {*this, proto::as_child(a)};
|
||||
return that;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Subscript
|
||||
///
|
||||
/// \param a The rhs.
|
||||
/// \return A new \c expr\<\> node representing \c *this subscripted with \c a.
|
||||
template<typename A>
|
||||
proto::expr<
|
||||
proto::tag::subscript
|
||||
, list2<expr const &, typename result_of::as_child<A>::type>
|
||||
> const
|
||||
operator [](A &a) const
|
||||
{
|
||||
proto::expr<
|
||||
proto::tag::subscript
|
||||
, list2<expr const &, typename result_of::as_child<A>::type>
|
||||
> that = {*this, proto::as_child(a)};
|
||||
return that;
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename A>
|
||||
proto::expr<
|
||||
proto::tag::subscript
|
||||
, list2<expr const &, typename result_of::as_child<A const>::type> > const
|
||||
operator [](A const &a) const
|
||||
{
|
||||
proto::expr<
|
||||
proto::tag::subscript
|
||||
, list2<expr const &, typename result_of::as_child<A const>::type>
|
||||
> that = {*this, proto::as_child(a)};
|
||||
return that;
|
||||
}
|
||||
|
||||
#if IS_TERMINAL
|
||||
/// \overload
|
||||
///
|
||||
template<typename A>
|
||||
proto::expr<
|
||||
proto::tag::subscript
|
||||
, list2<expr &, typename result_of::as_child<A>::type>
|
||||
> const
|
||||
operator [](A &a)
|
||||
{
|
||||
proto::expr<
|
||||
proto::tag::subscript
|
||||
, list2<expr &, typename result_of::as_child<A>::type>
|
||||
> that = {*this, proto::as_child(a)};
|
||||
return that;
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename A>
|
||||
proto::expr<
|
||||
proto::tag::subscript
|
||||
, list2<expr &, typename result_of::as_child<A const>::type>
|
||||
> const
|
||||
operator [](A const &a)
|
||||
{
|
||||
proto::expr<
|
||||
proto::tag::subscript
|
||||
, list2<expr &, typename result_of::as_child<A const>::type>
|
||||
> that = {*this, proto::as_child(a)};
|
||||
return that;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Encodes the return type of \c expr\<\>::operator(), for use with \c boost::result_of\<\>
|
||||
///
|
||||
template<typename Sig>
|
||||
struct result
|
||||
{
|
||||
typedef typename result_of::funop<Sig, expr, default_domain>::type const type;
|
||||
};
|
||||
|
||||
/// Function call
|
||||
///
|
||||
/// \return A new \c expr\<\> node representing the function invocation of \c (*this)().
|
||||
proto::expr<proto::tag::function, list1<expr const &> > const
|
||||
operator ()() const
|
||||
{
|
||||
proto::expr<proto::tag::function, list1<expr const &> > that = {*this};
|
||||
return that;
|
||||
}
|
||||
|
||||
#if IS_TERMINAL
|
||||
/// \overload
|
||||
///
|
||||
proto::expr<proto::tag::function, list1<expr &> > const
|
||||
operator ()()
|
||||
{
|
||||
proto::expr<proto::tag::function, list1<expr &> > that = {*this};
|
||||
return that;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_2 (3, (1, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY), <boost/proto/expr.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
};
|
||||
|
||||
#undef ARG_COUNT
|
||||
#undef IS_TERMINAL
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 2
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
typename result_of::BOOST_PP_CAT(funop, N)<
|
||||
expr const
|
||||
, default_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
|
||||
>::type const
|
||||
operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const &a)) const
|
||||
{
|
||||
return result_of::BOOST_PP_CAT(funop, N)<
|
||||
expr const
|
||||
, default_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
|
||||
>::call(*this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));
|
||||
}
|
||||
|
||||
#if IS_TERMINAL
|
||||
/// \overload
|
||||
///
|
||||
template<BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
typename result_of::BOOST_PP_CAT(funop, N)<
|
||||
expr
|
||||
, default_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
|
||||
>::type const
|
||||
operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const &a))
|
||||
{
|
||||
return result_of::BOOST_PP_CAT(funop, N)<
|
||||
expr
|
||||
, default_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
|
||||
>::call(*this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef N
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif
|
||||
596
libraries/include/boost/proto/extends.hpp
Normal file
596
libraries/include/boost/proto/extends.hpp
Normal file
@@ -0,0 +1,596 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file extends.hpp
|
||||
/// Macros and a base class for defining end-user expression types
|
||||
//
|
||||
// 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_PROTO_EXTENDS_HPP_EAN_11_1_2006
|
||||
#define BOOST_PROTO_EXTENDS_HPP_EAN_11_1_2006
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <cstddef> // for offsetof
|
||||
#include <boost/preprocessor/tuple/elem.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/expr.hpp>
|
||||
#include <boost/proto/args.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/generate.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
# define BOOST_PROTO_ADDROF(x) ((char const volatile*)boost::addressof(x))
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
# define BOOST_PROTO_OFFSETOF(s,m) (BOOST_PROTO_ADDROF((((s *)this)->m)) - BOOST_PROTO_ADDROF(*((s *)this)))
|
||||
#else
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
# define BOOST_PROTO_OFFSETOF offsetof
|
||||
#endif
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_CONST0
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_CONST1 const
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_TEMPLATE_YES_(Z, N) template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)>
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_TEMPLATE_NO_(Z, N)
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, Const) \
|
||||
BOOST_PP_IF(N, BOOST_PROTO_TEMPLATE_YES_, BOOST_PROTO_TEMPLATE_NO_)(Z, N) \
|
||||
typename boost::result_of< \
|
||||
proto_domain( \
|
||||
typename boost::proto::result_of::BOOST_PP_CAT(funop, N)< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const \
|
||||
, proto_domain \
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A) \
|
||||
>::type \
|
||||
) \
|
||||
>::type const \
|
||||
operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) BOOST_PROTO_CONST ## Const \
|
||||
{ \
|
||||
typedef boost::proto::result_of::BOOST_PP_CAT(funop, N)< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const \
|
||||
, proto_domain \
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A) \
|
||||
> funop; \
|
||||
return proto_domain()( \
|
||||
funop::call( \
|
||||
*static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, a) \
|
||||
) \
|
||||
); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(Const) \
|
||||
template<typename... A> \
|
||||
typename boost::result_of< \
|
||||
proto_domain( \
|
||||
typename boost::proto::result_of::funop< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const(A const &...) \
|
||||
, proto_derived_expr \
|
||||
, proto_domain \
|
||||
>::type \
|
||||
) \
|
||||
>::type const \
|
||||
operator ()(A const &...a) BOOST_PROTO_CONST ## Const \
|
||||
{ \
|
||||
typedef boost::proto::result_of::funop< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const(A const &...) \
|
||||
, proto_derived_expr \
|
||||
, proto_domain \
|
||||
> funop; \
|
||||
return proto_domain()( \
|
||||
funop::call( \
|
||||
*static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
|
||||
, a... \
|
||||
) \
|
||||
); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, DATA) \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, 1)
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, DATA) \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, 0)
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_DEFINE_FUN_OP(Z, N, DATA) \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, DATA) \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, DATA) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_EXTENDS_CHILD(Z, N, DATA) \
|
||||
typedef \
|
||||
typename proto_base_expr::BOOST_PP_CAT(proto_child, N) \
|
||||
BOOST_PP_CAT(proto_child, N); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain) \
|
||||
Expr proto_expr_; \
|
||||
\
|
||||
typedef typename Expr::proto_base_expr proto_base_expr; \
|
||||
typedef Domain proto_domain; \
|
||||
typedef Derived proto_derived_expr; \
|
||||
typedef typename proto_base_expr::proto_tag proto_tag; \
|
||||
typedef typename proto_base_expr::proto_args proto_args; \
|
||||
typedef typename proto_base_expr::proto_arity proto_arity; \
|
||||
typedef typename proto_base_expr::address_of_hack_type_ proto_address_of_hack_type_; \
|
||||
typedef void proto_is_expr_; /**< INTERNAL ONLY */ \
|
||||
BOOST_STATIC_CONSTANT(long, proto_arity_c = proto_base_expr::proto_arity_c); \
|
||||
BOOST_PROTO_FUSION_DEFINE_TAG(boost::proto::tag::proto_expr) \
|
||||
BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_CHILD, ~) \
|
||||
\
|
||||
static proto_derived_expr const make(Expr const &expr) \
|
||||
{ \
|
||||
proto_derived_expr that = {expr}; \
|
||||
return that; \
|
||||
} \
|
||||
\
|
||||
proto_base_expr &proto_base() \
|
||||
{ \
|
||||
return this->proto_expr_.proto_base(); \
|
||||
} \
|
||||
\
|
||||
proto_base_expr const &proto_base() const \
|
||||
{ \
|
||||
return this->proto_expr_.proto_base(); \
|
||||
} \
|
||||
\
|
||||
operator proto_address_of_hack_type_() const \
|
||||
{ \
|
||||
return boost::addressof(this->proto_base().child0); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain) \
|
||||
BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain) \
|
||||
typedef void proto_is_aggregate_; \
|
||||
/**< INTERNAL ONLY */
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Const) \
|
||||
template<typename A> \
|
||||
typename boost::result_of< \
|
||||
proto_domain( \
|
||||
boost::proto::expr< \
|
||||
boost::proto::tag::assign \
|
||||
, boost::proto::list2< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const & \
|
||||
, typename boost::proto::result_of::as_child<A, proto_domain>::type \
|
||||
> \
|
||||
> \
|
||||
) \
|
||||
>::type const \
|
||||
operator =(A &a) BOOST_PROTO_CONST ## Const \
|
||||
{ \
|
||||
typedef boost::proto::expr< \
|
||||
boost::proto::tag::assign \
|
||||
, boost::proto::list2< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const & \
|
||||
, typename boost::proto::result_of::as_child<A, proto_domain>::type \
|
||||
> \
|
||||
> that_type; \
|
||||
that_type that = { \
|
||||
*static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
|
||||
, boost::proto::as_child<proto_domain>(a) \
|
||||
}; \
|
||||
return proto_domain()(that); \
|
||||
} \
|
||||
\
|
||||
template<typename A> \
|
||||
typename boost::result_of< \
|
||||
proto_domain( \
|
||||
boost::proto::expr< \
|
||||
boost::proto::tag::assign \
|
||||
, boost::proto::list2< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const & \
|
||||
, typename boost::proto::result_of::as_child<A const, proto_domain>::type \
|
||||
> \
|
||||
> \
|
||||
) \
|
||||
>::type const \
|
||||
operator =(A const &a) BOOST_PROTO_CONST ## Const \
|
||||
{ \
|
||||
typedef boost::proto::expr< \
|
||||
boost::proto::tag::assign \
|
||||
, boost::proto::list2< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const & \
|
||||
, typename boost::proto::result_of::as_child<A const, proto_domain>::type \
|
||||
> \
|
||||
> that_type; \
|
||||
that_type that = { \
|
||||
*static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
|
||||
, boost::proto::as_child<proto_domain>(a) \
|
||||
}; \
|
||||
return proto_domain()(that); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_ASSIGN_CONST() \
|
||||
BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(1)
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST() \
|
||||
BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(0)
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_ASSIGN() \
|
||||
BOOST_PROTO_EXTENDS_ASSIGN_CONST() \
|
||||
BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST() \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Const) \
|
||||
template<typename A> \
|
||||
typename boost::result_of< \
|
||||
proto_domain( \
|
||||
boost::proto::expr< \
|
||||
boost::proto::tag::subscript \
|
||||
, boost::proto::list2< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const & \
|
||||
, typename boost::proto::result_of::as_child<A, proto_domain>::type \
|
||||
> \
|
||||
> \
|
||||
) \
|
||||
>::type const \
|
||||
operator [](A &a) BOOST_PROTO_CONST ## Const \
|
||||
{ \
|
||||
typedef boost::proto::expr< \
|
||||
boost::proto::tag::subscript \
|
||||
, boost::proto::list2< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const & \
|
||||
, typename boost::proto::result_of::as_child<A, proto_domain>::type \
|
||||
> \
|
||||
> that_type; \
|
||||
that_type that = { \
|
||||
*static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
|
||||
, boost::proto::as_child<proto_domain>(a) \
|
||||
}; \
|
||||
return proto_domain()(that); \
|
||||
} \
|
||||
\
|
||||
template<typename A> \
|
||||
typename boost::result_of< \
|
||||
proto_domain( \
|
||||
boost::proto::expr< \
|
||||
boost::proto::tag::subscript \
|
||||
, boost::proto::list2< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const & \
|
||||
, typename boost::proto::result_of::as_child<A const, proto_domain>::type \
|
||||
> \
|
||||
> \
|
||||
) \
|
||||
>::type const \
|
||||
operator [](A const &a) BOOST_PROTO_CONST ## Const \
|
||||
{ \
|
||||
typedef boost::proto::expr< \
|
||||
boost::proto::tag::subscript \
|
||||
, boost::proto::list2< \
|
||||
proto_derived_expr BOOST_PROTO_CONST ## Const & \
|
||||
, typename boost::proto::result_of::as_child<A const, proto_domain>::type \
|
||||
> \
|
||||
> that_type; \
|
||||
that_type that = { \
|
||||
*static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
|
||||
, boost::proto::as_child<proto_domain>(a) \
|
||||
}; \
|
||||
return proto_domain()(that); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST() \
|
||||
BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(1)
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST() \
|
||||
BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(0)
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_SUBSCRIPT() \
|
||||
BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST() \
|
||||
BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST() \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_EXTENDS_FUNCTION_() \
|
||||
template<typename Sig> \
|
||||
struct result \
|
||||
{ \
|
||||
typedef \
|
||||
typename boost::result_of< \
|
||||
proto_domain( \
|
||||
typename boost::proto::result_of::funop< \
|
||||
Sig \
|
||||
, proto_derived_expr \
|
||||
, proto_domain \
|
||||
>::type \
|
||||
) \
|
||||
>::type const \
|
||||
type; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
#ifdef BOOST_HAS_VARIADIC_TMPL
|
||||
#define BOOST_PROTO_EXTENDS_FUNCTION_CONST() \
|
||||
BOOST_PROTO_EXTENDS_FUNCTION_() \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(1) \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST() \
|
||||
BOOST_PROTO_EXTENDS_FUNCTION_() \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(0) \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_FUNCTION() \
|
||||
BOOST_PROTO_EXTENDS_FUNCTION_() \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(0) \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(1) \
|
||||
/**/
|
||||
#else
|
||||
#define BOOST_PROTO_EXTENDS_FUNCTION_CONST() \
|
||||
BOOST_PROTO_EXTENDS_FUNCTION_() \
|
||||
BOOST_PP_REPEAT_FROM_TO( \
|
||||
0 \
|
||||
, BOOST_PROTO_MAX_FUNCTION_CALL_ARITY \
|
||||
, BOOST_PROTO_DEFINE_FUN_OP_CONST \
|
||||
, ~ \
|
||||
) \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST() \
|
||||
BOOST_PROTO_EXTENDS_FUNCTION_() \
|
||||
BOOST_PP_REPEAT_FROM_TO( \
|
||||
0 \
|
||||
, BOOST_PROTO_MAX_FUNCTION_CALL_ARITY \
|
||||
, BOOST_PROTO_DEFINE_FUN_OP_NON_CONST \
|
||||
, ~ \
|
||||
) \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_EXTENDS_FUNCTION() \
|
||||
BOOST_PROTO_EXTENDS_FUNCTION_() \
|
||||
BOOST_PP_REPEAT_FROM_TO( \
|
||||
0 \
|
||||
, BOOST_PROTO_MAX_FUNCTION_CALL_ARITY \
|
||||
, BOOST_PROTO_DEFINE_FUN_OP \
|
||||
, ~ \
|
||||
) \
|
||||
/**/
|
||||
#endif
|
||||
|
||||
#define BOOST_PROTO_EXTENDS(Expr, Derived, Domain) \
|
||||
BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain) \
|
||||
BOOST_PROTO_EXTENDS_ASSIGN() \
|
||||
BOOST_PROTO_EXTENDS_SUBSCRIPT() \
|
||||
BOOST_PROTO_EXTENDS_FUNCTION() \
|
||||
/**/
|
||||
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(exprns_)
|
||||
|
||||
/// \brief Empty type to be used as a dummy template parameter of
|
||||
/// POD expression wrappers. It allows argument-dependent lookup
|
||||
/// to find Proto's operator overloads.
|
||||
///
|
||||
/// \c proto::is_proto_expr allows argument-dependent lookup
|
||||
/// to find Proto's operator overloads. For example:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename T, typename Dummy = proto::is_proto_expr>
|
||||
/// struct my_terminal
|
||||
/// {
|
||||
/// BOOST_PROTO_BASIC_EXTENDS(
|
||||
/// typename proto::terminal<T>::type
|
||||
/// , my_terminal<T>
|
||||
/// , default_domain
|
||||
/// )
|
||||
/// };
|
||||
///
|
||||
/// // ...
|
||||
/// my_terminal<int> _1, _2;
|
||||
/// _1 + _2; // OK, uses proto::operator+
|
||||
/// \endcode
|
||||
///
|
||||
/// Without the second \c Dummy template parameter, Proto's operator
|
||||
/// overloads would not be considered by name lookup.
|
||||
struct is_proto_expr
|
||||
{};
|
||||
|
||||
/// \brief extends\<\> class template for adding behaviors to a Proto expression template
|
||||
///
|
||||
template<
|
||||
typename Expr
|
||||
, typename Derived
|
||||
, typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= proto::default_domain)
|
||||
, long Arity BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity_c)
|
||||
>
|
||||
struct extends
|
||||
{
|
||||
extends()
|
||||
: proto_expr_()
|
||||
{}
|
||||
|
||||
extends(extends const &that)
|
||||
: proto_expr_(that.proto_expr_)
|
||||
{}
|
||||
|
||||
extends(Expr const &expr_)
|
||||
: proto_expr_(expr_)
|
||||
{}
|
||||
|
||||
BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain)
|
||||
BOOST_PROTO_EXTENDS_ASSIGN_CONST()
|
||||
BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST()
|
||||
|
||||
// Instead of using BOOST_PROTO_EXTENDS_FUNCTION, which uses
|
||||
// nested preprocessor loops, use file iteration here to generate
|
||||
// the operator() overloads, which is more efficient.
|
||||
BOOST_PROTO_EXTENDS_FUNCTION_()
|
||||
|
||||
#ifdef BOOST_HAS_VARIADIC_TMPL
|
||||
BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(1)
|
||||
#else
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PP_LOCAL_MACRO(N) \
|
||||
BOOST_PROTO_DEFINE_FUN_OP_CONST(1, N, ~) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY))
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
/// \brief extends\<\> class template for adding behaviors to a Proto expression template
|
||||
///
|
||||
template<typename Expr, typename Derived, typename Domain>
|
||||
struct extends<Expr, Derived, Domain, 0>
|
||||
{
|
||||
extends()
|
||||
: proto_expr_()
|
||||
{}
|
||||
|
||||
extends(extends const &that)
|
||||
: proto_expr_(that.proto_expr_)
|
||||
{}
|
||||
|
||||
extends(Expr const &expr_)
|
||||
: proto_expr_(expr_)
|
||||
{}
|
||||
|
||||
BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain)
|
||||
BOOST_PROTO_EXTENDS_ASSIGN()
|
||||
BOOST_PROTO_EXTENDS_SUBSCRIPT()
|
||||
|
||||
// Instead of using BOOST_PROTO_EXTENDS_FUNCTION, which uses
|
||||
// nested preprocessor loops, use file iteration here to generate
|
||||
// the operator() overloads, which is more efficient.
|
||||
BOOST_PROTO_EXTENDS_FUNCTION_()
|
||||
|
||||
#ifdef BOOST_HAS_VARIADIC_TMPL
|
||||
BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(0)
|
||||
BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(1)
|
||||
#else
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PP_LOCAL_MACRO(N) \
|
||||
BOOST_PROTO_DEFINE_FUN_OP(1, N, ~) \
|
||||
/**/
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY))
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename This, typename Fun, typename Domain>
|
||||
struct virtual_member
|
||||
{
|
||||
typedef
|
||||
expr<tag::member, list2<This &, expr<tag::terminal, term<Fun> > const &> >
|
||||
proto_base_expr;
|
||||
typedef Domain proto_domain;
|
||||
typedef virtual_member<This, Fun, Domain> proto_derived_expr;
|
||||
typedef typename proto_base_expr::proto_tag proto_tag;
|
||||
typedef typename proto_base_expr::proto_args proto_args;
|
||||
typedef typename proto_base_expr::proto_arity proto_arity;
|
||||
typedef typename proto_base_expr::address_of_hack_type_ proto_address_of_hack_type_;
|
||||
typedef void proto_is_expr_; /**< INTERNAL ONLY */
|
||||
BOOST_PROTO_FUSION_DEFINE_TAG(boost::proto::tag::proto_expr)
|
||||
BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_CHILD, ~)
|
||||
typedef void proto_is_aggregate_; /**< INTERNAL ONLY */
|
||||
|
||||
BOOST_PROTO_EXTENDS_ASSIGN()
|
||||
BOOST_PROTO_EXTENDS_SUBSCRIPT()
|
||||
BOOST_PROTO_EXTENDS_FUNCTION()
|
||||
|
||||
proto_base_expr const proto_base() const
|
||||
{
|
||||
proto_base_expr that = {this->child0(), this->child1()};
|
||||
return that;
|
||||
}
|
||||
|
||||
proto_child0 child0() const
|
||||
{
|
||||
return *(This *)((char *)this - BOOST_PROTO_OFFSETOF(This, proto_member_union_start_));
|
||||
}
|
||||
|
||||
proto_child1 child1() const
|
||||
{
|
||||
static expr<tag::terminal, term<Fun> > const that = {Fun()};
|
||||
return that;
|
||||
}
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_EXTENDS_MEMBER_(R, DATA, ELEM) \
|
||||
boost::proto::exprns_::virtual_member< \
|
||||
proto_derived_expr \
|
||||
, BOOST_PP_TUPLE_ELEM(2, 0, ELEM) \
|
||||
, proto_domain \
|
||||
> BOOST_PP_TUPLE_ELEM(2, 1, ELEM); \
|
||||
/**/
|
||||
|
||||
/// \brief For declaring virtual data members in an extension class.
|
||||
///
|
||||
#define BOOST_PROTO_EXTENDS_MEMBERS(SEQ) \
|
||||
union \
|
||||
{ \
|
||||
char proto_member_union_start_; \
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_PROTO_EXTENDS_MEMBER_, ~, SEQ) \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(exprns_)
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
729
libraries/include/boost/proto/fusion.hpp
Normal file
729
libraries/include/boost/proto/fusion.hpp
Normal file
@@ -0,0 +1,729 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file fusion.hpp
|
||||
/// Make any Proto expression a valid Fusion sequence
|
||||
//
|
||||
// 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_PROTO_FUSION_HPP_EAN_11_04_2006
|
||||
#define BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/long.hpp>
|
||||
#include <boost/mpl/sequence_tag_fwd.hpp>
|
||||
#if BOOST_VERSION >= 103500
|
||||
#include <boost/fusion/include/is_view.hpp>
|
||||
#include <boost/fusion/include/tag_of_fwd.hpp>
|
||||
#include <boost/fusion/include/category_of.hpp>
|
||||
#include <boost/fusion/include/iterator_base.hpp>
|
||||
#include <boost/fusion/include/intrinsic.hpp>
|
||||
#include <boost/fusion/include/pop_front.hpp>
|
||||
#include <boost/fusion/include/reverse.hpp>
|
||||
#include <boost/fusion/include/single_view.hpp>
|
||||
#include <boost/fusion/include/transform_view.hpp>
|
||||
#include <boost/fusion/support/ext_/is_segmented.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/ext_/size_s.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_iterator.hpp>
|
||||
#else
|
||||
#include <boost/spirit/fusion/sequence/is_sequence.hpp>
|
||||
#include <boost/spirit/fusion/sequence/begin.hpp>
|
||||
#include <boost/spirit/fusion/sequence/end.hpp>
|
||||
#include <boost/spirit/fusion/sequence/at.hpp>
|
||||
#include <boost/spirit/fusion/sequence/value_at.hpp>
|
||||
#include <boost/spirit/fusion/sequence/single_view.hpp>
|
||||
#include <boost/spirit/fusion/sequence/transform_view.hpp>
|
||||
#include <boost/proto/detail/reverse.hpp>
|
||||
#include <boost/proto/detail/pop_front.hpp>
|
||||
#endif
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/eval.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
#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 proto
|
||||
{
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define UNREF(x) typename boost::remove_reference<x>::type
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename Expr, long Pos>
|
||||
struct expr_iterator
|
||||
: fusion::iterator_base<expr_iterator<Expr, Pos> >
|
||||
{
|
||||
typedef Expr expr_type;
|
||||
typedef typename Expr::proto_tag proto_tag;
|
||||
BOOST_STATIC_CONSTANT(long, index = Pos);
|
||||
BOOST_PROTO_FUSION_DEFINE_CATEGORY(fusion::random_access_traversal_tag)
|
||||
BOOST_PROTO_FUSION_DEFINE_TAG(tag::proto_expr_iterator)
|
||||
|
||||
expr_iterator(Expr const &e)
|
||||
: expr(e)
|
||||
{}
|
||||
|
||||
Expr const &expr;
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
struct flat_view
|
||||
{
|
||||
typedef Expr expr_type;
|
||||
typedef typename Expr::proto_tag proto_tag;
|
||||
BOOST_PROTO_FUSION_DEFINE_CATEGORY(fusion::forward_traversal_tag)
|
||||
BOOST_PROTO_FUSION_DEFINE_TAG(tag::proto_flat_view)
|
||||
|
||||
explicit flat_view(Expr &expr)
|
||||
: expr_(expr)
|
||||
{}
|
||||
|
||||
Expr &expr_;
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct as_element
|
||||
{
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
: mpl::if_<
|
||||
is_same<Tag, UNREF(Expr)::proto_tag>
|
||||
, flat_view<UNREF(Expr) const>
|
||||
, fusion::single_view<UNREF(Expr) const &>
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
typename result<as_element(Expr const &)>::type
|
||||
operator ()(Expr const &expr) const
|
||||
{
|
||||
return typename result<as_element(Expr const &)>::type(expr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
template<typename Expr>
|
||||
struct flatten
|
||||
{
|
||||
typedef detail::flat_view<Expr const> type;
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
struct flatten<Expr &>
|
||||
{
|
||||
typedef detail::flat_view<Expr const> type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace functional
|
||||
{
|
||||
/// \brief A PolymorphicFunctionObject type that returns a "flattened"
|
||||
/// view of a Proto expression tree.
|
||||
///
|
||||
/// A PolymorphicFunctionObject type that returns a "flattened"
|
||||
/// view of a Proto expression tree. For a tree with a top-most node
|
||||
/// tag of type \c T, the elements of the flattened sequence are
|
||||
/// determined by recursing into each child node with the same
|
||||
/// tag type and returning those nodes of different type. So for
|
||||
/// instance, the Proto expression tree corresponding to the
|
||||
/// expression <tt>a | b | c</tt> has a flattened view with elements
|
||||
/// [a, b, c], even though the tree is grouped as
|
||||
/// <tt>((a | b) | c)</tt>.
|
||||
struct flatten
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef proto::detail::flat_view<UNREF(Expr) const> type;
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
proto::detail::flat_view<Expr const>
|
||||
operator ()(Expr const &expr) const
|
||||
{
|
||||
return proto::detail::flat_view<Expr const>(expr);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A PolymorphicFunctionObject type that invokes the
|
||||
/// \c fusion::pop_front() algorithm on its argument.
|
||||
///
|
||||
/// A PolymorphicFunctionObject type that invokes the
|
||||
/// \c fusion::pop_front() algorithm on its argument. This is
|
||||
/// useful for defining a CallableTransform like \c pop_front(_)
|
||||
/// which removes the first child from a Proto expression node.
|
||||
/// Such a transform might be used as the first argument to the
|
||||
/// \c proto::fold\<\> transform; that is, fold all but
|
||||
/// the first child.
|
||||
struct pop_front
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef
|
||||
typename fusion::BOOST_PROTO_FUSION_RESULT_OF::pop_front<UNREF(Expr) const>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
typename fusion::BOOST_PROTO_FUSION_RESULT_OF::pop_front<Expr const>::type
|
||||
operator ()(Expr const &expr) const
|
||||
{
|
||||
return fusion::pop_front(expr);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A PolymorphicFunctionObject type that invokes the
|
||||
/// \c fusion::reverse() algorithm on its argument.
|
||||
///
|
||||
/// A PolymorphicFunctionObject type that invokes the
|
||||
/// \c fusion::reverse() algorithm on its argument. This is
|
||||
/// useful for defining a CallableTransform like \c reverse(_)
|
||||
/// which reverses the order of the children of a Proto
|
||||
/// expression node.
|
||||
struct reverse
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef
|
||||
typename fusion::BOOST_PROTO_FUSION_RESULT_OF::reverse<UNREF(Expr) const>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
typename fusion::BOOST_PROTO_FUSION_RESULT_OF::reverse<Expr const>::type
|
||||
operator ()(Expr const &expr) const
|
||||
{
|
||||
return fusion::reverse(expr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief A function that returns a "flattened"
|
||||
/// view of a Proto expression tree.
|
||||
///
|
||||
/// For a tree with a top-most node
|
||||
/// tag of type \c T, the elements of the flattened sequence are
|
||||
/// determined by recursing into each child node with the same
|
||||
/// tag type and returning those nodes of different type. So for
|
||||
/// instance, the Proto expression tree corresponding to the
|
||||
/// expression <tt>a | b | c</tt> has a flattened view with elements
|
||||
/// [a, b, c], even though the tree is grouped as
|
||||
/// <tt>((a | b) | c)</tt>.
|
||||
template<typename Expr>
|
||||
proto::detail::flat_view<Expr const>
|
||||
flatten(Expr const &expr)
|
||||
{
|
||||
return proto::detail::flat_view<Expr const>(expr);
|
||||
}
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<functional::flatten>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<functional::pop_front>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<functional::reverse>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Context>
|
||||
struct eval_fun
|
||||
{
|
||||
explicit eval_fun(Context &ctx)
|
||||
: ctx_(ctx)
|
||||
{}
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::eval<UNREF(Expr), Context>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
typename proto::result_of::eval<Expr, Context>::type
|
||||
operator ()(Expr &expr) const
|
||||
{
|
||||
return proto::eval(expr, this->ctx_);
|
||||
}
|
||||
|
||||
private:
|
||||
Context &ctx_;
|
||||
};
|
||||
}}
|
||||
|
||||
// Don't bother emitting all this into the Doxygen-generated
|
||||
// reference section. It's enough to say that Proto expressions
|
||||
// are valid Fusion sequence without showing all this gunk.
|
||||
#ifndef BOOST_PROTO_BUILDING_DOCS
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
#if BOOST_VERSION < 103500
|
||||
template<typename Tag, typename Args, long Arity>
|
||||
struct is_sequence<proto::expr<Tag, Args, Arity> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
template<typename Tag, typename Args, long Arity>
|
||||
struct is_sequence<proto::expr<Tag, Args, Arity> const>
|
||||
: mpl::true_
|
||||
{};
|
||||
#endif
|
||||
|
||||
namespace BOOST_PROTO_FUSION_EXTENSION
|
||||
{
|
||||
|
||||
template<typename Tag>
|
||||
struct is_view_impl;
|
||||
|
||||
template<>
|
||||
struct is_view_impl<proto::tag::proto_flat_view>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: mpl::true_
|
||||
{};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_view_impl<proto::tag::proto_expr>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct value_of_impl;
|
||||
|
||||
template<>
|
||||
struct value_of_impl<proto::tag::proto_expr_iterator>
|
||||
{
|
||||
template<
|
||||
typename Iterator
|
||||
, long Arity = proto::arity_of<typename Iterator::expr_type>::value
|
||||
>
|
||||
struct apply
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::child_c<
|
||||
typename Iterator::expr_type
|
||||
, Iterator::index
|
||||
>::value_type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
struct apply<Iterator, 0>
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::value<
|
||||
typename Iterator::expr_type
|
||||
>::value_type
|
||||
type;
|
||||
};
|
||||
};
|
||||
|
||||
#if BOOST_VERSION < 103500
|
||||
template<typename Tag>
|
||||
struct value_impl;
|
||||
|
||||
template<>
|
||||
struct value_impl<proto::tag::proto_expr_iterator>
|
||||
: value_of_impl<proto::tag::proto_expr_iterator>
|
||||
{};
|
||||
#endif
|
||||
|
||||
template<typename Tag>
|
||||
struct deref_impl;
|
||||
|
||||
template<>
|
||||
struct deref_impl<proto::tag::proto_expr_iterator>
|
||||
{
|
||||
template<
|
||||
typename Iterator
|
||||
, long Arity = proto::arity_of<typename Iterator::expr_type>::value
|
||||
>
|
||||
struct apply
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::child_c<
|
||||
typename Iterator::expr_type const &
|
||||
, Iterator::index
|
||||
>::type
|
||||
type;
|
||||
|
||||
static type call(Iterator const &iter)
|
||||
{
|
||||
return proto::child_c<Iterator::index>(iter.expr);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
struct apply<Iterator, 0>
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::value<
|
||||
typename Iterator::expr_type const &
|
||||
>::type
|
||||
type;
|
||||
|
||||
static type call(Iterator const &iter)
|
||||
{
|
||||
return proto::value(iter.expr);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct advance_impl;
|
||||
|
||||
template<>
|
||||
struct advance_impl<proto::tag::proto_expr_iterator>
|
||||
{
|
||||
template<typename Iterator, typename N>
|
||||
struct apply
|
||||
{
|
||||
typedef
|
||||
typename proto::detail::expr_iterator<
|
||||
typename Iterator::expr_type
|
||||
, Iterator::index + N::value
|
||||
>
|
||||
type;
|
||||
|
||||
static type call(Iterator const &iter)
|
||||
{
|
||||
return type(iter.expr);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct distance_impl;
|
||||
|
||||
template<>
|
||||
struct distance_impl<proto::tag::proto_expr_iterator>
|
||||
{
|
||||
template<typename IteratorFrom, typename IteratorTo>
|
||||
struct apply
|
||||
: mpl::long_<IteratorTo::index - IteratorFrom::index>
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct next_impl;
|
||||
|
||||
template<>
|
||||
struct next_impl<proto::tag::proto_expr_iterator>
|
||||
{
|
||||
template<typename Iterator>
|
||||
struct apply
|
||||
: advance_impl<proto::tag::proto_expr_iterator>::template apply<Iterator, mpl::long_<1> >
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct prior_impl;
|
||||
|
||||
template<>
|
||||
struct prior_impl<proto::tag::proto_expr_iterator>
|
||||
{
|
||||
template<typename Iterator>
|
||||
struct apply
|
||||
: advance_impl<proto::tag::proto_expr_iterator>::template apply<Iterator, mpl::long_<-1> >
|
||||
{};
|
||||
};
|
||||
|
||||
#if BOOST_VERSION >= 103500
|
||||
template<typename Tag>
|
||||
struct category_of_impl;
|
||||
|
||||
template<>
|
||||
struct category_of_impl<proto::tag::proto_expr>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
{
|
||||
typedef random_access_traversal_tag type;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename Tag>
|
||||
struct size_impl;
|
||||
|
||||
template<>
|
||||
struct size_impl<proto::tag::proto_expr>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: mpl::long_<0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c>
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct begin_impl;
|
||||
|
||||
template<>
|
||||
struct begin_impl<proto::tag::proto_expr>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
{
|
||||
typedef proto::detail::expr_iterator<Sequence, 0> type;
|
||||
|
||||
static type call(Sequence const &seq)
|
||||
{
|
||||
return type(seq);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct end_impl;
|
||||
|
||||
template<>
|
||||
struct end_impl<proto::tag::proto_expr>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
{
|
||||
typedef
|
||||
proto::detail::expr_iterator<
|
||||
Sequence
|
||||
, 0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c
|
||||
>
|
||||
type;
|
||||
|
||||
static type call(Sequence const &seq)
|
||||
{
|
||||
return type(seq);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct value_at_impl;
|
||||
|
||||
template<>
|
||||
struct value_at_impl<proto::tag::proto_expr>
|
||||
{
|
||||
template<
|
||||
typename Sequence
|
||||
, typename Index
|
||||
, long Arity = proto::arity_of<Sequence>::value
|
||||
>
|
||||
struct apply
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::child_c<
|
||||
Sequence
|
||||
, Index::value
|
||||
>::value_type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename Sequence, typename Index>
|
||||
struct apply<Sequence, Index, 0>
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::value<
|
||||
Sequence
|
||||
>::value_type
|
||||
type;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct at_impl;
|
||||
|
||||
template<>
|
||||
struct at_impl<proto::tag::proto_expr>
|
||||
{
|
||||
template<
|
||||
typename Sequence
|
||||
, typename Index
|
||||
, long Arity = proto::arity_of<Sequence>::value
|
||||
>
|
||||
struct apply
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::child_c<
|
||||
Sequence &
|
||||
, Index::value
|
||||
>::type
|
||||
type;
|
||||
|
||||
static type call(Sequence &seq)
|
||||
{
|
||||
return proto::child_c<Index::value>(seq);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Sequence, typename Index>
|
||||
struct apply<Sequence, Index, 0>
|
||||
{
|
||||
typedef
|
||||
typename proto::result_of::value<
|
||||
Sequence &
|
||||
>::type
|
||||
type;
|
||||
|
||||
static type call(Sequence &seq)
|
||||
{
|
||||
return proto::value(seq);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#if BOOST_VERSION >= 103500
|
||||
template<typename Tag>
|
||||
struct is_segmented_impl;
|
||||
|
||||
template<>
|
||||
struct is_segmented_impl<proto::tag::proto_flat_view>
|
||||
{
|
||||
template<typename Iterator>
|
||||
struct apply
|
||||
: mpl::true_
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct segments_impl;
|
||||
|
||||
template<>
|
||||
struct segments_impl<proto::tag::proto_flat_view>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
{
|
||||
typedef typename Sequence::proto_tag proto_tag;
|
||||
|
||||
typedef fusion::transform_view<
|
||||
typename Sequence::expr_type
|
||||
, proto::detail::as_element<proto_tag>
|
||||
> type;
|
||||
|
||||
static type call(Sequence &sequence)
|
||||
{
|
||||
return type(sequence.expr_, proto::detail::as_element<proto_tag>());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct category_of_impl<proto::tag::proto_flat_view>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
{
|
||||
typedef forward_traversal_tag type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct begin_impl<proto::tag::proto_flat_view>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: fusion::segmented_begin<Sequence>
|
||||
{};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct end_impl<proto::tag::proto_flat_view>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: fusion::segmented_end<Sequence>
|
||||
{};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct size_impl<proto::tag::proto_flat_view>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: fusion::segmented_size<Sequence>
|
||||
{};
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
namespace boost { namespace mpl
|
||||
{
|
||||
template<typename Tag, typename Args, long Arity>
|
||||
struct sequence_tag< proto::expr<Tag, Args, Arity> >
|
||||
{
|
||||
typedef fusion::fusion_sequence_tag type;
|
||||
};
|
||||
}}
|
||||
|
||||
#endif // BOOST_PROTO_BUILDING_DOCS
|
||||
|
||||
#undef UNREF
|
||||
|
||||
#if BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
377
libraries/include/boost/proto/generate.hpp
Normal file
377
libraries/include/boost/proto/generate.hpp
Normal file
@@ -0,0 +1,377 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file generate.hpp
|
||||
/// Contains definition of generate\<\> class template, which end users can
|
||||
/// specialize for generating domain-specific expression wrappers.
|
||||
//
|
||||
// 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_PROTO_GENERATE_HPP_EAN_02_13_2007
|
||||
#define BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/args.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Expr>
|
||||
struct expr_params;
|
||||
|
||||
template<typename Tag, typename Args, long N>
|
||||
struct expr_params<proto::expr<Tag, Args, N> >
|
||||
{
|
||||
typedef Tag tag;
|
||||
typedef Args args;
|
||||
BOOST_STATIC_CONSTANT(long, arity = N);
|
||||
};
|
||||
|
||||
template<typename Expr, long Arity = expr_params<Expr>::arity>
|
||||
struct by_value_generator_;
|
||||
|
||||
#define BOOST_PROTO_DEFINE_BY_VALUE_TYPE(Z, N, Expr) \
|
||||
typename uncvref<typename expr_params<Expr>::args::BOOST_PP_CAT(child, N)>::type \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_DEFINE_BY_VALUE(Z, N, expr) \
|
||||
expr.BOOST_PP_CAT(child, N) \
|
||||
/**/
|
||||
|
||||
template<typename Expr>
|
||||
struct by_value_generator_<Expr, 0>
|
||||
{
|
||||
typedef
|
||||
proto::expr<
|
||||
typename expr_params<Expr>::tag
|
||||
, term<typename detail::term_traits<typename expr_params<Expr>::args::child0>::value_type>
|
||||
>
|
||||
type;
|
||||
|
||||
static type const make(Expr const &expr)
|
||||
{
|
||||
type that = {expr.child0};
|
||||
return that;
|
||||
}
|
||||
};
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/generate.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_PROTO_DEFINE_BY_VALUE
|
||||
#undef BOOST_PROTO_DEFINE_BY_VALUE_TYPE
|
||||
|
||||
}
|
||||
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(generatorns_)
|
||||
|
||||
/// \brief A simple generator that passes an expression
|
||||
/// through unchanged.
|
||||
///
|
||||
/// Generators are intended for use as the first template parameter
|
||||
/// to the \c domain\<\> class template and control if and how
|
||||
/// expressions within that domain are to be customized.
|
||||
/// The \c default_generator makes no modifications to the expressions
|
||||
/// passed to it.
|
||||
struct default_generator
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef Expr type;
|
||||
};
|
||||
|
||||
/// \param expr A Proto expression
|
||||
/// \return expr
|
||||
template<typename Expr>
|
||||
#ifdef BOOST_HAS_DECLTYPE
|
||||
Expr
|
||||
#else
|
||||
Expr const &
|
||||
#endif
|
||||
operator ()(Expr const &expr) const
|
||||
{
|
||||
return expr;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A generator that wraps expressions passed
|
||||
/// to it in the specified extension wrapper.
|
||||
///
|
||||
/// Generators are intended for use as the first template parameter
|
||||
/// to the \c domain\<\> class template and control if and how
|
||||
/// expressions within that domain are to be customized.
|
||||
/// \c generator\<\> wraps each expression passed to it in
|
||||
/// the \c Extends\<\> wrapper.
|
||||
template<template<typename> class Extends>
|
||||
struct generator
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef Extends<Expr> type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr &)>
|
||||
{
|
||||
typedef Extends<Expr> type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr const &)>
|
||||
{
|
||||
typedef Extends<Expr> type;
|
||||
};
|
||||
|
||||
/// \param expr A Proto expression
|
||||
/// \return Extends<Expr>(expr)
|
||||
template<typename Expr>
|
||||
Extends<Expr> operator ()(Expr const &expr) const
|
||||
{
|
||||
return Extends<Expr>(expr);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A generator that wraps expressions passed
|
||||
/// to it in the specified extension wrapper and uses
|
||||
/// aggregate initialization for the wrapper.
|
||||
///
|
||||
/// Generators are intended for use as the first template parameter
|
||||
/// to the \c domain\<\> class template and control if and how
|
||||
/// expressions within that domain are to be customized.
|
||||
/// \c pod_generator\<\> wraps each expression passed to it in
|
||||
/// the \c Extends\<\> wrapper, and uses aggregate initialzation
|
||||
/// for the wrapped object.
|
||||
template<template<typename> class Extends>
|
||||
struct pod_generator
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef Extends<Expr> type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr &)>
|
||||
{
|
||||
typedef Extends<Expr> type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr const &)>
|
||||
{
|
||||
typedef Extends<Expr> type;
|
||||
};
|
||||
|
||||
/// \param expr The expression to wrap
|
||||
/// \return <tt>Extends\<Expr\> that = {expr}; return that;</tt>
|
||||
template<typename Expr>
|
||||
Extends<Expr> operator ()(Expr const &expr) const
|
||||
{
|
||||
Extends<Expr> that = {expr};
|
||||
return that;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A generator that replaces child nodes held by
|
||||
/// reference with ones held by value. Use with
|
||||
/// \c compose_generators to forward that result to another
|
||||
/// generator.
|
||||
///
|
||||
/// Generators are intended for use as the first template parameter
|
||||
/// to the \c domain\<\> class template and control if and how
|
||||
/// expressions within that domain are to be customized.
|
||||
/// \c by_value_generator ensures all child nodes are
|
||||
/// held by value. This generator is typically composed with a
|
||||
/// second generator for further processing, as
|
||||
/// <tt>compose_generators\<by_value_generator, MyGenerator\></tt>.
|
||||
struct by_value_generator
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef
|
||||
typename detail::by_value_generator_<Expr>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr &)>
|
||||
{
|
||||
typedef
|
||||
typename detail::by_value_generator_<Expr>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr const &)>
|
||||
{
|
||||
typedef
|
||||
typename detail::by_value_generator_<Expr>::type
|
||||
type;
|
||||
};
|
||||
|
||||
/// \param expr The expression to modify.
|
||||
/// \return <tt>deep_copy(expr)</tt>
|
||||
template<typename Expr>
|
||||
typename result<void(Expr)>::type operator ()(Expr const &expr) const
|
||||
{
|
||||
return detail::by_value_generator_<Expr>::make(expr);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A composite generator that first applies one
|
||||
/// transform to an expression and then forwards the result
|
||||
/// on to another generator for further transformation.
|
||||
///
|
||||
/// Generators are intended for use as the first template parameter
|
||||
/// to the \c domain\<\> class template and control if and how
|
||||
/// expressions within that domain are to be customized.
|
||||
/// \c compose_generators\<\> is a composite generator that first
|
||||
/// applies one transform to an expression and then forwards the
|
||||
/// result on to another generator for further transformation.
|
||||
template<typename First, typename Second>
|
||||
struct compose_generators
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef
|
||||
typename Second::template result<
|
||||
void(typename First::template result<void(Expr)>::type)
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr &)>
|
||||
{
|
||||
typedef
|
||||
typename Second::template result<
|
||||
void(typename First::template result<void(Expr)>::type)
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr const &)>
|
||||
{
|
||||
typedef
|
||||
typename Second::template result<
|
||||
void(typename First::template result<void(Expr)>::type)
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
/// \param expr The expression to modify.
|
||||
/// \return Second()(First()(expr))
|
||||
template<typename Expr>
|
||||
typename result<void(Expr)>::type operator ()(Expr const &expr) const
|
||||
{
|
||||
return Second()(First()(expr));
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(generatorns_)
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<>
|
||||
struct is_callable<default_generator>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<template<typename> class Extends>
|
||||
struct is_callable<generator<Extends> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<template<typename> class Extends>
|
||||
struct is_callable<pod_generator<Extends> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<>
|
||||
struct is_callable<by_value_generator>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename First, typename Second>
|
||||
struct is_callable<compose_generators<First, Second> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
|
||||
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<typename Expr>
|
||||
struct by_value_generator_<Expr, N>
|
||||
{
|
||||
typedef
|
||||
proto::expr<
|
||||
typename expr_params<Expr>::tag
|
||||
, BOOST_PP_CAT(list, N)<
|
||||
// typename uncvref<typename expr_params<Expr>::args::child0>::type, ...
|
||||
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_BY_VALUE_TYPE, Expr)
|
||||
>
|
||||
>
|
||||
type;
|
||||
|
||||
static type const make(Expr const &expr)
|
||||
{
|
||||
type that = {
|
||||
// expr.child0, ...
|
||||
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_BY_VALUE, expr)
|
||||
};
|
||||
return that;
|
||||
}
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
109
libraries/include/boost/proto/literal.hpp
Normal file
109
libraries/include/boost/proto/literal.hpp
Normal file
@@ -0,0 +1,109 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file literal.hpp
|
||||
/// The literal\<\> terminal wrapper, and the proto::lit() function for
|
||||
/// creating literal\<\> wrappers.
|
||||
//
|
||||
// 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_PROTO_LITERAL_HPP_EAN_01_03_2007
|
||||
#define BOOST_PROTO_LITERAL_HPP_EAN_01_03_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/expr.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/extends.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
/// \brief A simple wrapper for a terminal, provided for
|
||||
/// ease of use.
|
||||
///
|
||||
/// A simple wrapper for a terminal, provided for
|
||||
/// ease of use. In all cases, <tt>literal\<X\> l(x);</tt>
|
||||
/// is equivalent to <tt>terminal\<X\>::::type l = {x};</tt>.
|
||||
///
|
||||
/// The \c Domain template parameter defaults to
|
||||
/// \c proto::default_domain.
|
||||
template<
|
||||
typename T
|
||||
, typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain)
|
||||
>
|
||||
struct literal
|
||||
: extends<expr<tag::terminal, term<T> >, literal<T, Domain>, Domain>
|
||||
{
|
||||
private:
|
||||
typedef expr<tag::terminal, term<T> > terminal_type;
|
||||
typedef extends<terminal_type, literal<T, Domain>, Domain> base_type;
|
||||
|
||||
public:
|
||||
typedef typename detail::term_traits<T>::value_type value_type;
|
||||
typedef typename detail::term_traits<T>::reference reference;
|
||||
typedef typename detail::term_traits<T>::const_reference const_reference;
|
||||
|
||||
template<typename U>
|
||||
literal(U &u)
|
||||
: base_type(terminal_type::make(u))
|
||||
{}
|
||||
|
||||
template<typename U>
|
||||
literal(U const &u)
|
||||
: base_type(terminal_type::make(u))
|
||||
{}
|
||||
|
||||
template<typename U>
|
||||
literal(literal<U, Domain> const &u)
|
||||
: base_type(terminal_type::make(u.get()))
|
||||
{}
|
||||
|
||||
using base_type::operator =;
|
||||
|
||||
reference get()
|
||||
{
|
||||
return proto::value(*this);
|
||||
}
|
||||
|
||||
const_reference get() const
|
||||
{
|
||||
return proto::value(*this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief A helper function for creating a \c literal\<\> wrapper.
|
||||
/// \param t The object to wrap.
|
||||
/// \return literal\<T &\>(t)
|
||||
/// \attention The returned value holds the argument by reference.
|
||||
/// \throw nothrow
|
||||
template<typename T>
|
||||
inline literal<T &> const lit(T &t)
|
||||
{
|
||||
return literal<T &>(t);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename T>
|
||||
inline literal<T const &> const lit(T const &t)
|
||||
{
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
|
||||
#endif
|
||||
|
||||
return literal<T const &>(t);
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
1147
libraries/include/boost/proto/make_expr.hpp
Normal file
1147
libraries/include/boost/proto/make_expr.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1044
libraries/include/boost/proto/matches.hpp
Normal file
1044
libraries/include/boost/proto/matches.hpp
Normal file
File diff suppressed because it is too large
Load Diff
446
libraries/include/boost/proto/operators.hpp
Normal file
446
libraries/include/boost/proto/operators.hpp
Normal file
@@ -0,0 +1,446 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file operators.hpp
|
||||
/// Contains all the overloaded operators that make it possible to build
|
||||
/// Proto expression trees.
|
||||
//
|
||||
// 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_PROTO_OPERATORS_HPP_EAN_04_01_2005
|
||||
#define BOOST_PROTO_OPERATORS_HPP_EAN_04_01_2005
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma.hpp>
|
||||
#include <boost/preprocessor/seq/seq.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/tags.hpp>
|
||||
#include <boost/proto/expr.hpp>
|
||||
#include <boost/proto/matches.hpp>
|
||||
#include <boost/proto/generate.hpp>
|
||||
#include <boost/proto/make_expr.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Domain, typename Expr>
|
||||
struct generate_if
|
||||
: lazy_enable_if_c<
|
||||
matches<Expr, typename Domain::proto_grammar>::value
|
||||
, typename Domain::template result<void(Expr)>
|
||||
>
|
||||
{};
|
||||
|
||||
// Optimization, generate fewer templates...
|
||||
template<typename Expr>
|
||||
struct generate_if<proto::default_domain, Expr>
|
||||
{
|
||||
typedef Expr type;
|
||||
};
|
||||
|
||||
template<typename Domain, typename Tag, typename Left, typename Right>
|
||||
struct generate_if_left
|
||||
: lazy_enable_if_c<
|
||||
matches<proto::expr<Tag, proto::list2<Left &, Right> >, typename Domain::proto_grammar>::value
|
||||
, typename Domain::template result<void(
|
||||
proto::expr<Tag, proto::list2<Left &, typename Domain::template result<void(Right)>::type> >
|
||||
)>
|
||||
>
|
||||
{};
|
||||
|
||||
// Optimization, generate fewer templates...
|
||||
template<typename Tag, typename Left, typename Right>
|
||||
struct generate_if_left<proto::default_domain, Tag, Left, Right>
|
||||
{
|
||||
typedef proto::expr<Tag, proto::list2<Left &, Right> > type;
|
||||
};
|
||||
|
||||
template<typename Domain, typename Tag, typename Left, typename Right>
|
||||
struct generate_if_right
|
||||
: lazy_enable_if_c<
|
||||
matches<proto::expr<Tag, proto::list2<Left, Right &> >, typename Domain::proto_grammar>::value
|
||||
, typename Domain::template result<void(
|
||||
proto::expr<Tag, proto::list2<typename Domain::template result<void(Left)>::type, Right &> >
|
||||
)>
|
||||
>
|
||||
{};
|
||||
|
||||
// Optimization, generate fewer templates...
|
||||
template<typename Tag, typename Left, typename Right>
|
||||
struct generate_if_right<proto::default_domain, Tag, Left, Right>
|
||||
{
|
||||
typedef proto::expr<Tag, proto::list2<Left, Right &> > type;
|
||||
};
|
||||
|
||||
template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void>
|
||||
struct as_expr_if2
|
||||
{};
|
||||
|
||||
template<typename Tag, typename Left, typename Right>
|
||||
struct as_expr_if2<Tag, Left, Right, typename Left::proto_is_expr_, void>
|
||||
: generate_if_left<
|
||||
typename Left::proto_domain
|
||||
, Tag
|
||||
, Left
|
||||
, proto::expr<tag::terminal, term<Right &> >
|
||||
>
|
||||
{
|
||||
typedef proto::expr<tag::terminal, term<Right &> > term_type;
|
||||
typedef proto::expr<Tag, list2<Left &, typename Left::proto_domain::template result<void(term_type)>::type> > expr_type;
|
||||
|
||||
static typename Left::proto_domain::template result<void(expr_type)>::type
|
||||
make(Left &left, Right &right)
|
||||
{
|
||||
term_type term = {right};
|
||||
expr_type that = {left, typename Left::proto_domain()(term)};
|
||||
return typename Left::proto_domain()(that);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tag, typename Left, typename Right>
|
||||
struct as_expr_if2<Tag, Left, Right, void, typename Right::proto_is_expr_>
|
||||
: generate_if_right<
|
||||
typename Right::proto_domain
|
||||
, Tag
|
||||
, proto::expr<tag::terminal, term<Left &> >
|
||||
, Right
|
||||
>
|
||||
{
|
||||
typedef proto::expr<tag::terminal, term<Left &> > term_type;
|
||||
typedef proto::expr<Tag, list2<typename Right::proto_domain::template result<void(term_type)>::type, Right &> > expr_type;
|
||||
|
||||
static typename Right::proto_domain::template result<void(expr_type)>::type
|
||||
make(Left &left, Right &right)
|
||||
{
|
||||
term_type term = {left};
|
||||
expr_type that = {typename Right::proto_domain()(term), right};
|
||||
return typename Right::proto_domain()(that);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void>
|
||||
struct as_expr_if
|
||||
: as_expr_if2<Tag, Left, Right>
|
||||
{};
|
||||
|
||||
template<typename Tag, typename Left, typename Right>
|
||||
struct as_expr_if<Tag, Left, Right, typename Left::proto_is_expr_, typename Right::proto_is_expr_>
|
||||
: generate_if<
|
||||
typename Left::proto_domain
|
||||
, proto::expr<Tag, list2<Left &, Right &> >
|
||||
>
|
||||
{
|
||||
typedef proto::expr<Tag, list2<Left &, Right &> > expr_type;
|
||||
BOOST_MPL_ASSERT((is_same<typename Left::proto_domain, typename Right::proto_domain>));
|
||||
|
||||
static typename Left::proto_domain::template result<void(expr_type)>::type
|
||||
make(Left &left, Right &right)
|
||||
{
|
||||
expr_type that = {left, right};
|
||||
return typename Left::proto_domain()(that);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Arg, typename Trait, typename Enable = void>
|
||||
struct arg_weight
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = 1 + Trait::value);
|
||||
};
|
||||
|
||||
template<typename Arg, typename Trait>
|
||||
struct arg_weight<Arg, Trait, typename Arg::proto_is_expr_>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = 0);
|
||||
};
|
||||
|
||||
template<typename Domain, typename Trait, typename Arg, typename Expr>
|
||||
struct enable_unary
|
||||
: boost::enable_if<
|
||||
boost::mpl::and_<Trait, boost::proto::matches<Expr, typename Domain::proto_grammar> >
|
||||
, Expr
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Trait, typename Arg, typename Expr>
|
||||
struct enable_unary<deduce_domain, Trait, Arg, Expr>
|
||||
: boost::enable_if<
|
||||
boost::mpl::and_<
|
||||
Trait
|
||||
, boost::proto::matches<Expr, typename domain_of<Arg>::type::proto_grammar>
|
||||
>
|
||||
, Expr
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Trait, typename Arg, typename Expr>
|
||||
struct enable_unary<default_domain, Trait, Arg, Expr>
|
||||
: boost::enable_if<Trait, Expr>
|
||||
{};
|
||||
|
||||
template<typename Domain, typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
|
||||
struct enable_binary
|
||||
: boost::enable_if<
|
||||
boost::mpl::and_<
|
||||
mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))>
|
||||
, boost::proto::matches<Expr, typename Domain::proto_grammar>
|
||||
>
|
||||
, Expr
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
|
||||
struct enable_binary<deduce_domain, Trait1, Arg1, Trait2, Arg2, Expr>
|
||||
: boost::enable_if<
|
||||
boost::mpl::and_<
|
||||
mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))>
|
||||
, boost::proto::matches<Expr, typename deduce_domain2<Arg1, Arg2>::type::proto_grammar>
|
||||
>
|
||||
, Expr
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
|
||||
struct enable_binary<default_domain, Trait1, Arg1, Trait2, Arg2, Expr>
|
||||
: boost::enable_if_c<
|
||||
(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))
|
||||
, Expr
|
||||
>
|
||||
{};
|
||||
|
||||
} // detail
|
||||
|
||||
#define BOOST_PROTO_UNARY_OP_IS_POSTFIX_0
|
||||
#define BOOST_PROTO_UNARY_OP_IS_POSTFIX_1 , int
|
||||
|
||||
#define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, POST) \
|
||||
template<typename Arg> \
|
||||
typename detail::generate_if< \
|
||||
typename Arg::proto_domain \
|
||||
, proto::expr<TAG, list1<typename Arg::proto_derived_expr &> > \
|
||||
>::type const \
|
||||
operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
|
||||
{ \
|
||||
typedef proto::expr<TAG, list1<typename Arg::proto_derived_expr &> > that_type; \
|
||||
that_type that = {arg}; \
|
||||
return typename Arg::proto_domain()(that); \
|
||||
} \
|
||||
template<typename Arg> \
|
||||
typename detail::generate_if< \
|
||||
typename Arg::proto_domain \
|
||||
, proto::expr<TAG, list1<typename Arg::proto_derived_expr const &> > \
|
||||
>::type const \
|
||||
operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
|
||||
{ \
|
||||
typedef proto::expr<TAG, list1<typename Arg::proto_derived_expr const &> > that_type; \
|
||||
that_type that = {arg}; \
|
||||
return typename Arg::proto_domain()(that); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG) \
|
||||
template<typename Left, typename Right> \
|
||||
inline typename detail::as_expr_if<TAG, Left, Right>::type const \
|
||||
operator OP(Left &left, Right &right) \
|
||||
{ \
|
||||
return detail::as_expr_if<TAG, Left, Right>::make(left, right); \
|
||||
} \
|
||||
template<typename Left, typename Right> \
|
||||
inline typename detail::as_expr_if<TAG, Left, Right const>::type const \
|
||||
operator OP(Left &left, Right const &right) \
|
||||
{ \
|
||||
return detail::as_expr_if<TAG, Left, Right const>::make(left, right); \
|
||||
} \
|
||||
template<typename Left, typename Right> \
|
||||
inline typename detail::as_expr_if<TAG, Left const, Right>::type const \
|
||||
operator OP(Left const &left, Right &right) \
|
||||
{ \
|
||||
return detail::as_expr_if<TAG, Left const, Right>::make(left, right); \
|
||||
} \
|
||||
template<typename Left, typename Right> \
|
||||
inline typename detail::as_expr_if<TAG, Left const, Right const>::type const \
|
||||
operator OP(Left const &left, Right const &right) \
|
||||
{ \
|
||||
return detail::as_expr_if<TAG, Left const, Right const>::make(left, right); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(exprns_)
|
||||
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(+, tag::unary_plus, 0)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(-, tag::negate, 0)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(*, tag::dereference, 0)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(~, tag::complement, 0)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(&, tag::address_of, 0)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(!, tag::logical_not, 0)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, tag::pre_inc, 0)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, tag::pre_dec, 0)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, tag::post_inc, 1)
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, tag::post_dec, 1)
|
||||
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<, tag::shift_left)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>, tag::shift_right)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(*, tag::multiplies)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(/, tag::divides)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(%, tag::modulus)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(+, tag::plus)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(-, tag::minus)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(<, tag::less)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(>, tag::greater)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(<=, tag::less_equal)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(>=, tag::greater_equal)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(==, tag::equal_to)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(!=, tag::not_equal_to)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(||, tag::logical_or)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(&&, tag::logical_and)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(&, tag::bitwise_and)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(|, tag::bitwise_or)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(^, tag::bitwise_xor)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(BOOST_PP_COMMA(), tag::comma)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(->*, tag::mem_ptr)
|
||||
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<=, tag::shift_left_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>=, tag::shift_right_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(*=, tag::multiplies_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(/=, tag::divides_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(%=, tag::modulus_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(+=, tag::plus_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(-=, tag::minus_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(&=, tag::bitwise_and_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(|=, tag::bitwise_or_assign)
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(^=, tag::bitwise_xor_assign)
|
||||
|
||||
/// if_else
|
||||
///
|
||||
BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
|
||||
3
|
||||
, if_else
|
||||
, deduce_domain
|
||||
, (tag::if_else_)
|
||||
, BOOST_PP_SEQ_NIL
|
||||
)
|
||||
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(exprns_)
|
||||
|
||||
BOOST_PROTO_WHEN_NOT_BUILDING_DOCS(using exprns_::if_else;)
|
||||
|
||||
#undef BOOST_PROTO_DEFINE_UNARY_OPERATOR
|
||||
#undef BOOST_PROTO_DEFINE_BINARY_OPERATOR
|
||||
|
||||
#define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, TRAIT, DOMAIN, POST) \
|
||||
template<typename Arg> \
|
||||
typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
|
||||
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg &>::type \
|
||||
>::type const \
|
||||
operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
|
||||
{ \
|
||||
return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(arg)); \
|
||||
} \
|
||||
template<typename Arg> \
|
||||
typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
|
||||
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg const &>::type \
|
||||
>::type const \
|
||||
operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
|
||||
{ \
|
||||
return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(arg)); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG, TRAIT, DOMAIN) \
|
||||
template<typename Left, typename Right> \
|
||||
typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
|
||||
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left &, Right &>::type \
|
||||
>::type const \
|
||||
operator OP(Left &left, Right &right) \
|
||||
{ \
|
||||
return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
|
||||
} \
|
||||
template<typename Left, typename Right> \
|
||||
typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
|
||||
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left &, Right const &>::type \
|
||||
>::type const \
|
||||
operator OP(Left &left, Right const &right) \
|
||||
{ \
|
||||
return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
|
||||
} \
|
||||
template<typename Left, typename Right> \
|
||||
typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
|
||||
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const &, Right &>::type \
|
||||
>::type const \
|
||||
operator OP(Left const &left, Right &right) \
|
||||
{ \
|
||||
return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
|
||||
} \
|
||||
template<typename Left, typename Right> \
|
||||
typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
|
||||
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const &, Right const &>::type\
|
||||
>::type const \
|
||||
operator OP(Left const &left, Right const &right) \
|
||||
{ \
|
||||
return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_DEFINE_OPERATORS(TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(+, boost::proto::tag::unary_plus, TRAIT, DOMAIN, 0) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(-, boost::proto::tag::negate, TRAIT, DOMAIN, 0) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(*, boost::proto::tag::dereference, TRAIT, DOMAIN, 0) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(~, boost::proto::tag::complement, TRAIT, DOMAIN, 0) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(&, boost::proto::tag::address_of, TRAIT, DOMAIN, 0) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(!, boost::proto::tag::logical_not, TRAIT, DOMAIN, 0) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, boost::proto::tag::pre_inc, TRAIT, DOMAIN, 0) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, boost::proto::tag::pre_dec, TRAIT, DOMAIN, 0) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, boost::proto::tag::post_inc, TRAIT, DOMAIN, 1) \
|
||||
BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, boost::proto::tag::post_dec, TRAIT, DOMAIN, 1) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<, boost::proto::tag::shift_left, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>, boost::proto::tag::shift_right, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(*, boost::proto::tag::multiplies, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(/, boost::proto::tag::divides, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(%, boost::proto::tag::modulus, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(+, boost::proto::tag::plus, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(-, boost::proto::tag::minus, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(<, boost::proto::tag::less, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(>, boost::proto::tag::greater, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(<=, boost::proto::tag::less_equal, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(>=, boost::proto::tag::greater_equal, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(==, boost::proto::tag::equal_to, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(!=, boost::proto::tag::not_equal_to, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(||, boost::proto::tag::logical_or, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(&&, boost::proto::tag::logical_and, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(&, boost::proto::tag::bitwise_and, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(|, boost::proto::tag::bitwise_or, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(^, boost::proto::tag::bitwise_xor, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(BOOST_PP_COMMA(), boost::proto::tag::comma, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(->*, boost::proto::tag::mem_ptr, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<=, boost::proto::tag::shift_left_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>=, boost::proto::tag::shift_right_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(*=, boost::proto::tag::multiplies_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(/=, boost::proto::tag::divides_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(%=, boost::proto::tag::modulus_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(+=, boost::proto::tag::plus_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(-=, boost::proto::tag::minus_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(&=, boost::proto::tag::bitwise_and_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(|=, boost::proto::tag::bitwise_or_assign, TRAIT, DOMAIN) \
|
||||
BOOST_PROTO_DEFINE_BINARY_OPERATOR(^=, boost::proto::tag::bitwise_xor_assign, TRAIT, DOMAIN) \
|
||||
/**/
|
||||
|
||||
template<typename T>
|
||||
struct is_extension
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
#ifndef BOOST_PROTO_BUILDING_DOCS
|
||||
namespace exops
|
||||
{
|
||||
BOOST_PROTO_DEFINE_OPERATORS(is_extension, default_domain)
|
||||
using proto::if_else;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
19
libraries/include/boost/proto/proto.hpp
Normal file
19
libraries/include/boost/proto/proto.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file proto.hpp
|
||||
/// Includes all of Proto.
|
||||
//
|
||||
// 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_PROTO_HPP_EAN_04_01_2005
|
||||
#define BOOST_PROTO_HPP_EAN_04_01_2005
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/proto/core.hpp>
|
||||
#include <boost/proto/debug.hpp>
|
||||
#include <boost/proto/context.hpp>
|
||||
#include <boost/proto/transform.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
#endif
|
||||
773
libraries/include/boost/proto/proto_fwd.hpp
Normal file
773
libraries/include/boost/proto/proto_fwd.hpp
Normal file
@@ -0,0 +1,773 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file proto_fwd.hpp
|
||||
/// Forward declarations of all of proto's public types and functions.
|
||||
//
|
||||
// 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_PROTO_FWD_HPP_EAN_04_01_2005
|
||||
#define BOOST_PROTO_FWD_HPP_EAN_04_01_2005
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp> // must be first include
|
||||
#include <cstddef>
|
||||
#include <climits>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/mpl/long.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
#ifndef BOOST_PROTO_MAX_ARITY
|
||||
# define BOOST_PROTO_MAX_ARITY 5
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_MAX_LOGICAL_ARITY
|
||||
# define BOOST_PROTO_MAX_LOGICAL_ARITY 8
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_MAX_FUNCTION_CALL_ARITY
|
||||
# define BOOST_PROTO_MAX_FUNCTION_CALL_ARITY BOOST_PROTO_MAX_ARITY
|
||||
#endif
|
||||
|
||||
#if BOOST_PROTO_MAX_ARITY < 3
|
||||
# error BOOST_PROTO_MAX_ARITY must be at least 3
|
||||
#endif
|
||||
|
||||
#if BOOST_PROTO_MAX_FUNCTION_CALL_ARITY > BOOST_PROTO_MAX_ARITY
|
||||
# error BOOST_PROTO_MAX_FUNCTION_CALL_ARITY cannot be larger than BOOST_PROTO_MAX_ARITY
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_BROKEN_CONST_OVERLOADS
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 3) \
|
||||
|| BOOST_WORKAROUND(__EDG_VERSION__, BOOST_TESTED_AT(306))
|
||||
# define BOOST_PROTO_BROKEN_CONST_OVERLOADS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_PROTO_BROKEN_CONST_OVERLOADS
|
||||
# include <boost/utility/enable_if.hpp>
|
||||
# include <boost/type_traits/is_const.hpp>
|
||||
# define BOOST_PROTO_DISABLE_IF_IS_CONST(T)\
|
||||
, typename boost::disable_if<boost::is_const<T>, boost::proto::detail::undefined>::type * = 0
|
||||
#else
|
||||
# define BOOST_PROTO_DISABLE_IF_IS_CONST(T)
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PROTO_BROKEN_PTS
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
|
||||
# define BOOST_PROTO_BROKEN_PTS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if BOOST_VERSION < 103500
|
||||
#define BOOST_PROTO_FUSION_DEFINE_TAG(X) typedef X tag;
|
||||
#define BOOST_PROTO_FUSION_DEFINE_CATEGORY(X)
|
||||
#define BOOST_PROTO_FUSION_RESULT_OF meta
|
||||
#define BOOST_PROTO_FUSION_EXTENSION meta
|
||||
#define BOOST_PROTO_FUSION_AT_C(N, X) at<N>(X)
|
||||
#else
|
||||
#define BOOST_PROTO_FUSION_DEFINE_TAG(X) typedef X fusion_tag;
|
||||
#define BOOST_PROTO_FUSION_DEFINE_CATEGORY(X) typedef X category;
|
||||
#define BOOST_PROTO_FUSION_RESULT_OF result_of
|
||||
#define BOOST_PROTO_FUSION_EXTENSION extension
|
||||
#define BOOST_PROTO_FUSION_AT_C(N, X) at_c<N>(X)
|
||||
#endif
|
||||
|
||||
#include <boost/proto/detail/suffix.hpp> // must be last include
|
||||
|
||||
#ifdef BOOST_PROTO_BUILDING_DOCS
|
||||
// HACKHACK so Doxygen shows inheritance from mpl::true_ and mpl::false_
|
||||
namespace boost
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
namespace mpl
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
struct true_ {};
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
struct false_ {};
|
||||
}
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
namespace fusion
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Function>
|
||||
class unfused_generic {};
|
||||
}
|
||||
}
|
||||
#define BOOST_PROTO_WHEN_BUILDING_DOCS(x) x
|
||||
#define BOOST_PROTO_WHEN_NOT_BUILDING_DOCS(x)
|
||||
#define BOOST_PROTO_BEGIN_ADL_NAMESPACE(x)
|
||||
#define BOOST_PROTO_END_ADL_NAMESPACE(x)
|
||||
#else
|
||||
#define BOOST_PROTO_WHEN_BUILDING_DOCS(x)
|
||||
#define BOOST_PROTO_WHEN_NOT_BUILDING_DOCS(x) x
|
||||
#define BOOST_PROTO_BEGIN_ADL_NAMESPACE(x) namespace x {
|
||||
#define BOOST_PROTO_END_ADL_NAMESPACE(x) }
|
||||
#endif
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
typedef char yes_type;
|
||||
typedef char (&no_type)[2];
|
||||
|
||||
struct dont_care;
|
||||
struct undefined; // leave this undefined
|
||||
|
||||
struct private_type_
|
||||
{
|
||||
private_type_ const &operator ,(int) const;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct uncvref
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct uncvref<T const>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct uncvref<T &>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct uncvref<T const &>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
struct ignore
|
||||
{
|
||||
ignore()
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
ignore(T const &)
|
||||
{}
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
#define BOOST_PROTO_UNCVREF(X) \
|
||||
typename boost::remove_const<typename boost::remove_reference<X>::type>::type
|
||||
}
|
||||
|
||||
typedef detail::ignore const ignore;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Operator tags
|
||||
namespace tag
|
||||
{
|
||||
struct terminal;
|
||||
struct unary_plus;
|
||||
struct negate;
|
||||
struct dereference;
|
||||
struct complement;
|
||||
struct address_of;
|
||||
struct logical_not;
|
||||
struct pre_inc;
|
||||
struct pre_dec;
|
||||
struct post_inc;
|
||||
struct post_dec;
|
||||
|
||||
struct shift_left;
|
||||
struct shift_right;
|
||||
struct multiplies;
|
||||
struct divides;
|
||||
struct modulus;
|
||||
struct plus;
|
||||
struct minus;
|
||||
struct less;
|
||||
struct greater;
|
||||
struct less_equal;
|
||||
struct greater_equal;
|
||||
struct equal_to;
|
||||
struct not_equal_to;
|
||||
struct logical_or;
|
||||
struct logical_and;
|
||||
struct bitwise_and;
|
||||
struct bitwise_or;
|
||||
struct bitwise_xor;
|
||||
struct comma;
|
||||
struct mem_ptr;
|
||||
|
||||
struct assign;
|
||||
struct shift_left_assign;
|
||||
struct shift_right_assign;
|
||||
struct multiplies_assign;
|
||||
struct divides_assign;
|
||||
struct modulus_assign;
|
||||
struct plus_assign;
|
||||
struct minus_assign;
|
||||
struct bitwise_and_assign;
|
||||
struct bitwise_or_assign;
|
||||
struct bitwise_xor_assign;
|
||||
struct subscript;
|
||||
struct member;
|
||||
struct if_else_;
|
||||
struct function;
|
||||
|
||||
// Fusion tags
|
||||
struct proto_expr;
|
||||
struct proto_expr_iterator;
|
||||
struct proto_flat_view;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(wildcardns_)
|
||||
struct _;
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(wildcardns_)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_PROTO_BUILDING_DOCS
|
||||
using wildcardns_::_;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(generatorns_)
|
||||
struct default_generator;
|
||||
|
||||
template<template<typename> class Extends>
|
||||
struct generator;
|
||||
|
||||
template<template<typename> class Extends>
|
||||
struct pod_generator;
|
||||
|
||||
struct by_value_generator;
|
||||
|
||||
template<typename First, typename Second>
|
||||
struct compose_generators;
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(generatorns_)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_PROTO_BUILDING_DOCS
|
||||
using generatorns_::default_generator;
|
||||
using generatorns_::generator;
|
||||
using generatorns_::pod_generator;
|
||||
using generatorns_::by_value_generator;
|
||||
using generatorns_::compose_generators;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(domainns_)
|
||||
template<typename Generator = default_generator, typename Grammar = proto::_>
|
||||
struct domain;
|
||||
|
||||
struct default_domain;
|
||||
|
||||
struct deduce_domain;
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(domainns_)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_PROTO_BUILDING_DOCS
|
||||
using domainns_::domain;
|
||||
using domainns_::default_domain;
|
||||
using domainns_::deduce_domain;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_PROTO_BEGIN_ADL_NAMESPACE(exprns_)
|
||||
template<typename Tag, typename Args, long Arity = Args::arity>
|
||||
struct expr;
|
||||
|
||||
template<
|
||||
typename Expr
|
||||
, typename Derived
|
||||
, typename Domain = default_domain
|
||||
, long Arity = Expr::proto_arity_c
|
||||
>
|
||||
struct extends;
|
||||
|
||||
template<typename This, typename Fun, typename Domain>
|
||||
struct virtual_member;
|
||||
|
||||
struct is_proto_expr;
|
||||
BOOST_PROTO_END_ADL_NAMESPACE(exprns_)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_PROTO_BUILDING_DOCS
|
||||
using exprns_::expr;
|
||||
using exprns_::extends;
|
||||
using exprns_::is_proto_expr;
|
||||
#endif
|
||||
|
||||
namespace control
|
||||
{
|
||||
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G, void)>
|
||||
struct or_;
|
||||
|
||||
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G, void)>
|
||||
struct and_;
|
||||
|
||||
template<typename Grammar>
|
||||
struct not_;
|
||||
|
||||
template<typename Condition, typename Then = _, typename Else = not_<_> >
|
||||
struct if_;
|
||||
|
||||
template<typename Cases>
|
||||
struct switch_;
|
||||
|
||||
template<typename T>
|
||||
struct exact;
|
||||
|
||||
template<typename T>
|
||||
struct convertible_to;
|
||||
|
||||
template<typename Grammar>
|
||||
struct vararg;
|
||||
|
||||
int const N = INT_MAX;
|
||||
}
|
||||
|
||||
using control::if_;
|
||||
using control::or_;
|
||||
using control::and_;
|
||||
using control::not_;
|
||||
using control::switch_;
|
||||
using control::exact;
|
||||
using control::convertible_to;
|
||||
using control::vararg;
|
||||
using control::N;
|
||||
|
||||
namespace context
|
||||
{
|
||||
struct null_context;
|
||||
|
||||
template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
|
||||
struct null_eval;
|
||||
|
||||
struct default_context;
|
||||
|
||||
template<typename Expr, typename Context, typename Tag = typename Expr::proto_tag, long Arity = Expr::proto_arity_c>
|
||||
struct default_eval;
|
||||
|
||||
template<typename Derived, typename DefaultCtx = default_context>
|
||||
struct callable_context;
|
||||
|
||||
template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
|
||||
struct callable_eval;
|
||||
}
|
||||
|
||||
using context::null_context;
|
||||
using context::null_eval;
|
||||
using context::default_context;
|
||||
using context::default_eval;
|
||||
using context::callable_context;
|
||||
using context::callable_eval;
|
||||
|
||||
namespace utility
|
||||
{
|
||||
template<typename T, typename Domain = default_domain>
|
||||
struct literal;
|
||||
}
|
||||
|
||||
using utility::literal;
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
template<
|
||||
typename T
|
||||
, typename Domain = default_domain
|
||||
, typename Void = void
|
||||
#ifdef BOOST_PROTO_BROKEN_PTS
|
||||
, typename Void2 = void
|
||||
#endif
|
||||
>
|
||||
struct as_expr;
|
||||
|
||||
template<
|
||||
typename T
|
||||
, typename Domain = default_domain
|
||||
, typename Void = void
|
||||
#ifdef BOOST_PROTO_BROKEN_PTS
|
||||
, typename Void2 = void
|
||||
#endif
|
||||
>
|
||||
struct as_child;
|
||||
|
||||
template<typename Expr, typename N = mpl::long_<0> >
|
||||
struct child;
|
||||
|
||||
template<typename Expr, long N>
|
||||
struct child_c;
|
||||
|
||||
template<typename Expr>
|
||||
struct left;
|
||||
|
||||
template<typename Expr>
|
||||
struct right;
|
||||
|
||||
template<typename Expr>
|
||||
struct deep_copy;
|
||||
|
||||
template<typename Expr, typename Context>
|
||||
struct eval;
|
||||
|
||||
template<
|
||||
typename Tag
|
||||
, typename DomainOrA0
|
||||
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
|
||||
BOOST_PROTO_MAX_ARITY
|
||||
, typename A
|
||||
, = void BOOST_PP_INTERCEPT
|
||||
)
|
||||
, typename Void = void
|
||||
>
|
||||
struct make_expr;
|
||||
|
||||
template<typename Tag, typename DomainOrSequence, typename SequenceOrVoid = void, typename Void = void>
|
||||
struct unpack_expr;
|
||||
|
||||
template<typename T, typename Void = void>
|
||||
struct is_expr;
|
||||
|
||||
template<typename T, typename Void = void>
|
||||
struct is_domain;
|
||||
|
||||
template<typename Expr>
|
||||
struct tag_of;
|
||||
|
||||
template<typename Expr>
|
||||
struct arity_of;
|
||||
|
||||
template<typename T, typename Void = void>
|
||||
struct domain_of;
|
||||
|
||||
template<typename Expr, typename Grammar>
|
||||
struct matches;
|
||||
}
|
||||
|
||||
using result_of::is_expr;
|
||||
using result_of::is_domain;
|
||||
using result_of::tag_of;
|
||||
using result_of::arity_of;
|
||||
using result_of::domain_of;
|
||||
using result_of::matches;
|
||||
|
||||
namespace op
|
||||
{
|
||||
// Generic expression metafunctions and
|
||||
// grammar elements
|
||||
template<typename Tag, typename Arg>
|
||||
struct unary_expr;
|
||||
|
||||
template<typename Tag, typename Left, typename Right>
|
||||
struct binary_expr;
|
||||
|
||||
template<typename Tag, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
|
||||
struct nary_expr;
|
||||
|
||||
// Specific expression metafunctions and
|
||||
// grammar elements, for convenience
|
||||
template<typename T> struct terminal;
|
||||
template<typename T> struct unary_plus;
|
||||
template<typename T> struct negate;
|
||||
template<typename T> struct dereference;
|
||||
template<typename T> struct complement;
|
||||
template<typename T> struct address_of;
|
||||
template<typename T> struct logical_not;
|
||||
template<typename T> struct pre_inc;
|
||||
template<typename T> struct pre_dec;
|
||||
template<typename T> struct post_inc;
|
||||
template<typename T> struct post_dec;
|
||||
|
||||
template<typename T, typename U> struct shift_left;
|
||||
template<typename T, typename U> struct shift_right;
|
||||
template<typename T, typename U> struct multiplies;
|
||||
template<typename T, typename U> struct divides;
|
||||
template<typename T, typename U> struct modulus;
|
||||
template<typename T, typename U> struct plus;
|
||||
template<typename T, typename U> struct minus;
|
||||
template<typename T, typename U> struct less;
|
||||
template<typename T, typename U> struct greater;
|
||||
template<typename T, typename U> struct less_equal;
|
||||
template<typename T, typename U> struct greater_equal;
|
||||
template<typename T, typename U> struct equal_to;
|
||||
template<typename T, typename U> struct not_equal_to;
|
||||
template<typename T, typename U> struct logical_or;
|
||||
template<typename T, typename U> struct logical_and;
|
||||
template<typename T, typename U> struct bitwise_and;
|
||||
template<typename T, typename U> struct bitwise_or;
|
||||
template<typename T, typename U> struct bitwise_xor;
|
||||
template<typename T, typename U> struct comma;
|
||||
template<typename T, typename U> struct mem_ptr;
|
||||
|
||||
template<typename T, typename U> struct assign;
|
||||
template<typename T, typename U> struct shift_left_assign;
|
||||
template<typename T, typename U> struct shift_right_assign;
|
||||
template<typename T, typename U> struct multiplies_assign;
|
||||
template<typename T, typename U> struct divides_assign;
|
||||
template<typename T, typename U> struct modulus_assign;
|
||||
template<typename T, typename U> struct plus_assign;
|
||||
template<typename T, typename U> struct minus_assign;
|
||||
template<typename T, typename U> struct bitwise_and_assign;
|
||||
template<typename T, typename U> struct bitwise_or_assign;
|
||||
template<typename T, typename U> struct bitwise_xor_assign;
|
||||
template<typename T, typename U> struct subscript;
|
||||
template<typename T, typename U> struct member;
|
||||
template<typename T, typename U, typename V> struct if_else_;
|
||||
|
||||
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
|
||||
struct function;
|
||||
}
|
||||
|
||||
using namespace op;
|
||||
|
||||
namespace functional
|
||||
{
|
||||
struct left;
|
||||
struct right;
|
||||
struct eval;
|
||||
struct deep_copy;
|
||||
|
||||
template<typename Domain = default_domain>
|
||||
struct as_expr;
|
||||
|
||||
template<typename Domain = default_domain>
|
||||
struct as_child;
|
||||
|
||||
template<typename N = mpl::long_<0> >
|
||||
struct child;
|
||||
|
||||
template<long N>
|
||||
struct child_c;
|
||||
|
||||
template<typename Tag, typename Domain = deduce_domain>
|
||||
struct make_expr;
|
||||
|
||||
template<typename Tag, typename Domain = deduce_domain>
|
||||
struct unpack_expr;
|
||||
|
||||
template<typename Tag, typename Domain = deduce_domain>
|
||||
struct unfused_expr_fun;
|
||||
|
||||
template<typename Tag, typename Domain = deduce_domain>
|
||||
struct unfused_expr;
|
||||
|
||||
typedef make_expr<tag::terminal> make_terminal;
|
||||
typedef make_expr<tag::unary_plus> make_unary_plus;
|
||||
typedef make_expr<tag::negate> make_negate;
|
||||
typedef make_expr<tag::dereference> make_dereference;
|
||||
typedef make_expr<tag::complement> make_complement;
|
||||
typedef make_expr<tag::address_of> make_address_of;
|
||||
typedef make_expr<tag::logical_not> make_logical_not;
|
||||
typedef make_expr<tag::pre_inc> make_pre_inc;
|
||||
typedef make_expr<tag::pre_dec> make_pre_dec;
|
||||
typedef make_expr<tag::post_inc> make_post_inc;
|
||||
typedef make_expr<tag::post_dec> make_post_dec;
|
||||
typedef make_expr<tag::shift_left> make_shift_left;
|
||||
typedef make_expr<tag::shift_right> make_shift_right;
|
||||
typedef make_expr<tag::multiplies> make_multiplies;
|
||||
typedef make_expr<tag::divides> make_divides;
|
||||
typedef make_expr<tag::modulus> make_modulus;
|
||||
typedef make_expr<tag::plus> make_plus;
|
||||
typedef make_expr<tag::minus> make_minus;
|
||||
typedef make_expr<tag::less> make_less;
|
||||
typedef make_expr<tag::greater> make_greater;
|
||||
typedef make_expr<tag::less_equal> make_less_equal;
|
||||
typedef make_expr<tag::greater_equal> make_greater_equal;
|
||||
typedef make_expr<tag::equal_to> make_equal_to;
|
||||
typedef make_expr<tag::not_equal_to> make_not_equal_to;
|
||||
typedef make_expr<tag::logical_or> make_logical_or;
|
||||
typedef make_expr<tag::logical_and> make_logical_and;
|
||||
typedef make_expr<tag::bitwise_and> make_bitwise_and;
|
||||
typedef make_expr<tag::bitwise_or> make_bitwise_or;
|
||||
typedef make_expr<tag::bitwise_xor> make_bitwise_xor;
|
||||
typedef make_expr<tag::comma> make_comma;
|
||||
typedef make_expr<tag::mem_ptr> make_mem_ptr;
|
||||
typedef make_expr<tag::assign> make_assign;
|
||||
typedef make_expr<tag::shift_left_assign> make_shift_left_assign;
|
||||
typedef make_expr<tag::shift_right_assign> make_shift_right_assign;
|
||||
typedef make_expr<tag::multiplies_assign> make_multiplies_assign;
|
||||
typedef make_expr<tag::divides_assign> make_divides_assign;
|
||||
typedef make_expr<tag::modulus_assign> make_modulus_assign;
|
||||
typedef make_expr<tag::plus_assign> make_plus_assign;
|
||||
typedef make_expr<tag::minus_assign> make_minus_assign;
|
||||
typedef make_expr<tag::bitwise_and_assign> make_bitwise_and_assign;
|
||||
typedef make_expr<tag::bitwise_or_assign> make_bitwise_or_assign;
|
||||
typedef make_expr<tag::bitwise_xor_assign> make_bitwise_xor_assign;
|
||||
typedef make_expr<tag::subscript> make_subscript;
|
||||
typedef make_expr<tag::if_else_> make_if_else;
|
||||
typedef make_expr<tag::function> make_function;
|
||||
|
||||
struct flatten;
|
||||
struct pop_front;
|
||||
struct reverse;
|
||||
}
|
||||
|
||||
typedef functional::flatten _flatten;
|
||||
typedef functional::pop_front _pop_front;
|
||||
typedef functional::reverse _reverse;
|
||||
typedef functional::eval _eval;
|
||||
typedef functional::deep_copy _deep_copy;
|
||||
|
||||
typedef functional::make_expr<tag::terminal> _make_terminal;
|
||||
typedef functional::make_expr<tag::unary_plus> _make_unary_plus;
|
||||
typedef functional::make_expr<tag::negate> _make_negate;
|
||||
typedef functional::make_expr<tag::dereference> _make_dereference;
|
||||
typedef functional::make_expr<tag::complement> _make_complement;
|
||||
typedef functional::make_expr<tag::address_of> _make_address_of;
|
||||
typedef functional::make_expr<tag::logical_not> _make_logical_not;
|
||||
typedef functional::make_expr<tag::pre_inc> _make_pre_inc;
|
||||
typedef functional::make_expr<tag::pre_dec> _make_pre_dec;
|
||||
typedef functional::make_expr<tag::post_inc> _make_post_inc;
|
||||
typedef functional::make_expr<tag::post_dec> _make_post_dec;
|
||||
typedef functional::make_expr<tag::shift_left> _make_shift_left;
|
||||
typedef functional::make_expr<tag::shift_right> _make_shift_right;
|
||||
typedef functional::make_expr<tag::multiplies> _make_multiplies;
|
||||
typedef functional::make_expr<tag::divides> _make_divides;
|
||||
typedef functional::make_expr<tag::modulus> _make_modulus;
|
||||
typedef functional::make_expr<tag::plus> _make_plus;
|
||||
typedef functional::make_expr<tag::minus> _make_minus;
|
||||
typedef functional::make_expr<tag::less> _make_less;
|
||||
typedef functional::make_expr<tag::greater> _make_greater;
|
||||
typedef functional::make_expr<tag::less_equal> _make_less_equal;
|
||||
typedef functional::make_expr<tag::greater_equal> _make_greater_equal;
|
||||
typedef functional::make_expr<tag::equal_to> _make_equal_to;
|
||||
typedef functional::make_expr<tag::not_equal_to> _make_not_equal_to;
|
||||
typedef functional::make_expr<tag::logical_or> _make_logical_or;
|
||||
typedef functional::make_expr<tag::logical_and> _make_logical_and;
|
||||
typedef functional::make_expr<tag::bitwise_and> _make_bitwise_and;
|
||||
typedef functional::make_expr<tag::bitwise_or> _make_bitwise_or;
|
||||
typedef functional::make_expr<tag::bitwise_xor> _make_bitwise_xor;
|
||||
typedef functional::make_expr<tag::comma> _make_comma;
|
||||
typedef functional::make_expr<tag::mem_ptr> _make_mem_ptr;
|
||||
typedef functional::make_expr<tag::assign> _make_assign;
|
||||
typedef functional::make_expr<tag::shift_left_assign> _make_shift_left_assign;
|
||||
typedef functional::make_expr<tag::shift_right_assign> _make_shift_right_assign;
|
||||
typedef functional::make_expr<tag::multiplies_assign> _make_multiplies_assign;
|
||||
typedef functional::make_expr<tag::divides_assign> _make_divides_assign;
|
||||
typedef functional::make_expr<tag::modulus_assign> _make_modulus_assign;
|
||||
typedef functional::make_expr<tag::plus_assign> _make_plus_assign;
|
||||
typedef functional::make_expr<tag::minus_assign> _make_minus_assign;
|
||||
typedef functional::make_expr<tag::bitwise_and_assign> _make_bitwise_and_assign;
|
||||
typedef functional::make_expr<tag::bitwise_or_assign> _make_bitwise_or_assign;
|
||||
typedef functional::make_expr<tag::bitwise_xor_assign> _make_bitwise_xor_assign;
|
||||
typedef functional::make_expr<tag::subscript> _make_subscript;
|
||||
typedef functional::make_expr<tag::if_else_> _make_if_else;
|
||||
typedef functional::make_expr<tag::function> _make_function;
|
||||
|
||||
template<typename T>
|
||||
struct is_callable;
|
||||
|
||||
template<typename T, typename Void = void>
|
||||
struct is_aggregate;
|
||||
|
||||
template<typename T, typename Void = void>
|
||||
struct is_transform;
|
||||
|
||||
#define BOOST_PROTO_UNEXPR() typedef int proto_is_expr_;
|
||||
#define BOOST_PROTO_CALLABLE() typedef void proto_is_callable_;
|
||||
#define BOOST_PROTO_TRANSFORM() typedef void proto_is_transform_;
|
||||
#define BOOST_PROTO_AGGREGATE() typedef void proto_is_aggregate_;
|
||||
|
||||
struct callable
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
};
|
||||
|
||||
struct empty_base;
|
||||
|
||||
struct transform_base;
|
||||
|
||||
template<typename PrimitiveTransform, typename Base = transform_base>
|
||||
struct transform;
|
||||
|
||||
template<typename Grammar, typename Fun = Grammar>
|
||||
struct when;
|
||||
|
||||
template<typename Fun>
|
||||
struct otherwise;
|
||||
|
||||
template<typename Fun>
|
||||
struct call;
|
||||
|
||||
template<typename Fun>
|
||||
struct make;
|
||||
|
||||
template<typename PrimitiveTransform>
|
||||
struct protect;
|
||||
|
||||
template<typename T>
|
||||
struct noinvoke;
|
||||
|
||||
template<typename Fun>
|
||||
struct lazy;
|
||||
|
||||
template<typename Sequence, typename State, typename Fun>
|
||||
struct fold;
|
||||
|
||||
template<typename Sequence, typename State, typename Fun>
|
||||
struct reverse_fold;
|
||||
|
||||
// BUGBUG can we replace fold_tree with fold<flatten(_), state, fun> ?
|
||||
template<typename Sequence, typename State, typename Fun>
|
||||
struct fold_tree;
|
||||
|
||||
template<typename Sequence, typename State, typename Fun>
|
||||
struct reverse_fold_tree;
|
||||
|
||||
template<typename Grammar>
|
||||
struct pass_through;
|
||||
|
||||
struct _expr;
|
||||
struct _state;
|
||||
struct _data;
|
||||
|
||||
struct _value;
|
||||
|
||||
template<int I>
|
||||
struct _child_c;
|
||||
|
||||
typedef _child_c<0> _child0;
|
||||
typedef _child_c<1> _child1;
|
||||
typedef _child0 _child;
|
||||
typedef _child0 _left;
|
||||
typedef _child1 _right;
|
||||
|
||||
// _child2, _child3, _child4, ...
|
||||
#define M0(Z, N, DATA) typedef _child_c<N> BOOST_PP_CAT(_child, N);
|
||||
BOOST_PP_REPEAT_FROM_TO(
|
||||
2
|
||||
, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)
|
||||
, M0
|
||||
, ~
|
||||
)
|
||||
#undef M0
|
||||
|
||||
struct _byref;
|
||||
struct _byval;
|
||||
|
||||
template<typename T>
|
||||
struct is_extension;
|
||||
|
||||
namespace exops
|
||||
{}
|
||||
|
||||
}} // namespace boost::proto
|
||||
|
||||
#endif
|
||||
135
libraries/include/boost/proto/proto_typeof.hpp
Normal file
135
libraries/include/boost/proto/proto_typeof.hpp
Normal file
@@ -0,0 +1,135 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file proto_typeof.hpp
|
||||
/// Type registrations so that proto expression templates can be used together
|
||||
/// with the Boost.Typeof library.
|
||||
//
|
||||
// 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_PROTO_PROTO_TYPEOF_H
|
||||
#define BOOST_XPRESSIVE_PROTO_PROTO_TYPEOF_H
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/deep_copy.hpp>
|
||||
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::terminal)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::unary_plus)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::negate)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::dereference)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::complement)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::address_of)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::logical_not)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::pre_inc)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::pre_dec)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::post_inc)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::post_dec)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::shift_left)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::shift_right)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::multiplies)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::divides)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::modulus)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::plus)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::minus)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::less)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::greater)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::less_equal)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::greater_equal)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::equal_to)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::not_equal_to)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::logical_or)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::logical_and)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_and)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_or)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_xor)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::comma)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::mem_ptr)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::shift_left_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::shift_right_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::multiplies_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::divides_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::modulus_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::plus_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::minus_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_and_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_or_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_xor_assign)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::subscript)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::member)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::if_else_)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::function)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(boost::proto::exprns_::is_proto_expr)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::exprns_::expr, (typename)(typename)(long))
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::utility::literal, (typename)(typename))
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::term, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list1, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list2, 2)
|
||||
// can't use PP metaprogramming here because all typeof registrations
|
||||
// must be on separate lines.
|
||||
#if BOOST_PROTO_MAX_ARITY >= 3
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list3, 3)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 4
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list4, 4)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 5
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list5, 5)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 6
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list6, 6)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 7
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list7, 7)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 8
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list8, 8)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 9
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list9, 9)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 10
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list10, 10)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 11
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list11, 11)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 12
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list12, 12)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 13
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list13, 13)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 14
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list14, 14)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 15
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list15, 15)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 16
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list16, 16)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 17
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list17, 17)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 18
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list18, 18)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 19
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list19, 19)
|
||||
#endif
|
||||
#if BOOST_PROTO_MAX_ARITY >= 20
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list20, 20)
|
||||
#endif
|
||||
|
||||
#define BOOST_PROTO_AUTO(Var, Expr) BOOST_AUTO(Var, boost::proto::deep_copy(Expr))
|
||||
#define BOOST_PROTO_AUTO_TPL(Var, Expr) BOOST_AUTO_TPL(Var, boost::proto::deep_copy(Expr))
|
||||
|
||||
#endif
|
||||
312
libraries/include/boost/proto/repeat.hpp
Normal file
312
libraries/include/boost/proto/repeat.hpp
Normal file
@@ -0,0 +1,312 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file repeat.hpp
|
||||
/// Contains macros to ease the generation of repetitious code constructs
|
||||
//
|
||||
// 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_PROTO_REPEAT_HPP_EAN_11_24_2008
|
||||
#define BOOST_PROTO_REPEAT_HPP_EAN_11_24_2008
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/tuple/elem.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp> // for BOOST_PROTO_MAX_ARITY
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
////////////////////////////////////////////
|
||||
/// INTERNAL ONLY
|
||||
#define BOOST_PROTO_ref_a_aux(Z, N, DATA)\
|
||||
boost::ref(BOOST_PP_CAT(proto_a, N))
|
||||
|
||||
/// \brief Generates a sequence like <tt>typename A0, typename A1, ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_typename_A(N)\
|
||||
BOOST_PP_ENUM_PARAMS(N, typename proto_A)
|
||||
|
||||
/// \brief Generates a sequence like <tt>A0 const &, A1 const &, ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_A_const_ref(N)\
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, const & BOOST_PP_INTERCEPT)
|
||||
|
||||
/// \brief Generates a sequence like <tt>A0 &, A1 &, ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_A_ref(N)\
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, & BOOST_PP_INTERCEPT)
|
||||
|
||||
/// \brief Generates a sequence like <tt>A0, A1, ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_A(N)\
|
||||
BOOST_PP_ENUM_PARAMS(N, proto_A)
|
||||
|
||||
/// \brief Generates a sequence like <tt>A0 const, A1 const, ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_A_const(N)\
|
||||
BOOST_PP_ENUM_PARAMS(N, const proto_A)
|
||||
|
||||
/// \brief Generates a sequence like <tt>A0 const &a0, A1 const &a0, ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_A_const_ref_a(N)\
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, const &proto_a)
|
||||
|
||||
/// \brief Generates a sequence like <tt>A0 &a0, A1 &a0, ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_A_ref_a(N)\
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, &proto_a)
|
||||
|
||||
/// \brief Generates a sequence like <tt>boost::ref(a0), boost::ref(a1), ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_ref_a(N)\
|
||||
BOOST_PP_ENUM(N, BOOST_PROTO_ref_a_aux, ~)
|
||||
|
||||
/// \brief Generates a sequence like <tt>a0, a1, ...</tt>
|
||||
///
|
||||
#define BOOST_PROTO_a(N)\
|
||||
BOOST_PP_ENUM_PARAMS(N, proto_a)
|
||||
|
||||
////////////////////////////////////////////
|
||||
/// INTERNAL ONLY
|
||||
#define BOOST_PROTO_invoke(Z, N, DATA)\
|
||||
BOOST_PP_TUPLE_ELEM(5,0,DATA)(N, BOOST_PP_TUPLE_ELEM(5,1,DATA), BOOST_PP_TUPLE_ELEM(5,2,DATA), BOOST_PP_TUPLE_ELEM(5,3,DATA), BOOST_PP_TUPLE_ELEM(5,4,DATA))
|
||||
|
||||
/// \brief Repeatedly invoke the specified macro.
|
||||
///
|
||||
/// BOOST_PROTO_REPEAT_FROM_TO_EX() is used generate the kind of repetitive code that is typical
|
||||
/// of DSELs built with Proto. BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, typename_A, A, A_a, a) is equivalent to:
|
||||
///
|
||||
/// \code
|
||||
/// MACRO(FROM, typename_A, A, A_a, a)
|
||||
/// MACRO(FROM+1, typename_A, A, A_a, a)
|
||||
/// ...
|
||||
/// MACRO(TO-1, typename_A, A, A_a, a)
|
||||
/// \endcode
|
||||
#define BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, typename_A, A, A_a, a)\
|
||||
BOOST_PP_REPEAT_FROM_TO(FROM, TO, BOOST_PROTO_invoke, (MACRO, typename_A, A, A_a, a))
|
||||
|
||||
/// \brief Repeatedly invoke the specified macro.
|
||||
///
|
||||
/// BOOST_PROTO_REPEAT_FROM_TO() is used generate the kind of repetitive code that is typical
|
||||
/// of DSELs built with Proto. BOOST_PROTO_REPEAT_FROM_TO(FROM, TO, MACRO) is equivalent to:
|
||||
///
|
||||
/// \code
|
||||
/// MACRO(FROM, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
|
||||
/// MACRO(FROM+1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
|
||||
/// ...
|
||||
/// MACRO(TO-1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
|
||||
/// \endcode
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/** \code
|
||||
|
||||
// Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
|
||||
// following construct() function template.
|
||||
#define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \
|
||||
template<typename T, typename_A(N)> \
|
||||
typename proto::result_of::make_expr< \
|
||||
proto::tag::function \
|
||||
, construct_helper<T> \
|
||||
, A_const_ref(N) \
|
||||
>::type const \
|
||||
construct(A_const_ref_a(N)) \
|
||||
{ \
|
||||
return proto::make_expr< \
|
||||
proto::tag::function \
|
||||
>( \
|
||||
construct_helper<T>() \
|
||||
, ref_a(N) \
|
||||
); \
|
||||
}
|
||||
BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0)
|
||||
#undef M0
|
||||
|
||||
\endcode
|
||||
**/
|
||||
/// The above invocation of BOOST_PROTO_REPEAT_FROM_TO() will generate
|
||||
/// the following code:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename T, typename A0>
|
||||
/// typename proto::result_of::make_expr<
|
||||
/// proto::tag::function
|
||||
/// , construct_helper<T>
|
||||
/// , A0 const &
|
||||
/// >::type const
|
||||
/// construct(A0 const & a0)
|
||||
/// {
|
||||
/// return proto::make_expr<
|
||||
/// proto::tag::function
|
||||
/// >(
|
||||
/// construct_helper<T>()
|
||||
/// , boost::ref(a0)
|
||||
/// );
|
||||
/// }
|
||||
///
|
||||
/// template<typename T, typename A0, typename A1>
|
||||
/// typename proto::result_of::make_expr<
|
||||
/// proto::tag::function
|
||||
/// , construct_helper<T>
|
||||
/// , A0 const &
|
||||
/// , A1 const &
|
||||
/// >::type const
|
||||
/// construct(A0 const & a0, A1 const & a1)
|
||||
/// {
|
||||
/// return proto::make_expr<
|
||||
/// proto::tag::function
|
||||
/// >(
|
||||
/// construct_helper<T>()
|
||||
/// , boost::ref(a0)
|
||||
/// , boost::ref(a1)
|
||||
/// );
|
||||
/// }
|
||||
///
|
||||
/// // ... and so on, up to BOOST_PROTO_MAX_ARITY-1 arguments ...
|
||||
/// \endcode
|
||||
#define BOOST_PROTO_REPEAT_FROM_TO(FROM, TO, MACRO)\
|
||||
BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
|
||||
|
||||
/// \brief Repeatedly invoke the specified macro.
|
||||
///
|
||||
/// BOOST_PROTO_REPEAT_EX() is used generate the kind of repetitive code that is typical
|
||||
/// of DSELs built with Proto. BOOST_PROTO_REPEAT_EX(MACRO, typename_A, A, A_a, a) is equivalent to:
|
||||
///
|
||||
/// \code
|
||||
/// MACRO(1, typename_A, A, A_a, a)
|
||||
/// MACRO(2, typename_A, A, A_a, a)
|
||||
/// ...
|
||||
/// MACRO(BOOST_PROTO_MAX_ARITY, typename_A, A, A_a, a)
|
||||
/// \endcode
|
||||
#define BOOST_PROTO_REPEAT_EX(MACRO, typename_A, A, A_a, a)\
|
||||
BOOST_PROTO_REPEAT_FROM_TO_EX(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
|
||||
|
||||
/// \brief Repeatedly invoke the specified macro.
|
||||
///
|
||||
/// BOOST_PROTO_REPEAT() is used generate the kind of repetitive code that is typical
|
||||
/// of DSELs built with Proto. BOOST_PROTO_REPEAT(MACRO) is equivalent to:
|
||||
///
|
||||
/// \code
|
||||
/// MACRO(1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
|
||||
/// MACRO(2, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
|
||||
/// ...
|
||||
/// MACRO(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
|
||||
/// \endcode
|
||||
#define BOOST_PROTO_REPEAT(MACRO)\
|
||||
BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO)
|
||||
|
||||
/// \brief Repeatedly invoke the specified macro.
|
||||
///
|
||||
/// BOOST_PROTO_LOCAL_ITERATE() is used generate the kind of repetitive code that is typical
|
||||
/// of DSELs built with Proto. This macro causes the user-defined macro BOOST_PROTO_LOCAL_MACRO to
|
||||
/// be expanded with values in the range specified by BOOST_PROTO_LOCAL_LIMITS.
|
||||
///
|
||||
/// Usage:
|
||||
///
|
||||
/// \code
|
||||
/// #include BOOST_PROTO_LOCAL_ITERATE()
|
||||
/// \endcode
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/** \code
|
||||
|
||||
// Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
|
||||
// following construct() function template.
|
||||
#define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, \
|
||||
A_const_ref_a, ref_a) \
|
||||
template<typename T, typename_A(N)> \
|
||||
typename proto::result_of::make_expr< \
|
||||
proto::tag::function \
|
||||
, construct_helper<T> \
|
||||
, A_const_ref(N) \
|
||||
>::type const \
|
||||
construct(A_const_ref_a(N)) \
|
||||
{ \
|
||||
return proto::make_expr< \
|
||||
proto::tag::function \
|
||||
>( \
|
||||
construct_helper<T>() \
|
||||
, ref_a(N) \
|
||||
); \
|
||||
}
|
||||
#define BOOST_PROTO_LOCAL_LIMITS (1, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY))
|
||||
#include BOOST_PROTO_LOCAL_ITERATE()
|
||||
|
||||
\endcode
|
||||
**/
|
||||
/// The above inclusion of BOOST_PROTO_LOCAL_ITERATE() will generate
|
||||
/// the following code:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename T, typename A0>
|
||||
/// typename proto::result_of::make_expr<
|
||||
/// proto::tag::function
|
||||
/// , construct_helper<T>
|
||||
/// , A0 const &
|
||||
/// >::type const
|
||||
/// construct(A0 const & a0)
|
||||
/// {
|
||||
/// return proto::make_expr<
|
||||
/// proto::tag::function
|
||||
/// >(
|
||||
/// construct_helper<T>()
|
||||
/// , boost::ref(a0)
|
||||
/// );
|
||||
/// }
|
||||
///
|
||||
/// template<typename T, typename A0, typename A1>
|
||||
/// typename proto::result_of::make_expr<
|
||||
/// proto::tag::function
|
||||
/// , construct_helper<T>
|
||||
/// , A0 const &
|
||||
/// , A1 const &
|
||||
/// >::type const
|
||||
/// construct(A0 const & a0, A1 const & a1)
|
||||
/// {
|
||||
/// return proto::make_expr<
|
||||
/// proto::tag::function
|
||||
/// >(
|
||||
/// construct_helper<T>()
|
||||
/// , boost::ref(a0)
|
||||
/// , boost::ref(a1)
|
||||
/// );
|
||||
/// }
|
||||
///
|
||||
/// // ... and so on, up to BOOST_PROTO_MAX_ARITY-1 arguments ...
|
||||
/// \endcode
|
||||
///
|
||||
/// If BOOST_PROTO_LOCAL_LIMITS is not defined by the user, it defaults
|
||||
/// to (1, BOOST_PROTO_MAX_ARITY)
|
||||
///
|
||||
/// At each iteration, BOOST_PROTO_LOCAL_MACRO is invoked with the current
|
||||
/// iteration number and the following 4 macro parameters:
|
||||
///
|
||||
/// \li BOOST_PROTO_LOCAL_typename_A
|
||||
/// \li BOOST_PROTO_LOCAL_A
|
||||
/// \li BOOST_PROTO_LOCAL_A_a
|
||||
/// \li BOOST_PROTO_LOCAL_a
|
||||
///
|
||||
/// If these macros are not defined by the user, they default respectively to:
|
||||
///
|
||||
/// \li BOOST_PROTO_typename_A
|
||||
/// \li BOOST_PROTO_A_const_ref
|
||||
/// \li BOOST_PROTO_A_const_ref_a
|
||||
/// \li BOOST_PROTO_ref_a
|
||||
///
|
||||
/// After including BOOST_PROTO_LOCAL_ITERATE(), the following macros are
|
||||
/// automatically undefined:
|
||||
///
|
||||
/// \li BOOST_PROTO_LOCAL_MACRO
|
||||
/// \li BOOST_PROTO_LOCAL_LIMITS
|
||||
/// \li BOOST_PROTO_LOCAL_typename_A
|
||||
/// \li BOOST_PROTO_LOCAL_A
|
||||
/// \li BOOST_PROTO_LOCAL_A_a
|
||||
/// \li BOOST_PROTO_LOCAL_a
|
||||
#define BOOST_PROTO_LOCAL_ITERATE() <boost/proto/detail/local.hpp>
|
||||
|
||||
#endif
|
||||
159
libraries/include/boost/proto/tags.hpp
Normal file
159
libraries/include/boost/proto/tags.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file tags.hpp
|
||||
/// Contains the tags for all the overloadable operators in C++
|
||||
//
|
||||
// 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_PROTO_TAGS_HPP_EAN_04_01_2005
|
||||
#define BOOST_PROTO_TAGS_HPP_EAN_04_01_2005
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto { namespace tag
|
||||
{
|
||||
|
||||
/// Tag type for terminals; aka, leaves in the expression tree.
|
||||
struct terminal {};
|
||||
|
||||
/// Tag type for the unary + operator.
|
||||
struct unary_plus {};
|
||||
|
||||
/// Tag type for the unary - operator.
|
||||
struct negate {};
|
||||
|
||||
/// Tag type for the unary * operator.
|
||||
struct dereference {};
|
||||
|
||||
/// Tag type for the unary ~ operator.
|
||||
struct complement {};
|
||||
|
||||
/// Tag type for the unary & operator.
|
||||
struct address_of {};
|
||||
|
||||
/// Tag type for the unary ! operator.
|
||||
struct logical_not {};
|
||||
|
||||
/// Tag type for the unary prefix ++ operator.
|
||||
struct pre_inc {};
|
||||
|
||||
/// Tag type for the unary prefix -- operator.
|
||||
struct pre_dec {};
|
||||
|
||||
/// Tag type for the unary postfix ++ operator.
|
||||
struct post_inc {};
|
||||
|
||||
/// Tag type for the unary postfix -- operator.
|
||||
struct post_dec {};
|
||||
|
||||
/// Tag type for the binary \<\< operator.
|
||||
struct shift_left {};
|
||||
|
||||
/// Tag type for the binary \>\> operator.
|
||||
struct shift_right {};
|
||||
|
||||
/// Tag type for the binary * operator.
|
||||
struct multiplies {};
|
||||
|
||||
/// Tag type for the binary / operator.
|
||||
struct divides {};
|
||||
|
||||
/// Tag type for the binary % operator.
|
||||
struct modulus {};
|
||||
|
||||
/// Tag type for the binary + operator.
|
||||
struct plus {};
|
||||
|
||||
/// Tag type for the binary - operator.
|
||||
struct minus {};
|
||||
|
||||
/// Tag type for the binary \< operator.
|
||||
struct less {};
|
||||
|
||||
/// Tag type for the binary \> operator.
|
||||
struct greater {};
|
||||
|
||||
/// Tag type for the binary \<= operator.
|
||||
struct less_equal {};
|
||||
|
||||
/// Tag type for the binary \>= operator.
|
||||
struct greater_equal {};
|
||||
|
||||
/// Tag type for the binary == operator.
|
||||
struct equal_to {};
|
||||
|
||||
/// Tag type for the binary != operator.
|
||||
struct not_equal_to {};
|
||||
|
||||
/// Tag type for the binary || operator.
|
||||
struct logical_or {};
|
||||
|
||||
/// Tag type for the binary && operator.
|
||||
struct logical_and {};
|
||||
|
||||
/// Tag type for the binary & operator.
|
||||
struct bitwise_and {};
|
||||
|
||||
/// Tag type for the binary | operator.
|
||||
struct bitwise_or {};
|
||||
|
||||
/// Tag type for the binary ^ operator.
|
||||
struct bitwise_xor {};
|
||||
|
||||
/// Tag type for the binary , operator.
|
||||
struct comma {};
|
||||
|
||||
/// Tag type for the binary ->* operator.
|
||||
struct mem_ptr {};
|
||||
|
||||
/// Tag type for the binary = operator.
|
||||
struct assign {};
|
||||
|
||||
/// Tag type for the binary \<\<= operator.
|
||||
struct shift_left_assign {};
|
||||
|
||||
/// Tag type for the binary \>\>= operator.
|
||||
struct shift_right_assign {};
|
||||
|
||||
/// Tag type for the binary *= operator.
|
||||
struct multiplies_assign {};
|
||||
|
||||
/// Tag type for the binary /= operator.
|
||||
struct divides_assign {};
|
||||
|
||||
/// Tag type for the binary %= operator.
|
||||
struct modulus_assign {};
|
||||
|
||||
/// Tag type for the binary += operator.
|
||||
struct plus_assign {};
|
||||
|
||||
/// Tag type for the binary -= operator.
|
||||
struct minus_assign {};
|
||||
|
||||
/// Tag type for the binary &= operator.
|
||||
struct bitwise_and_assign {};
|
||||
|
||||
/// Tag type for the binary |= operator.
|
||||
struct bitwise_or_assign {};
|
||||
|
||||
/// Tag type for the binary ^= operator.
|
||||
struct bitwise_xor_assign {};
|
||||
|
||||
/// Tag type for the binary subscript operator.
|
||||
struct subscript {};
|
||||
|
||||
/// Tag type for the binary virtual data members.
|
||||
struct member {};
|
||||
|
||||
/// Tag type for the ternary ?: conditional operator.
|
||||
struct if_else_ {};
|
||||
|
||||
/// Tag type for the n-ary function call operator.
|
||||
struct function {};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
2428
libraries/include/boost/proto/traits.hpp
Normal file
2428
libraries/include/boost/proto/traits.hpp
Normal file
File diff suppressed because it is too large
Load Diff
24
libraries/include/boost/proto/transform.hpp
Normal file
24
libraries/include/boost/proto/transform.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file transform.hpp
|
||||
/// Includes all the transforms in the transform/ sub-directory.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_HPP_EAN_06_23_2007
|
||||
#define BOOST_PROTO_TRANSFORM_HPP_EAN_06_23_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp> // must be first include
|
||||
#include <boost/proto/transform/arg.hpp>
|
||||
#include <boost/proto/transform/call.hpp>
|
||||
#include <boost/proto/transform/default.hpp>
|
||||
#include <boost/proto/transform/fold.hpp>
|
||||
#include <boost/proto/transform/fold_tree.hpp>
|
||||
#include <boost/proto/transform/lazy.hpp>
|
||||
#include <boost/proto/transform/make.hpp>
|
||||
#include <boost/proto/transform/pass_through.hpp>
|
||||
#include <boost/proto/transform/when.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp> // must be last include
|
||||
|
||||
#endif
|
||||
362
libraries/include/boost/proto/transform/arg.hpp
Normal file
362
libraries/include/boost/proto/transform/arg.hpp
Normal file
@@ -0,0 +1,362 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file arg.hpp
|
||||
/// Contains definition of the argN transforms.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
|
||||
#define BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
/// \brief A PrimitiveTransform that returns the current expression
|
||||
/// unmodified
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// proto::terminal<int>::type i = {42};
|
||||
/// proto::terminal<int>::type & j = proto::_expr()(i);
|
||||
/// assert( boost::addressof(i) == boost::addressof(j) );
|
||||
/// \endcode
|
||||
struct _expr : transform<_expr>
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef Expr result_type;
|
||||
|
||||
/// Returns the current expression.
|
||||
/// \param e The current expression.
|
||||
/// \return \c e
|
||||
/// \throw nothrow
|
||||
#ifdef BOOST_HAS_DECLTYPE
|
||||
result_type
|
||||
#else
|
||||
typename impl::expr_param
|
||||
#endif
|
||||
operator()(
|
||||
typename impl::expr_param e
|
||||
, typename impl::state_param
|
||||
, typename impl::data_param
|
||||
) const
|
||||
{
|
||||
return e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief A PrimitiveTransform that returns the current state
|
||||
/// unmodified
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// proto::terminal<int>::type i = {42};
|
||||
/// char ch = proto::_state()(i, 'a');
|
||||
/// assert( ch == 'a' );
|
||||
/// \endcode
|
||||
struct _state : transform<_state>
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef State result_type;
|
||||
|
||||
/// Returns the current state.
|
||||
/// \param s The current state.
|
||||
/// \return \c s
|
||||
/// \throw nothrow
|
||||
#ifdef BOOST_HAS_DECLTYPE
|
||||
result_type
|
||||
#else
|
||||
typename impl::state_param
|
||||
#endif
|
||||
operator ()(
|
||||
typename impl::expr_param
|
||||
, typename impl::state_param s
|
||||
, typename impl::data_param
|
||||
) const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief A PrimitiveTransform that returns the current data
|
||||
/// unmodified
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// proto::terminal<int>::type i = {42};
|
||||
/// std::string str("hello");
|
||||
/// std::string & data = proto::_data()(i, 'a', str);
|
||||
/// assert( &str == &data );
|
||||
/// \endcode
|
||||
struct _data : transform<_data>
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef Data result_type;
|
||||
|
||||
/// Returns the current data.
|
||||
/// \param d The current data.
|
||||
/// \return \c d
|
||||
/// \throw nothrow
|
||||
#ifdef BOOST_HAS_DECLTYPE
|
||||
result_type
|
||||
#else
|
||||
typename impl::data_param
|
||||
#endif
|
||||
operator ()(
|
||||
typename impl::expr_param
|
||||
, typename impl::state_param
|
||||
, typename impl::data_param d
|
||||
) const
|
||||
{
|
||||
return d;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief A PrimitiveTransform that returns N-th child of the current
|
||||
/// expression.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// proto::terminal<int>::type i = {42};
|
||||
/// proto::terminal<int>::type & j = proto::_child_c<0>()(-i);
|
||||
/// assert( boost::addressof(i) == boost::addressof(j) );
|
||||
/// \endcode
|
||||
template<int N>
|
||||
struct _child_c : transform<_child_c<N> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef
|
||||
typename result_of::child_c<Expr, N>::type
|
||||
result_type;
|
||||
|
||||
/// Returns the N-th child of \c e
|
||||
/// \pre <tt>arity_of\<Expr\>::::value \> N</tt>
|
||||
/// \param e The current expression.
|
||||
/// \return <tt>proto::child_c\<N\>(e)</tt>
|
||||
/// \throw nothrow
|
||||
#ifdef BOOST_HAS_DECLTYPE
|
||||
result_type
|
||||
#else
|
||||
typename result_of::child_c<typename impl::expr_param, N>::type
|
||||
#endif
|
||||
operator ()(
|
||||
typename impl::expr_param e
|
||||
, typename impl::state_param
|
||||
, typename impl::data_param
|
||||
) const
|
||||
{
|
||||
return proto::child_c<N>(e);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief A PrimitiveTransform that returns the value of the
|
||||
/// current terminal expression.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// proto::terminal<int>::type i = {42};
|
||||
/// int j = proto::_value()(i);
|
||||
/// assert( 42 == j );
|
||||
/// \endcode
|
||||
struct _value : transform<_value>
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef
|
||||
typename result_of::value<Expr>::type
|
||||
result_type;
|
||||
|
||||
/// Returns the value of the specified terminal expression.
|
||||
/// \pre <tt>arity_of\<Expr\>::::value == 0</tt>.
|
||||
/// \param e The current expression.
|
||||
/// \return <tt>proto::value(e)</tt>
|
||||
/// \throw nothrow
|
||||
#ifdef BOOST_HAS_DECLTYPE
|
||||
result_type
|
||||
#else
|
||||
typename result_of::value<typename impl::expr_param>::type
|
||||
#endif
|
||||
operator ()(
|
||||
typename impl::expr_param e
|
||||
, typename impl::state_param
|
||||
, typename impl::data_param
|
||||
) const
|
||||
{
|
||||
return proto::value(e);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief A unary CallableTransform that wraps its argument
|
||||
/// in a \c boost::reference_wrapper\<\>.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// proto::terminal<int>::type i = {42};
|
||||
/// boost::reference_wrapper<proto::terminal<int>::type> j
|
||||
/// = proto::when<_, proto::_byref(_)>()(i);
|
||||
/// assert( boost::addressof(i) == boost::addressof(j.get()) );
|
||||
/// \endcode
|
||||
struct _byref : callable
|
||||
{
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename T>
|
||||
struct result<This(T)>
|
||||
{
|
||||
typedef boost::reference_wrapper<T const> const type;
|
||||
};
|
||||
|
||||
template<typename This, typename T>
|
||||
struct result<This(T &)>
|
||||
{
|
||||
typedef boost::reference_wrapper<T> const type;
|
||||
};
|
||||
|
||||
/// Wrap the parameter \c t in a \c boost::reference_wrapper\<\>
|
||||
/// \param t The object to wrap
|
||||
/// \return <tt>boost::ref(t)</tt>
|
||||
/// \throw nothrow
|
||||
template<typename T>
|
||||
boost::reference_wrapper<T> const operator ()(T &t) const
|
||||
{
|
||||
return boost::reference_wrapper<T>(t);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename T>
|
||||
boost::reference_wrapper<T const> const operator ()(T const &t) const
|
||||
{
|
||||
return boost::reference_wrapper<T const>(t);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A unary CallableTransform that strips references
|
||||
/// and \c boost::reference_wrapper\<\> from its argument.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// proto::terminal<int>::type i = {42};
|
||||
/// int j = 67;
|
||||
/// int k = proto::when<_, proto::_byval(proto::_state)>()(i, boost::ref(j));
|
||||
/// assert( 67 == k );
|
||||
/// \endcode
|
||||
struct _byval : callable
|
||||
{
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename T>
|
||||
struct result<This(T)>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename This, typename T>
|
||||
struct result<This(T &)>
|
||||
: result<This(T)>
|
||||
{};
|
||||
|
||||
template<typename This, typename T>
|
||||
struct result<This(boost::reference_wrapper<T>)>
|
||||
: result<This(T)>
|
||||
{};
|
||||
|
||||
/// \param t The object to unref
|
||||
/// \return <tt>t</tt>
|
||||
/// \throw nothrow
|
||||
template<typename T>
|
||||
T operator ()(T const &t) const
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
/// \overload
|
||||
///
|
||||
template<typename T>
|
||||
T operator ()(boost::reference_wrapper<T> const &t) const
|
||||
{
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<_expr>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<_state>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<_data>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<int N>
|
||||
struct is_callable<_child_c<N> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<_value>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<_byref>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<>
|
||||
struct is_callable<_byval>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
424
libraries/include/boost/proto/transform/call.hpp
Normal file
424
libraries/include/boost/proto/transform/call.hpp
Normal file
@@ -0,0 +1,424 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file call.hpp
|
||||
/// Contains definition of the call<> transform.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_CALL_HPP_EAN_11_02_2007
|
||||
#define BOOST_PROTO_TRANSFORM_CALL_HPP_EAN_11_02_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/detail/dont_care.hpp>
|
||||
#include <boost/proto/detail/as_lvalue.hpp>
|
||||
#include <boost/proto/detail/poly_function.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
/// \brief Wrap \c PrimitiveTransform so that <tt>when\<\></tt> knows
|
||||
/// it is callable. Requires that the parameter is actually a
|
||||
/// PrimitiveTransform.
|
||||
///
|
||||
/// This form of <tt>call\<\></tt> is useful for annotating an
|
||||
/// arbitrary PrimitiveTransform as callable when using it with
|
||||
/// <tt>when\<\></tt>. Consider the following transform, which
|
||||
/// is parameterized with another transform.
|
||||
///
|
||||
/// \code
|
||||
/// template<typename Grammar>
|
||||
/// struct Foo
|
||||
/// : when<
|
||||
/// unary_plus<Grammar>
|
||||
/// , Grammar(_child) // May or may not work.
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
///
|
||||
/// The problem with the above is that <tt>when\<\></tt> may or
|
||||
/// may not recognize \c Grammar as callable, depending on how
|
||||
/// \c Grammar is implemented. (See <tt>is_callable\<\></tt> for
|
||||
/// a discussion of this issue.) You can guard against
|
||||
/// the issue by wrapping \c Grammar in <tt>call\<\></tt>, such
|
||||
/// as:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename Grammar>
|
||||
/// struct Foo
|
||||
/// : when<
|
||||
/// unary_plus<Grammar>
|
||||
/// , call<Grammar>(_child) // OK, this works
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
///
|
||||
/// The above could also have been written as:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename Grammar>
|
||||
/// struct Foo
|
||||
/// : when<
|
||||
/// unary_plus<Grammar>
|
||||
/// , call<Grammar(_child)> // OK, this works, too
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
template<typename PrimitiveTransform>
|
||||
struct call : PrimitiveTransform
|
||||
{
|
||||
};
|
||||
|
||||
/// \brief Either call the PolymorphicFunctionObject with 0
|
||||
/// arguments, or invoke the PrimitiveTransform with 3
|
||||
/// arguments.
|
||||
template<typename Fun>
|
||||
struct call<Fun()> : transform<call<Fun()> >
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr, typename State, typename Data, bool B>
|
||||
struct impl2
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename boost::result_of<Fun()>::type result_type;
|
||||
|
||||
result_type operator()(
|
||||
typename impl2::expr_param
|
||||
, typename impl2::state_param
|
||||
, typename impl2::data_param
|
||||
) const
|
||||
{
|
||||
return Fun()();
|
||||
}
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, true>
|
||||
: Fun::template impl<Expr, State, Data>
|
||||
{};
|
||||
|
||||
/// Either call the PolymorphicFunctionObject \c Fun with 0 arguments; or
|
||||
/// invoke the PrimitiveTransform \c Fun with 3 arguments: the current
|
||||
/// expression, state, and data.
|
||||
///
|
||||
/// If \c Fun is a nullary PolymorphicFunctionObject, return <tt>Fun()()</tt>.
|
||||
/// Otherwise, return <tt>Fun()(e, s, d)</tt>.
|
||||
///
|
||||
/// \param e The current expression
|
||||
/// \param s The current state
|
||||
/// \param d An arbitrary data
|
||||
|
||||
/// If \c Fun is a nullary PolymorphicFunctionObject, \c type is a typedef
|
||||
/// for <tt>boost::result_of\<Fun()\>::::type</tt>. Otherwise, it is
|
||||
/// a typedef for <tt>boost::result_of\<Fun(Expr, State, Data)\>::::type</tt>.
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: impl2<Expr, State, Data, is_transform<Fun>::value>
|
||||
{};
|
||||
};
|
||||
|
||||
/// \brief Either call the PolymorphicFunctionObject with 1
|
||||
/// argument, or invoke the PrimitiveTransform with 3
|
||||
/// arguments.
|
||||
template<typename Fun, typename A0>
|
||||
struct call<Fun(A0)> : transform<call<Fun(A0)> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data, bool B>
|
||||
struct impl2
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
|
||||
typedef typename detail::as_mono_function<Fun(a0)>::type mono_fun;
|
||||
typedef typename boost::result_of<mono_fun(a0)>::type result_type;
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return mono_fun()(
|
||||
detail::as_lvalue(typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, true>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
|
||||
typedef typename Fun::template impl<a0, State, Data>::result_type result_type;
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return typename Fun::template impl<a0, State, Data>()(
|
||||
typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d)
|
||||
, s
|
||||
, d
|
||||
);
|
||||
}
|
||||
};
|
||||
/// Let \c x be <tt>when\<_, A0\>()(e, s, d)</tt> and \c X
|
||||
/// be the type of \c x.
|
||||
/// If \c Fun is a unary PolymorphicFunctionObject that accepts \c x,
|
||||
/// then \c type is a typedef for <tt>boost::result_of\<Fun(X)\>::::type</tt>.
|
||||
/// Otherwise, it is a typedef for <tt>boost::result_of\<Fun(X, State, Data)\>::::type</tt>.
|
||||
|
||||
/// Either call the PolymorphicFunctionObject with 1 argument:
|
||||
/// the result of applying the \c A0 transform; or
|
||||
/// invoke the PrimitiveTransform with 3 arguments:
|
||||
/// result of applying the \c A0 transform, the state, and the
|
||||
/// data.
|
||||
///
|
||||
/// Let \c x be <tt>when\<_, A0\>()(e, s, d)</tt>.
|
||||
/// If \c Fun is a unary PolymorphicFunctionObject that accepts \c x,
|
||||
/// then return <tt>Fun()(x)</tt>. Otherwise, return
|
||||
/// <tt>Fun()(x, s, d)</tt>.
|
||||
///
|
||||
/// \param e The current expression
|
||||
/// \param s The current state
|
||||
/// \param d An arbitrary data
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: impl2<Expr, State, Data, is_transform<Fun>::value>
|
||||
{};
|
||||
};
|
||||
|
||||
/// \brief Either call the PolymorphicFunctionObject with 2
|
||||
/// arguments, or invoke the PrimitiveTransform with 3
|
||||
/// arguments.
|
||||
template<typename Fun, typename A0, typename A1>
|
||||
struct call<Fun(A0, A1)> : transform<call<Fun(A0, A1)> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data, bool B>
|
||||
struct impl2
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
|
||||
typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
|
||||
typedef typename detail::as_mono_function<Fun(a0, a1)>::type mono_fun;
|
||||
typedef typename boost::result_of<mono_fun(a0, a1)>::type result_type;
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return mono_fun()(
|
||||
detail::as_lvalue(typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d))
|
||||
, detail::as_lvalue(typename when<_, A1>::template impl<Expr, State, Data>()(e, s, d))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, true>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
|
||||
typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
|
||||
typedef typename Fun::template impl<a0, a1, Data>::result_type result_type;
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return typename Fun::template impl<a0, a1, Data>()(
|
||||
typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d)
|
||||
, typename when<_, A1>::template impl<Expr, State, Data>()(e, s, d)
|
||||
, d
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/// Let \c x be <tt>when\<_, A0\>()(e, s, d)</tt> and \c X
|
||||
/// be the type of \c x.
|
||||
/// Let \c y be <tt>when\<_, A1\>()(e, s, d)</tt> and \c Y
|
||||
/// be the type of \c y.
|
||||
/// If \c Fun is a binary PolymorphicFunction object that accepts \c x
|
||||
/// and \c y, then \c type is a typedef for
|
||||
/// <tt>boost::result_of\<Fun(X, Y)\>::::type</tt>. Otherwise, it is
|
||||
/// a typedef for <tt>boost::result_of\<Fun(X, Y, Data)\>::::type</tt>.
|
||||
|
||||
/// Either call the PolymorphicFunctionObject with 2 arguments:
|
||||
/// the result of applying the \c A0 transform, and the
|
||||
/// result of applying the \c A1 transform; or invoke the
|
||||
/// PrimitiveTransform with 3 arguments: the result of applying
|
||||
/// the \c A0 transform, the result of applying the \c A1
|
||||
/// transform, and the data.
|
||||
///
|
||||
/// Let \c x be <tt>when\<_, A0\>()(e, s, d)</tt>.
|
||||
/// Let \c y be <tt>when\<_, A1\>()(e, s, d)</tt>.
|
||||
/// If \c Fun is a binary PolymorphicFunction object that accepts \c x
|
||||
/// and \c y, return <tt>Fun()(x, y)</tt>. Otherwise, return
|
||||
/// <tt>Fun()(x, y, d)</tt>.
|
||||
///
|
||||
/// \param e The current expression
|
||||
/// \param s The current state
|
||||
/// \param d An arbitrary data
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: impl2<Expr, State, Data, is_transform<Fun>::value>
|
||||
{};
|
||||
};
|
||||
|
||||
/// \brief Call the PolymorphicFunctionObject or the
|
||||
/// PrimitiveTransform with the current expression, state
|
||||
/// and data, transformed according to \c A0, \c A1, and
|
||||
/// \c A2, respectively.
|
||||
template<typename Fun, typename A0, typename A1, typename A2>
|
||||
struct call<Fun(A0, A1, A2)> : transform<call<Fun(A0, A1, A2)> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data, bool B>
|
||||
struct impl2
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
|
||||
typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
|
||||
typedef typename when<_, A2>::template impl<Expr, State, Data>::result_type a2;
|
||||
typedef typename detail::as_mono_function<Fun(a0, a1, a2)>::type mono_fun;
|
||||
typedef typename boost::result_of<mono_fun(a0, a1, a2)>::type result_type;
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return mono_fun()(
|
||||
detail::as_lvalue(typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d))
|
||||
, detail::as_lvalue(typename when<_, A1>::template impl<Expr, State, Data>()(e, s, d))
|
||||
, detail::as_lvalue(typename when<_, A2>::template impl<Expr, State, Data>()(e, s, d))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, true>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
|
||||
typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
|
||||
typedef typename when<_, A2>::template impl<Expr, State, Data>::result_type a2;
|
||||
typedef typename Fun::template impl<a0, a1, a2>::result_type result_type;
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return typename Fun::template impl<a0, a1, a2>()(
|
||||
typename when<_, A0>::template impl<Expr, State, Data>()(e, s, d)
|
||||
, typename when<_, A1>::template impl<Expr, State, Data>()(e, s, d)
|
||||
, typename when<_, A2>::template impl<Expr, State, Data>()(e, s, d)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/// Let \c x be <tt>when\<_, A0\>()(e, s, d)</tt>.
|
||||
/// Let \c y be <tt>when\<_, A1\>()(e, s, d)</tt>.
|
||||
/// Let \c z be <tt>when\<_, A2\>()(e, s, d)</tt>.
|
||||
/// Return <tt>Fun()(x, y, z)</tt>.
|
||||
///
|
||||
/// \param e The current expression
|
||||
/// \param s The current state
|
||||
/// \param d An arbitrary data
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: impl2<Expr, State, Data, is_transform<Fun>::value>
|
||||
{};
|
||||
};
|
||||
|
||||
#if BOOST_PROTO_MAX_ARITY > 3
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (4, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/call.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
#endif
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Fun>
|
||||
struct is_callable<call<Fun> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
}} // namespace boost::proto
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
/// \brief Call the PolymorphicFunctionObject \c Fun with the
|
||||
/// current expression, state and data, transformed according
|
||||
/// to \c A0 through \c AN.
|
||||
template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
|
||||
struct call<Fun(BOOST_PP_ENUM_PARAMS(N, A))> : transform<call<Fun(BOOST_PP_ENUM_PARAMS(N, A))> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
#define M0(Z, M, DATA) \
|
||||
typedef \
|
||||
typename when<_, BOOST_PP_CAT(A, M)> \
|
||||
::template impl<Expr, State, Data> \
|
||||
::result_type \
|
||||
BOOST_PP_CAT(a, M); \
|
||||
/**/
|
||||
BOOST_PP_REPEAT(N, M0, ~)
|
||||
#undef M0
|
||||
|
||||
typedef
|
||||
typename detail::as_mono_function<Fun(BOOST_PP_ENUM_PARAMS(N, a))>::type
|
||||
mono_fun;
|
||||
|
||||
typedef
|
||||
typename boost::result_of<mono_fun(BOOST_PP_ENUM_PARAMS(N, a))>::type
|
||||
result_type;
|
||||
|
||||
/// Let \c ax be <tt>when\<_, Ax\>()(e, s, d)</tt>
|
||||
/// for each \c x in <tt>[0,N]</tt>.
|
||||
/// Return <tt>Fun()(a0, a1,... aN)</tt>.
|
||||
///
|
||||
/// \param e The current expression
|
||||
/// \param s The current state
|
||||
/// \param d An arbitrary data
|
||||
result_type operator ()(
|
||||
typename impl::expr_param e
|
||||
, typename impl::state_param s
|
||||
, typename impl::data_param d
|
||||
) const
|
||||
{
|
||||
#define M0(Z, M, DATA) \
|
||||
detail::as_lvalue( \
|
||||
typename when<_, BOOST_PP_CAT(A, M)> \
|
||||
::template impl<Expr, State, Data>()(e, s, d)) \
|
||||
/**/
|
||||
return mono_fun()(BOOST_PP_ENUM(N, M0, ~));
|
||||
#undef M0
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
525
libraries/include/boost/proto/transform/default.hpp
Normal file
525
libraries/include/boost/proto/transform/default.hpp
Normal file
@@ -0,0 +1,525 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file default.hpp
|
||||
/// Contains definition of the _default transform, which gives operators their
|
||||
/// usual C++ meanings and uses Boost.Typeof to deduce return types.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_DEFAULT_HPP_EAN_04_04_2008
|
||||
#define BOOST_PROTO_TRANSFORM_DEFAULT_HPP_EAN_04_04_2008
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/get_pointer.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_member_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_object_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_function_pointer.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/transform/arg.hpp>
|
||||
#include <boost/proto/detail/decltype.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
template<typename Grammar>
|
||||
struct _default
|
||||
: transform<_default<Grammar> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data, typename Tag, long Arity>
|
||||
struct impl2;
|
||||
|
||||
template<typename Expr, typename State, typename Data, typename Tag>
|
||||
struct impl2<Expr, State, Data, Tag, 0>
|
||||
: _value::impl<Expr, State, Data>
|
||||
{};
|
||||
|
||||
#define BOOST_PROTO_UNARY_OP_RESULT(OP, TAG, MAKE) \
|
||||
template<typename Expr, typename State, typename Data> \
|
||||
struct impl2<Expr, State, Data, TAG, 1> \
|
||||
: transform_impl<Expr, State, Data> \
|
||||
{ \
|
||||
private: \
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0; \
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0; \
|
||||
public: \
|
||||
BOOST_PROTO_DECLTYPE_(OP proto::detail::MAKE<r0>(), result_type) \
|
||||
result_type operator ()( \
|
||||
typename impl2::expr_param e \
|
||||
, typename impl2::state_param s \
|
||||
, typename impl2::data_param d \
|
||||
) const \
|
||||
{ \
|
||||
typename Grammar::template impl<e0, State, Data> t0; \
|
||||
return OP t0(proto::child_c<0>(e), s, d); \
|
||||
} \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_BINARY_OP_RESULT(OP, TAG, LMAKE, RMAKE) \
|
||||
template<typename Expr, typename State, typename Data> \
|
||||
struct impl2<Expr, State, Data, TAG, 2> \
|
||||
: transform_impl<Expr, State, Data> \
|
||||
{ \
|
||||
private: \
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0; \
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1; \
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0; \
|
||||
typedef typename Grammar::template impl<e1, State, Data>::result_type r1; \
|
||||
public: \
|
||||
BOOST_PROTO_DECLTYPE_( \
|
||||
proto::detail::LMAKE<r0>() OP proto::detail::RMAKE<r1>() \
|
||||
, result_type \
|
||||
) \
|
||||
result_type operator ()( \
|
||||
typename impl2::expr_param e \
|
||||
, typename impl2::state_param s \
|
||||
, typename impl2::data_param d \
|
||||
) const \
|
||||
{ \
|
||||
typename Grammar::template impl<e0, State, Data> t0; \
|
||||
typename Grammar::template impl<e1, State, Data> t1; \
|
||||
return t0(proto::child_c<0>(e), s, d) \
|
||||
OP t1(proto::child_c<1>(e), s, d); \
|
||||
} \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
BOOST_PROTO_UNARY_OP_RESULT(+, tag::unary_plus, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(-, tag::negate, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(*, tag::dereference, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(~, tag::complement, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(&, tag::address_of, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(!, tag::logical_not, make)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(++, tag::pre_inc, make_mutable)
|
||||
BOOST_PROTO_UNARY_OP_RESULT(--, tag::pre_dec, make_mutable)
|
||||
|
||||
BOOST_PROTO_BINARY_OP_RESULT(<<, tag::shift_left, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(>>, tag::shift_right, make_mutable, make_mutable)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(*, tag::multiplies, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(/, tag::divides, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(%, tag::modulus, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(+, tag::plus, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(-, tag::minus, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(<, tag::less, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(>, tag::greater, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(<=, tag::less_equal, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(>=, tag::greater_equal, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(==, tag::equal_to, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(!=, tag::not_equal_to, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(||, tag::logical_or, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(&&, tag::logical_and, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(&, tag::bitwise_and, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(|, tag::bitwise_or, make, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(^, tag::bitwise_xor, make, make)
|
||||
|
||||
BOOST_PROTO_BINARY_OP_RESULT(=, tag::assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(<<=, tag::shift_left_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(>>=, tag::shift_right_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(*=, tag::multiplies_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(/=, tag::divides_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(%=, tag::modulus_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(+=, tag::plus_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(-=, tag::minus_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(&=, tag::bitwise_and_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(|=, tag::bitwise_or_assign, make_mutable, make)
|
||||
BOOST_PROTO_BINARY_OP_RESULT(^=, tag::bitwise_xor_assign, make_mutable, make)
|
||||
|
||||
#undef BOOST_PROTO_UNARY_OP_RESULT
|
||||
#undef BOOST_PROTO_BINARY_OP_RESULT
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct is_member_function_invocation
|
||||
{
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
|
||||
typedef typename remove_const<typename remove_reference<r1>::type>::type uncvref_r1;
|
||||
typedef typename is_member_function_pointer<uncvref_r1>::type type;
|
||||
BOOST_STATIC_CONSTANT(bool, value = type::value);
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr, typename State, typename Data, bool IsMemFunCall>
|
||||
struct memfun_impl
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
|
||||
typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
|
||||
public:
|
||||
typedef typename detail::mem_ptr_fun<r0, r1>::result_type result_type;
|
||||
result_type operator ()(
|
||||
typename memfun_impl::expr_param e
|
||||
, typename memfun_impl::state_param s
|
||||
, typename memfun_impl::data_param d
|
||||
) const
|
||||
{
|
||||
typename Grammar::template impl<e0, State, Data> t0;
|
||||
typename Grammar::template impl<e1, State, Data> t1;
|
||||
return detail::mem_ptr_fun<r0, r1>()(
|
||||
t0(proto::child_c<0>(e), s, d)
|
||||
, t1(proto::child_c<1>(e), s, d)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct memfun_impl<Expr, State, Data, true>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
|
||||
typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
|
||||
public:
|
||||
typedef detail::memfun<r0, r1> result_type;
|
||||
result_type const operator ()(
|
||||
typename memfun_impl::expr_param e
|
||||
, typename memfun_impl::state_param s
|
||||
, typename memfun_impl::data_param d
|
||||
) const
|
||||
{
|
||||
typename Grammar::template impl<e0, State, Data> t0;
|
||||
typename Grammar::template impl<e1, State, Data> t1;
|
||||
return detail::memfun<r0, r1>(
|
||||
t0(proto::child_c<0>(e), s, d)
|
||||
, t1(proto::child_c<1>(e), s, d)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::mem_ptr, 2>
|
||||
: memfun_impl<Expr, State, Data, is_member_function_invocation<Expr, State, Data>::value>
|
||||
{};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::post_inc, 1>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
|
||||
public:
|
||||
BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() ++, result_type)
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
typename Grammar::template impl<e0, State, Data> t0;
|
||||
return t0(proto::child_c<0>(e), s, d) ++;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::post_dec, 1>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
|
||||
public:
|
||||
BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() --, result_type)
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
typename Grammar::template impl<e0, State, Data> t0;
|
||||
return t0(proto::child_c<0>(e), s, d) --;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::subscript, 2>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
|
||||
typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
|
||||
public:
|
||||
BOOST_PROTO_DECLTYPE_(
|
||||
proto::detail::make_subscriptable<r0>() [ proto::detail::make<r1>() ]
|
||||
, result_type
|
||||
)
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
typename Grammar::template impl<e0, State, Data> t0;
|
||||
typename Grammar::template impl<e1, State, Data> t1;
|
||||
return t0(proto::child_c<0>(e), s, d) [
|
||||
t1(proto::child_c<1>(e), s, d) ];
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::if_else_, 3>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename result_of::child_c<Expr, 2>::type e2;
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
|
||||
typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
|
||||
typedef typename Grammar::template impl<e2, State, Data>::result_type r2;
|
||||
public:
|
||||
BOOST_PROTO_DECLTYPE_(
|
||||
proto::detail::make<r0>()
|
||||
? proto::detail::make<r1>()
|
||||
: proto::detail::make<r2>()
|
||||
, result_type
|
||||
)
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
typename Grammar::template impl<e0, State, Data> t0;
|
||||
typename Grammar::template impl<e1, State, Data> t1;
|
||||
typename Grammar::template impl<e2, State, Data> t2;
|
||||
return t0(proto::child_c<0>(e), s, d)
|
||||
? t1(proto::child_c<1>(e), s, d)
|
||||
: t2(proto::child_c<2>(e), s, d);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::comma, 2>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
private:
|
||||
typedef typename result_of::child_c<Expr, 0>::type e0;
|
||||
typedef typename result_of::child_c<Expr, 1>::type e1;
|
||||
typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
|
||||
typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
|
||||
public:
|
||||
typedef typename proto::detail::comma_result<r0, r1>::type result_type;
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
typename Grammar::template impl<e0, State, Data> t0;
|
||||
typename Grammar::template impl<e1, State, Data> t1;
|
||||
return t0(proto::child_c<0>(e), s, d)
|
||||
, t1(proto::child_c<1>(e), s, d);
|
||||
}
|
||||
};
|
||||
|
||||
#define EVAL_TYPE(Z, N, DATA) \
|
||||
typedef \
|
||||
typename result_of::child_c<DATA, N>::type \
|
||||
BOOST_PP_CAT(e, N); \
|
||||
typedef \
|
||||
typename Grammar::template impl<BOOST_PP_CAT(e, N), State, Data>::result_type \
|
||||
BOOST_PP_CAT(r, N); \
|
||||
/**/
|
||||
|
||||
#define EVAL(Z, N, DATA) \
|
||||
typename Grammar::template impl<BOOST_PP_CAT(e, N), State, Data>()( \
|
||||
proto::child_c<N>(DATA), s, d \
|
||||
) \
|
||||
/**/
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::function, 1>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
EVAL_TYPE(~, 0, Expr)
|
||||
|
||||
typedef
|
||||
typename proto::detail::result_of_fixup<r0>::type
|
||||
function_type;
|
||||
|
||||
typedef
|
||||
typename boost::result_of<function_type()>::type
|
||||
result_type;
|
||||
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return EVAL(~, 0, e)();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::function, 2>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
EVAL_TYPE(~, 0, Expr)
|
||||
EVAL_TYPE(~, 1, Expr)
|
||||
|
||||
typedef
|
||||
typename proto::detail::result_of_fixup<r0>::type
|
||||
function_type;
|
||||
|
||||
typedef
|
||||
typename detail::result_of_<function_type(r1)>::type
|
||||
result_type;
|
||||
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return this->invoke(
|
||||
e
|
||||
, s
|
||||
, d
|
||||
, is_member_function_pointer<function_type>()
|
||||
, is_member_object_pointer<function_type>()
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
result_type invoke(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
, mpl::false_
|
||||
, mpl::false_
|
||||
) const
|
||||
{
|
||||
return EVAL(~, 0, e)(EVAL(~, 1, e));
|
||||
}
|
||||
|
||||
result_type invoke(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
, mpl::true_
|
||||
, mpl::false_
|
||||
) const
|
||||
{
|
||||
using namespace detail::get_pointer_;
|
||||
return (get_pointer(EVAL(~, 1, e)) ->* EVAL(~, 0, e))();
|
||||
}
|
||||
|
||||
result_type invoke(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
, mpl::false_
|
||||
, mpl::true_
|
||||
) const
|
||||
{
|
||||
using namespace detail::get_pointer_;
|
||||
return (get_pointer(EVAL(~, 1, e)) ->* EVAL(~, 0, e));
|
||||
}
|
||||
};
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (3, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/default.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef EVAL_TYPE
|
||||
#undef EVAL
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: impl2<
|
||||
Expr
|
||||
, State
|
||||
, Data
|
||||
, typename transform_impl<Expr, State, Data>::expr::proto_tag
|
||||
, transform_impl<Expr, State, Data>::expr::proto_arity_c
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Grammar>
|
||||
struct is_callable<_default<Grammar> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl2<Expr, State, Data, tag::function, N>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
BOOST_PP_REPEAT(N, EVAL_TYPE, Expr)
|
||||
|
||||
typedef
|
||||
typename proto::detail::result_of_fixup<r0>::type
|
||||
function_type;
|
||||
|
||||
typedef
|
||||
typename boost::result_of<
|
||||
function_type(BOOST_PP_ENUM_SHIFTED_PARAMS(N, r))
|
||||
>::type
|
||||
result_type;
|
||||
|
||||
result_type operator ()(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
) const
|
||||
{
|
||||
return this->invoke(e, s, d, is_member_function_pointer<function_type>());
|
||||
}
|
||||
|
||||
private:
|
||||
result_type invoke(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
, mpl::false_
|
||||
) const
|
||||
{
|
||||
return EVAL(~, 0, e)(BOOST_PP_ENUM_SHIFTED(N, EVAL, e));
|
||||
}
|
||||
|
||||
result_type invoke(
|
||||
typename impl2::expr_param e
|
||||
, typename impl2::state_param s
|
||||
, typename impl2::data_param d
|
||||
, mpl::true_
|
||||
) const
|
||||
{
|
||||
#define M0(Z, M, e) BOOST_PP_COMMA_IF(BOOST_PP_SUB(M, 2)) EVAL(Z, M, e)
|
||||
using namespace detail::get_pointer_;
|
||||
return (get_pointer(EVAL(~, 1, e)) ->* EVAL(~, 0, e))(
|
||||
BOOST_PP_REPEAT_FROM_TO(2, N, M0, e)
|
||||
);
|
||||
#undef M0
|
||||
}
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
361
libraries/include/boost/proto/transform/fold.hpp
Normal file
361
libraries/include/boost/proto/transform/fold.hpp
Normal file
@@ -0,0 +1,361 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file fold.hpp
|
||||
/// Contains definition of the fold<> and reverse_fold<> transforms.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
|
||||
#define BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/arithmetic/sub.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#if BOOST_VERSION >= 103500
|
||||
#include <boost/fusion/include/fold.hpp>
|
||||
#else
|
||||
#include <boost/spirit/fusion/algorithm/fold.hpp>
|
||||
#endif
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/fusion.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/transform/call.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Transform, typename Data>
|
||||
struct as_callable
|
||||
{
|
||||
as_callable(Data v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr, typename State>
|
||||
struct result<This(Expr, State)>
|
||||
{
|
||||
typedef
|
||||
typename when<_, Transform>::template impl<Expr, State, Data>::result_type
|
||||
type;
|
||||
};
|
||||
|
||||
#if BOOST_VERSION < 103500
|
||||
template<typename Expr, typename State>
|
||||
struct apply
|
||||
: result<void(Expr, State)>
|
||||
{};
|
||||
#endif
|
||||
|
||||
template<typename Expr, typename State>
|
||||
typename when<_, Transform>::template impl<Expr &, State const &, Data>::result_type
|
||||
operator ()(Expr &e, State const &s) const
|
||||
{
|
||||
return typename when<_, Transform>::template impl<Expr &, State const &, Data>()(e, s, this->v_);
|
||||
}
|
||||
|
||||
private:
|
||||
Data v_;
|
||||
};
|
||||
|
||||
#if BOOST_VERSION < 103500
|
||||
template<typename Sequence, typename Void = void>
|
||||
struct as_fusion_sequence_type
|
||||
{
|
||||
typedef Sequence const type;
|
||||
};
|
||||
|
||||
template<typename Sequence>
|
||||
Sequence const &as_fusion_sequence(Sequence const &sequence, ...)
|
||||
{
|
||||
return sequence;
|
||||
}
|
||||
|
||||
template<typename Sequence>
|
||||
struct as_fusion_sequence_type<Sequence, typename Sequence::proto_is_expr_>
|
||||
{
|
||||
typedef typename Sequence::proto_base_expr const type;
|
||||
};
|
||||
|
||||
template<typename Sequence>
|
||||
typename Sequence::proto_base_expr const &as_fusion_sequence(Sequence const &sequence, int)
|
||||
{
|
||||
return sequence.proto_base();
|
||||
}
|
||||
|
||||
#define BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(X) typename detail::as_fusion_sequence_type<X>::type
|
||||
#define BOOST_PROTO_AS_FUSION_SEQUENCE(X) detail::as_fusion_sequence(X, 0)
|
||||
#else
|
||||
#define BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(X) X
|
||||
#define BOOST_PROTO_AS_FUSION_SEQUENCE(X) X
|
||||
#endif
|
||||
|
||||
template<
|
||||
typename State0
|
||||
, typename Fun
|
||||
, typename Expr
|
||||
, typename State
|
||||
, typename Data
|
||||
, long Arity = arity_of<Expr>::value
|
||||
>
|
||||
struct fold_impl
|
||||
{};
|
||||
|
||||
template<
|
||||
typename State0
|
||||
, typename Fun
|
||||
, typename Expr
|
||||
, typename State
|
||||
, typename Data
|
||||
, long Arity = arity_of<Expr>::value
|
||||
>
|
||||
struct reverse_fold_impl
|
||||
{};
|
||||
|
||||
#define BOOST_PROTO_CHILD_N_TYPE(N)\
|
||||
BOOST_PP_CAT(proto_child, N)\
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_FOLD_STATE_TYPE(Z, N, DATA) \
|
||||
typedef \
|
||||
typename when<_, Fun>::template impl< \
|
||||
typename result_of::child_c<Expr, N>::type \
|
||||
, BOOST_PP_CAT(state, N) \
|
||||
, Data \
|
||||
>::result_type \
|
||||
BOOST_PP_CAT(state, BOOST_PP_INC(N)); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_FOLD_STATE(Z, N, DATA) \
|
||||
BOOST_PP_CAT(state, BOOST_PP_INC(N)) \
|
||||
BOOST_PP_CAT(s, BOOST_PP_INC(N)) \
|
||||
= typename when<_, Fun>::template impl< \
|
||||
typename result_of::child_c<Expr, N>::type \
|
||||
, BOOST_PP_CAT(state, N) \
|
||||
, Data \
|
||||
>()( \
|
||||
proto::child_c<N>(e) \
|
||||
, BOOST_PP_CAT(s, N) \
|
||||
, d \
|
||||
); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_REVERSE_FOLD_STATE_TYPE(Z, N, DATA) \
|
||||
typedef \
|
||||
typename when<_, Fun>::template impl< \
|
||||
typename result_of::child_c< \
|
||||
Expr \
|
||||
, BOOST_PP_SUB(DATA, BOOST_PP_INC(N)) \
|
||||
>::type \
|
||||
, BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, N)) \
|
||||
, Data \
|
||||
>::result_type \
|
||||
BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PROTO_REVERSE_FOLD_STATE(Z, N, DATA) \
|
||||
BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))) \
|
||||
BOOST_PP_CAT(s, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))) \
|
||||
= typename when<_, Fun>::template impl< \
|
||||
typename result_of::child_c< \
|
||||
Expr \
|
||||
, BOOST_PP_SUB(DATA, BOOST_PP_INC(N)) \
|
||||
>::type \
|
||||
, BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, N)) \
|
||||
, Data \
|
||||
>()( \
|
||||
proto::child_c<BOOST_PP_SUB(DATA, BOOST_PP_INC(N))>(e) \
|
||||
, BOOST_PP_CAT(s, BOOST_PP_SUB(DATA, N)) \
|
||||
, d \
|
||||
); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/fold.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_PROTO_REVERSE_FOLD_STATE
|
||||
#undef BOOST_PROTO_REVERSE_FOLD_STATE_TYPE
|
||||
#undef BOOST_PROTO_FOLD_STATE
|
||||
#undef BOOST_PROTO_FOLD_STATE_TYPE
|
||||
#undef BOOST_PROTO_CHILD_N_TYPE
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief A PrimitiveTransform that invokes the <tt>fusion::fold\<\></tt>
|
||||
/// algorithm to accumulate
|
||||
template<typename Sequence, typename State0, typename Fun>
|
||||
struct fold : transform<fold<Sequence, State0, Fun> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
/// \brief A Fusion sequence.
|
||||
typedef
|
||||
typename remove_reference<
|
||||
typename when<_, Sequence>::template impl<Expr, State, Data>::result_type
|
||||
>::type
|
||||
sequence;
|
||||
|
||||
/// \brief An initial state for the fold.
|
||||
typedef
|
||||
typename remove_reference<
|
||||
typename when<_, State0>::template impl<Expr, State, Data>::result_type
|
||||
>::type
|
||||
state0;
|
||||
|
||||
/// \brief <tt>fun(v)(e,s) == when\<_,Fun\>()(e,s,v)</tt>
|
||||
typedef
|
||||
detail::as_callable<Fun, Data>
|
||||
fun;
|
||||
|
||||
typedef
|
||||
typename fusion::BOOST_PROTO_FUSION_RESULT_OF::fold<
|
||||
BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(sequence)
|
||||
, state0
|
||||
, fun
|
||||
>::type
|
||||
result_type;
|
||||
|
||||
/// Let \c seq be <tt>when\<_, Sequence\>()(e, s, d)</tt>, let
|
||||
/// \c state0 be <tt>when\<_, State0\>()(e, s, d)</tt>, and
|
||||
/// let \c fun(d) be an object such that <tt>fun(d)(e, s)</tt>
|
||||
/// is equivalent to <tt>when\<_, Fun\>()(e, s, d)</tt>. Then, this
|
||||
/// function returns <tt>fusion::fold(seq, state0, fun(d))</tt>.
|
||||
///
|
||||
/// \param e The current expression
|
||||
/// \param s The current state
|
||||
/// \param d An arbitrary data
|
||||
result_type operator ()(
|
||||
typename impl::expr_param e
|
||||
, typename impl::state_param s
|
||||
, typename impl::data_param d
|
||||
) const
|
||||
{
|
||||
typename when<_, Sequence>::template impl<Expr, State, Data> seq;
|
||||
detail::as_callable<Fun, Data> f(d);
|
||||
return fusion::fold(
|
||||
BOOST_PROTO_AS_FUSION_SEQUENCE(seq(e, s, d))
|
||||
, typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d)
|
||||
, f
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief A PrimitiveTransform that is the same as the
|
||||
/// <tt>fold\<\></tt> transform, except that it folds
|
||||
/// back-to-front instead of front-to-back. It uses
|
||||
/// the \c _reverse callable PolymorphicFunctionObject
|
||||
/// to create a <tt>fusion::reverse_view\<\></tt> of the
|
||||
/// sequence before invoking <tt>fusion::fold\<\></tt>.
|
||||
template<typename Sequence, typename State0, typename Fun>
|
||||
struct reverse_fold
|
||||
: fold<call<_reverse(Sequence)>, State0, Fun>
|
||||
{};
|
||||
|
||||
// This specialization is only for improved compile-time performance
|
||||
// in the commom case when the Sequence transform is \c proto::_.
|
||||
//
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename State0, typename Fun>
|
||||
struct fold<_, State0, Fun> : transform<fold<_, State0, Fun> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: detail::fold_impl<State0, Fun, Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
// This specialization is only for improved compile-time performance
|
||||
// in the commom case when the Sequence transform is \c proto::_.
|
||||
//
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename State0, typename Fun>
|
||||
struct reverse_fold<_, State0, Fun> : transform<reverse_fold<_, State0, Fun> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: detail::reverse_fold_impl<State0, Fun, Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Sequence, typename State, typename Fun>
|
||||
struct is_callable<fold<Sequence, State, Fun> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Sequence, typename State, typename Fun>
|
||||
struct is_callable<reverse_fold<Sequence, State, Fun> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<typename State0, typename Fun, typename Expr, typename State, typename Data>
|
||||
struct fold_impl<State0, Fun, Expr, State, Data, N>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename when<_, State0>::template impl<Expr, State, Data>::result_type state0;
|
||||
BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE_TYPE, N)
|
||||
typedef BOOST_PP_CAT(state, N) result_type;
|
||||
|
||||
result_type operator ()(
|
||||
typename fold_impl::expr_param e
|
||||
, typename fold_impl::state_param s
|
||||
, typename fold_impl::data_param d
|
||||
) const
|
||||
{
|
||||
state0 s0 =
|
||||
typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d);
|
||||
BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE, N)
|
||||
return BOOST_PP_CAT(s, N);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename State0, typename Fun, typename Expr, typename State, typename Data>
|
||||
struct reverse_fold_impl<State0, Fun, Expr, State, Data, N>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename when<_, State0>::template impl<Expr, State, Data>::result_type BOOST_PP_CAT(state, N);
|
||||
BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE_TYPE, N)
|
||||
typedef state0 result_type;
|
||||
|
||||
result_type operator ()(
|
||||
typename reverse_fold_impl::expr_param e
|
||||
, typename reverse_fold_impl::state_param s
|
||||
, typename reverse_fold_impl::data_param d
|
||||
) const
|
||||
{
|
||||
BOOST_PP_CAT(state, N) BOOST_PP_CAT(s, N) =
|
||||
typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d);
|
||||
BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE, N)
|
||||
return s0;
|
||||
}
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
174
libraries/include/boost/proto/transform/fold_tree.hpp
Normal file
174
libraries/include/boost/proto/transform/fold_tree.hpp
Normal file
@@ -0,0 +1,174 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file fold_tree.hpp
|
||||
/// Contains definition of the fold_tree<> and reverse_fold_tree<> transforms.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007
|
||||
#define BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/matches.hpp>
|
||||
#include <boost/proto/transform/fold.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Tag>
|
||||
struct has_tag : transform<has_tag<Tag> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data, typename EnableIf = Tag>
|
||||
struct impl
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef mpl::false_ result_type;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl<Expr, State, Data, typename Expr::proto_tag>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef mpl::true_ result_type;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl<Expr &, State, Data, typename Expr::proto_tag>
|
||||
: transform_impl<Expr &, State, Data>
|
||||
{
|
||||
typedef mpl::true_ result_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Tag, typename Fun>
|
||||
struct fold_tree_
|
||||
: if_<has_tag<Tag>, fold<_, _state, fold_tree_<Tag, Fun> >, Fun>
|
||||
{};
|
||||
|
||||
template<typename Tag, typename Fun>
|
||||
struct reverse_fold_tree_
|
||||
: if_<has_tag<Tag>, reverse_fold<_, _state, reverse_fold_tree_<Tag, Fun> >, Fun>
|
||||
{};
|
||||
}
|
||||
|
||||
/// \brief A PrimitiveTransform that recursively applies the
|
||||
/// <tt>fold\<\></tt> transform to sub-trees that all share a common
|
||||
/// tag type.
|
||||
///
|
||||
/// <tt>fold_tree\<\></tt> is useful for flattening trees into lists;
|
||||
/// for example, you might use <tt>fold_tree\<\></tt> to flatten an
|
||||
/// expression tree like <tt>a | b | c</tt> into a Fusion list like
|
||||
/// <tt>cons(c, cons(b, cons(a)))</tt>.
|
||||
///
|
||||
/// <tt>fold_tree\<\></tt> is easily understood in terms of a
|
||||
/// <tt>recurse_if_\<\></tt> helper, defined as follows:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename Tag, typename Fun>
|
||||
/// struct recurse_if_
|
||||
/// : if_<
|
||||
/// // If the current node has type type "Tag" ...
|
||||
/// is_same<tag_of<_>, Tag>()
|
||||
/// // ... recurse, otherwise ...
|
||||
/// , fold<_, _state, recurse_if_<Tag, Fun> >
|
||||
/// // ... apply the Fun transform.
|
||||
/// , Fun
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
///
|
||||
/// With <tt>recurse_if_\<\></tt> as defined above,
|
||||
/// <tt>fold_tree\<Sequence, State0, Fun\>()(e, s, d)</tt> is
|
||||
/// equivalent to
|
||||
/// <tt>fold<Sequence, State0, recurse_if_<Expr::proto_tag, Fun> >()(e, s, d).</tt>
|
||||
/// It has the effect of folding a tree front-to-back, recursing into
|
||||
/// child nodes that share a tag type with the parent node.
|
||||
template<typename Sequence, typename State0, typename Fun>
|
||||
struct fold_tree
|
||||
: transform<fold_tree<Sequence, State0, Fun> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: fold<
|
||||
Sequence
|
||||
, State0
|
||||
, detail::fold_tree_<
|
||||
typename remove_reference<Expr>::type::proto_tag
|
||||
, Fun
|
||||
>
|
||||
>::template impl<Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
/// \brief A PrimitiveTransform that recursively applies the
|
||||
/// <tt>reverse_fold\<\></tt> transform to sub-trees that all share
|
||||
/// a common tag type.
|
||||
///
|
||||
/// <tt>reverse_fold_tree\<\></tt> is useful for flattening trees into
|
||||
/// lists; for example, you might use <tt>reverse_fold_tree\<\></tt> to
|
||||
/// flatten an expression tree like <tt>a | b | c</tt> into a Fusion list
|
||||
/// like <tt>cons(a, cons(b, cons(c)))</tt>.
|
||||
///
|
||||
/// <tt>reverse_fold_tree\<\></tt> is easily understood in terms of a
|
||||
/// <tt>recurse_if_\<\></tt> helper, defined as follows:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename Tag, typename Fun>
|
||||
/// struct recurse_if_
|
||||
/// : if_<
|
||||
/// // If the current node has type type "Tag" ...
|
||||
/// is_same<tag_of<_>, Tag>()
|
||||
/// // ... recurse, otherwise ...
|
||||
/// , reverse_fold<_, _state, recurse_if_<Tag, Fun> >
|
||||
/// // ... apply the Fun transform.
|
||||
/// , Fun
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
///
|
||||
/// With <tt>recurse_if_\<\></tt> as defined above,
|
||||
/// <tt>reverse_fold_tree\<Sequence, State0, Fun\>()(e, s, d)</tt> is
|
||||
/// equivalent to
|
||||
/// <tt>reverse_fold<Sequence, State0, recurse_if_<Expr::proto_tag, Fun> >()(e, s, d).</tt>
|
||||
/// It has the effect of folding a tree back-to-front, recursing into
|
||||
/// child nodes that share a tag type with the parent node.
|
||||
template<typename Sequence, typename State0, typename Fun>
|
||||
struct reverse_fold_tree
|
||||
: transform<reverse_fold_tree<Sequence, State0, Fun> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: reverse_fold<
|
||||
Sequence
|
||||
, State0
|
||||
, detail::reverse_fold_tree_<
|
||||
typename remove_reference<Expr>::type::proto_tag
|
||||
, Fun
|
||||
>
|
||||
>::template impl<Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Sequence, typename State0, typename Fun>
|
||||
struct is_callable<fold_tree<Sequence, State0, Fun> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Sequence, typename State0, typename Fun>
|
||||
struct is_callable<reverse_fold_tree<Sequence, State0, Fun> >
|
||||
: mpl::true_
|
||||
{};
|
||||
}}
|
||||
|
||||
#endif
|
||||
190
libraries/include/boost/proto/transform/impl.hpp
Normal file
190
libraries/include/boost/proto/transform/impl.hpp
Normal file
@@ -0,0 +1,190 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file impl.hpp
|
||||
/// Contains definition of transform<> and transform_impl<> helpers.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008
|
||||
#define BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
template<typename PrimitiveTransform, typename Expr, typename State = int, typename Data = int>
|
||||
struct apply_transform
|
||||
: PrimitiveTransform::template impl<Expr, State, Data>
|
||||
{};
|
||||
|
||||
struct transform_base
|
||||
{
|
||||
BOOST_PROTO_CALLABLE()
|
||||
BOOST_PROTO_TRANSFORM()
|
||||
};
|
||||
|
||||
struct empty_base
|
||||
{};
|
||||
|
||||
template<
|
||||
typename PrimitiveTransform
|
||||
, typename Base BOOST_PROTO_WHEN_BUILDING_DOCS(= transform_base)
|
||||
>
|
||||
struct transform : Base
|
||||
{
|
||||
typedef PrimitiveTransform transform_type;
|
||||
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)>
|
||||
{
|
||||
typedef typename PrimitiveTransform::template impl<Expr, int, int>::result_type type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr, typename State>
|
||||
struct result<This(Expr, State)>
|
||||
{
|
||||
typedef typename PrimitiveTransform::template impl<Expr, State, int>::result_type type;
|
||||
};
|
||||
|
||||
template<typename This, typename Expr, typename State, typename Data>
|
||||
struct result<This(Expr, State, Data)>
|
||||
{
|
||||
typedef typename PrimitiveTransform::template impl<Expr, State, Data>::result_type type;
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
typename apply_transform<PrimitiveTransform, Expr &>::result_type
|
||||
operator ()(Expr &e) const
|
||||
{
|
||||
int i = 0;
|
||||
return apply_transform<PrimitiveTransform, Expr &>()(e, i, i);
|
||||
}
|
||||
|
||||
template<typename Expr, typename State>
|
||||
typename apply_transform<PrimitiveTransform, Expr &, State &>::result_type
|
||||
operator ()(Expr &e, State &s) const
|
||||
{
|
||||
int i = 0;
|
||||
return apply_transform<PrimitiveTransform, Expr &, State &>()(e, s, i);
|
||||
}
|
||||
|
||||
template<typename Expr, typename State>
|
||||
typename apply_transform<PrimitiveTransform, Expr &, State const &>::result_type
|
||||
operator ()(Expr &e, State const &s) const
|
||||
{
|
||||
int i = 0;
|
||||
return apply_transform<PrimitiveTransform, Expr &, State const &>()(e, s, i);
|
||||
}
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
typename apply_transform<PrimitiveTransform, Expr &, State &, Data &>::result_type
|
||||
operator ()(Expr &e, State &s, Data &d) const
|
||||
{
|
||||
return apply_transform<PrimitiveTransform, Expr &, State &, Data &>()(e, s, d);
|
||||
}
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
typename apply_transform<PrimitiveTransform, Expr &, State const &, Data &>::result_type
|
||||
operator ()(Expr &e, State const &s, Data &d) const
|
||||
{
|
||||
return apply_transform<PrimitiveTransform, Expr &, State const &, Data &>()(e, s, d);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct transform_impl
|
||||
{
|
||||
typedef Expr const expr;
|
||||
typedef Expr const &expr_param;
|
||||
typedef State const state;
|
||||
typedef State const &state_param;
|
||||
typedef Data const data;
|
||||
typedef Data const &data_param;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct transform_impl<Expr &, State, Data>
|
||||
{
|
||||
typedef Expr expr;
|
||||
typedef Expr &expr_param;
|
||||
typedef State const state;
|
||||
typedef State const &state_param;
|
||||
typedef Data const data;
|
||||
typedef Data const &data_param;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct transform_impl<Expr, State &, Data>
|
||||
{
|
||||
typedef Expr const expr;
|
||||
typedef Expr const &expr_param;
|
||||
typedef State state;
|
||||
typedef State &state_param;
|
||||
typedef Data const data;
|
||||
typedef Data const &data_param;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct transform_impl<Expr, State, Data &>
|
||||
{
|
||||
typedef Expr const expr;
|
||||
typedef Expr const &expr_param;
|
||||
typedef State const state;
|
||||
typedef State const &state_param;
|
||||
typedef Data data;
|
||||
typedef Data &data_param;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct transform_impl<Expr &, State &, Data>
|
||||
{
|
||||
typedef Expr expr;
|
||||
typedef Expr &expr_param;
|
||||
typedef State state;
|
||||
typedef State &state_param;
|
||||
typedef Data const data;
|
||||
typedef Data const &data_param;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct transform_impl<Expr &, State, Data &>
|
||||
{
|
||||
typedef Expr expr;
|
||||
typedef Expr &expr_param;
|
||||
typedef State const state;
|
||||
typedef State const &state_param;
|
||||
typedef Data data;
|
||||
typedef Data &data_param;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct transform_impl<Expr, State &, Data &>
|
||||
{
|
||||
typedef Expr const expr;
|
||||
typedef Expr const &expr_param;
|
||||
typedef State state;
|
||||
typedef State &state_param;
|
||||
typedef Data data;
|
||||
typedef Data &data_param;
|
||||
};
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct transform_impl<Expr &, State &, Data &>
|
||||
{
|
||||
typedef Expr expr;
|
||||
typedef Expr &expr_param;
|
||||
typedef State state;
|
||||
typedef State &state_param;
|
||||
typedef Data data;
|
||||
typedef Data &data_param;
|
||||
};
|
||||
|
||||
}} // namespace boost::proto
|
||||
|
||||
#endif
|
||||
85
libraries/include/boost/proto/transform/lazy.hpp
Normal file
85
libraries/include/boost/proto/transform/lazy.hpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file lazy.hpp
|
||||
/// Contains definition of the lazy<> transform.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_LAZY_HPP_EAN_12_02_2007
|
||||
#define BOOST_PROTO_TRANSFORM_LAZY_HPP_EAN_12_02_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/transform/make.hpp>
|
||||
#include <boost/proto/transform/call.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
/// \brief A PrimitiveTransform that uses <tt>make\<\></tt> to build
|
||||
/// a CallableTransform, and then uses <tt>call\<\></tt> to apply it.
|
||||
///
|
||||
/// <tt>lazy\<\></tt> is useful as a higher-order transform, when the
|
||||
/// transform to be applied depends on the current state of the
|
||||
/// transformation. The invocation of the <tt>make\<\></tt> transform
|
||||
/// evaluates any nested transforms, and the resulting type is treated
|
||||
/// as a CallableTransform, which is evaluated with <tt>call\<\></tt>.
|
||||
template<typename Object>
|
||||
struct lazy : transform<lazy<Object> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: call<
|
||||
typename make<Object>::template impl<Expr, State, Data>::result_type
|
||||
>::template impl<Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/lazy.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Object>
|
||||
struct is_callable<lazy<Object> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
/// \brief A PrimitiveTransform that uses <tt>make\<\></tt> to build
|
||||
/// a CallableTransform, and then uses <tt>call\<\></tt> to apply it.
|
||||
///
|
||||
/// <tt>lazy\<\></tt> is useful as a higher-order transform, when the
|
||||
/// transform to be applied depends on the current state of the
|
||||
/// transformation. The invocation of the <tt>make\<\></tt> transform
|
||||
/// evaluates any nested transforms, and the resulting type is treated
|
||||
/// as a CallableTransform, which is evaluated with <tt>call\<\></tt>.
|
||||
template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
|
||||
struct lazy<Object(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
: transform<lazy<Object(BOOST_PP_ENUM_PARAMS(N, A))> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: call<
|
||||
typename make<Object>::template impl<Expr, State, Data>::result_type
|
||||
(BOOST_PP_ENUM_PARAMS(N, A))
|
||||
>::template impl<Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
453
libraries/include/boost/proto/transform/make.hpp
Normal file
453
libraries/include/boost/proto/transform/make.hpp
Normal file
@@ -0,0 +1,453 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file make.hpp
|
||||
/// Contains definition of the make<> transform.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
|
||||
#define BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/selection/max.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/mpl/aux_/has_type.hpp>
|
||||
#include <boost/mpl/aux_/template_arity.hpp>
|
||||
#include <boost/mpl/aux_/lambda_arity_param.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/args.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/detail/as_lvalue.hpp>
|
||||
#include <boost/proto/detail/ignore_unused.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
|
||||
struct typelist
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<typename T, bool HasType = mpl::aux::has_type<T>::value>
|
||||
struct nested_type
|
||||
{
|
||||
typedef typename T::type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct nested_type<T, false>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T, typename Args, typename Void = void>
|
||||
struct nested_type_if
|
||||
: nested_type<T>
|
||||
{};
|
||||
|
||||
template<typename R, typename Expr, typename State, typename Data
|
||||
, bool IsTransform = is_callable<R>::value
|
||||
>
|
||||
struct make_if_;
|
||||
|
||||
template<typename R, typename Expr, typename State, typename Data
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value)
|
||||
>
|
||||
struct make_
|
||||
{
|
||||
typedef R type;
|
||||
typedef void not_applied_;
|
||||
};
|
||||
|
||||
template<typename R, typename Expr, typename State, typename Data>
|
||||
struct make_if_<R, Expr, State, Data, false>
|
||||
: make_<R, Expr, State, Data>
|
||||
{};
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
|
||||
// work around GCC bug
|
||||
template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data>
|
||||
struct make_if_<proto::expr<Tag, Args, N>, Expr, State, Data, false>
|
||||
{
|
||||
typedef proto::expr<Tag, Args, N> type;
|
||||
typedef void not_applied_;
|
||||
};
|
||||
#endif
|
||||
|
||||
// TODO could optimize this if R is a transform
|
||||
template<typename R, typename Expr, typename State, typename Data>
|
||||
struct make_if_<R, Expr, State, Data, true>
|
||||
: remove_const<typename remove_reference<
|
||||
typename boost::result_of<R(Expr, State, Data)>::type
|
||||
>::type>
|
||||
{};
|
||||
|
||||
template<typename Type, bool IsAggregate = is_aggregate<Type>::value>
|
||||
struct construct_
|
||||
{
|
||||
typedef Type result_type;
|
||||
|
||||
Type operator ()() const
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
#define TMP(Z, N, DATA) \
|
||||
template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
|
||||
Type operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \
|
||||
{ \
|
||||
return Type(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~)
|
||||
#undef TMP
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
struct construct_<Type, true>
|
||||
{
|
||||
typedef Type result_type;
|
||||
|
||||
Type operator ()() const
|
||||
{
|
||||
return Type();
|
||||
}
|
||||
|
||||
#define TMP(Z, N, DATA) \
|
||||
template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
|
||||
Type operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \
|
||||
{ \
|
||||
Type that = {BOOST_PP_ENUM_PARAMS_Z(Z, N, a)}; \
|
||||
return that; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~)
|
||||
#undef TMP
|
||||
};
|
||||
|
||||
#define TMP(Z, N, DATA) \
|
||||
template<typename Type BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, typename A)> \
|
||||
Type construct(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) \
|
||||
{ \
|
||||
return construct_<Type>()(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \
|
||||
}
|
||||
BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, TMP, ~)
|
||||
#undef TMP
|
||||
}
|
||||
|
||||
/// \brief A PrimitiveTransform which prevents another PrimitiveTransform
|
||||
/// from being applied in an \c ObjectTransform.
|
||||
///
|
||||
/// When building higher order transforms with <tt>make\<\></tt> or
|
||||
/// <tt>lazy\<\></tt>, you sometimes would like to build types that
|
||||
/// are parameterized with Proto transforms. In such lambda-style
|
||||
/// transforms, Proto will unhelpfully find all nested transforms
|
||||
/// and apply them, even if you don't want them to be applied. Consider
|
||||
/// the following transform, which will replace the \c _ in
|
||||
/// <tt>Bar<_>()</tt> with <tt>proto::terminal\<int\>::type</tt>:
|
||||
///
|
||||
/// \code
|
||||
/// template<typename T>
|
||||
/// struct Bar
|
||||
/// {};
|
||||
///
|
||||
/// struct Foo
|
||||
/// : proto::when<_, Bar<_>() >
|
||||
/// {};
|
||||
///
|
||||
/// proto::terminal<int>::type i = {0};
|
||||
///
|
||||
/// int main()
|
||||
/// {
|
||||
/// Foo()(i);
|
||||
/// std::cout << typeid(Foo()(i)).name() << std::endl;
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// If you actually wanted to default-construct an object of type
|
||||
/// <tt>Bar\<_\></tt>, you would have to protect the \c _ to prevent
|
||||
/// it from being applied. You can use <tt>proto::protect\<\></tt>
|
||||
/// as follows:
|
||||
///
|
||||
/// \code
|
||||
/// // OK: replace anything with Bar<_>()
|
||||
/// struct Foo
|
||||
/// : proto::when<_, Bar<protect<_> >() >
|
||||
/// {};
|
||||
/// \endcode
|
||||
template<typename PrimitiveTransform>
|
||||
struct protect : transform<protect<PrimitiveTransform> >
|
||||
{
|
||||
template<typename, typename, typename>
|
||||
struct impl
|
||||
{
|
||||
typedef PrimitiveTransform result_type;
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief A PrimitiveTransform which computes a type by evaluating any
|
||||
/// nested transforms and then constructs an object of that type.
|
||||
///
|
||||
/// The <tt>make\<\></tt> transform checks to see if \c Object is a template.
|
||||
/// If it is, the template type is disassembled to find nested transforms.
|
||||
/// Proto considers the following types to represent transforms:
|
||||
///
|
||||
/// \li Function types
|
||||
/// \li Function pointer types
|
||||
/// \li Types for which <tt>proto::is_callable\< type \>::::value</tt> is \c true
|
||||
///
|
||||
/// <tt>make\<T\<X0,X1,...\> \>::::result\<void(Expr, State, Data)\>::::type</tt>
|
||||
/// is evaluated as follows. For each \c X in <tt>X0,X1,...</tt>, do:
|
||||
///
|
||||
/// \li If \c X is a template like <tt>U\<Y0,Y1,...\></tt>, then let <tt>X'</tt>
|
||||
/// be <tt>make\<U\<Y0,Y1,...\> \>::::result\<void(Expr, State, Data)\>::::type</tt>
|
||||
/// (which evaluates this procedure recursively). Note whether any
|
||||
/// substitutions took place during this operation.
|
||||
/// \li Otherwise, if \c X is a transform, then let <tt>X'</tt> be
|
||||
/// <tt>when\<_, X\>::::result\<void(Expr, State, Data)\>::::type</tt>.
|
||||
/// Note that a substitution took place.
|
||||
/// \li Otherwise, let <tt>X'</tt> be \c X, and note that no substitution
|
||||
/// took place.
|
||||
/// \li If any substitutions took place in any of the above steps and
|
||||
/// <tt>T\<X0',X1',...\></tt> has a nested <tt>::type</tt> typedef,
|
||||
/// the result type is <tt>T\<X0',X1',...\>::::type</tt>.
|
||||
/// \li Otherwise, the result type is <tt>T\<X0',X1',...\></tt>.
|
||||
///
|
||||
/// Note that <tt>when\<\></tt> is implemented in terms of <tt>call\<\></tt>
|
||||
/// and <tt>make\<\></tt>, so the above procedure is evaluated recursively.
|
||||
template<typename Object>
|
||||
struct make : transform<make<Object> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
|
||||
|
||||
/// \return <tt>result_type()</tt>
|
||||
result_type operator ()(
|
||||
typename impl::expr_param
|
||||
, typename impl::state_param
|
||||
, typename impl::data_param
|
||||
) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/make.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Object>
|
||||
struct is_callable<make<Object> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename PrimitiveTransform>
|
||||
struct is_callable<protect<PrimitiveTransform> >
|
||||
: mpl::true_
|
||||
{};
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#if N > 0
|
||||
template<typename T BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
|
||||
struct nested_type_if<
|
||||
T
|
||||
, typelist<BOOST_PP_ENUM_PARAMS(N, A)>
|
||||
, typename typelist<
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(N, typename A, ::not_applied_ BOOST_PP_INTERCEPT)
|
||||
>::type
|
||||
>
|
||||
{
|
||||
typedef T type;
|
||||
typedef void not_applied_;
|
||||
};
|
||||
|
||||
#define TMP0(Z, M, DATA) make_if_<BOOST_PP_CAT(A, M), Expr, State, Data>
|
||||
#define TMP1(Z, M, DATA) typename TMP0(Z, M, DATA) ::type
|
||||
|
||||
template<
|
||||
template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class R
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
|
||||
, typename Expr, typename State, typename Data
|
||||
>
|
||||
struct make_<R<BOOST_PP_ENUM_PARAMS(N, A)>, Expr, State, Data
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)
|
||||
>
|
||||
: nested_type_if<
|
||||
R<BOOST_PP_ENUM(N, TMP1, ~)>
|
||||
, typelist<BOOST_PP_ENUM(N, TMP0, ~) >
|
||||
>
|
||||
{};
|
||||
|
||||
template<
|
||||
template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class R
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
|
||||
, typename Expr, typename State, typename Data
|
||||
>
|
||||
struct make_<noinvoke<R<BOOST_PP_ENUM_PARAMS(N, A)> >, Expr, State, Data
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)
|
||||
>
|
||||
{
|
||||
typedef R<BOOST_PP_ENUM(N, TMP1, ~)> type;
|
||||
};
|
||||
|
||||
#undef TMP0
|
||||
#undef TMP1
|
||||
#endif
|
||||
|
||||
template<
|
||||
typename R
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
|
||||
, typename Expr, typename State, typename Data
|
||||
>
|
||||
struct make_if_<R(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data, false>
|
||||
{
|
||||
typedef
|
||||
typename remove_const<
|
||||
typename remove_reference<
|
||||
typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
::template impl<Expr, State, Data>::result_type
|
||||
>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<
|
||||
typename R
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
|
||||
, typename Expr, typename State, typename Data
|
||||
>
|
||||
struct make_if_<R(*)(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data, false>
|
||||
{
|
||||
typedef
|
||||
typename remove_const<
|
||||
typename remove_reference<
|
||||
typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
::template impl<Expr, State, Data>::result_type
|
||||
>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename T, typename A>
|
||||
struct construct_<proto::expr<T, A, N>, true>
|
||||
{
|
||||
typedef proto::expr<T, A, N> result_type;
|
||||
|
||||
template<BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), typename A)>
|
||||
result_type operator ()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_MAX(N, 1), A, &a)) const
|
||||
{
|
||||
return result_type::make(BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), a));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief A PrimitiveTransform which computes a type by evaluating any
|
||||
/// nested transforms and then constructs an object of that type with the
|
||||
/// current expression, state and data, transformed according
|
||||
/// to \c A0 through \c AN.
|
||||
template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
|
||||
struct make<Object(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
: transform<make<Object(BOOST_PP_ENUM_PARAMS(N, A))> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
/// \brief <tt>make\<Object\>::::result\<void(Expr, State, Data)\>::::type</tt>
|
||||
typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
|
||||
//typedef typename detail::make_<Object, Expr, State, Data>::type result_type;
|
||||
|
||||
/// Let \c ax be <tt>when\<_, Ax\>()(e, s, d)</tt>
|
||||
/// for each \c x in <tt>[0,N]</tt>.
|
||||
/// Let \c T be <tt>result\<void(Expr, State, Data)\>::::type</tt>.
|
||||
/// Return <tt>T(a0, a1,... aN)</tt>.
|
||||
///
|
||||
/// \param e The current expression
|
||||
/// \param s The current state
|
||||
/// \param d An arbitrary data
|
||||
result_type operator ()(
|
||||
typename impl::expr_param e
|
||||
, typename impl::state_param s
|
||||
, typename impl::data_param d
|
||||
) const
|
||||
{
|
||||
proto::detail::ignore_unused(e);
|
||||
proto::detail::ignore_unused(s);
|
||||
proto::detail::ignore_unused(d);
|
||||
return detail::construct<result_type>(
|
||||
#define TMP(Z, M, DATA) \
|
||||
detail::as_lvalue( \
|
||||
typename when<_, BOOST_PP_CAT(A, M)> \
|
||||
::template impl<Expr, State, Data>()(e, s, d) \
|
||||
)
|
||||
BOOST_PP_ENUM(N, TMP, DATA)
|
||||
#undef TMP
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
|
||||
// work around GCC bug
|
||||
template<typename Tag, typename Args, long Arity BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
|
||||
struct make<proto::expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
: transform<make<proto::expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef proto::expr<Tag, Args, Arity> result_type;
|
||||
|
||||
result_type operator ()(
|
||||
typename impl::expr_param e
|
||||
, typename impl::state_param s
|
||||
, typename impl::data_param d
|
||||
) const
|
||||
{
|
||||
return proto::expr<Tag, Args, Arity>::make(
|
||||
#define TMP(Z, M, DATA) \
|
||||
detail::as_lvalue( \
|
||||
typename when<_, BOOST_PP_CAT(A, M)> \
|
||||
::template impl<Expr, State, Data>()(e, s, d) \
|
||||
)
|
||||
BOOST_PP_ENUM(N, TMP, DATA)
|
||||
#undef TMP
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
196
libraries/include/boost/proto/transform/pass_through.hpp
Normal file
196
libraries/include/boost/proto/transform/pass_through.hpp
Normal file
@@ -0,0 +1,196 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file pass_through.hpp
|
||||
///
|
||||
/// Definition of the pass_through transform, which is the default transform
|
||||
/// of all of the expression generator metafunctions such as unary_plus<>, plus<>
|
||||
/// and nary_expr<>.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_PASS_THROUGH_HPP_EAN_12_26_2006
|
||||
#define BOOST_PROTO_TRANSFORM_PASS_THROUGH_HPP_EAN_12_26_2006
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/args.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<
|
||||
typename Grammar
|
||||
, typename Expr
|
||||
, typename State
|
||||
, typename Data
|
||||
, long Arity = arity_of<Expr>::value
|
||||
>
|
||||
struct pass_through_impl
|
||||
{};
|
||||
|
||||
#define BOOST_PROTO_DEFINE_TRANSFORM_TYPE(Z, N, DATA) \
|
||||
typename Grammar::BOOST_PP_CAT(proto_child, N)::template impl< \
|
||||
typename result_of::child_c<Expr, N>::type \
|
||||
, State \
|
||||
, Data \
|
||||
>::result_type
|
||||
|
||||
#define BOOST_PROTO_DEFINE_TRANSFORM(Z, N, DATA) \
|
||||
typename Grammar::BOOST_PP_CAT(proto_child, N)::template impl< \
|
||||
typename result_of::child_c<Expr, N>::type \
|
||||
, State \
|
||||
, Data \
|
||||
>()( \
|
||||
e.proto_base().BOOST_PP_CAT(child, N), s, d \
|
||||
)
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/pass_through.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_PROTO_DEFINE_TRANSFORM
|
||||
#undef BOOST_PROTO_DEFINE_TRANSFORM_TYPE
|
||||
|
||||
template<typename Grammar, typename Expr, typename State, typename Data>
|
||||
struct pass_through_impl<Grammar, Expr, State, Data, 0>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef Expr result_type;
|
||||
|
||||
/// \param e An expression
|
||||
/// \return \c e
|
||||
/// \throw nothrow
|
||||
#ifdef BOOST_HAS_DECLTYPE
|
||||
result_type
|
||||
#else
|
||||
typename pass_through_impl::expr_param
|
||||
#endif
|
||||
operator()(
|
||||
typename pass_through_impl::expr_param e
|
||||
, typename pass_through_impl::state_param
|
||||
, typename pass_through_impl::data_param
|
||||
) const
|
||||
{
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief A PrimitiveTransform that transforms the child expressions
|
||||
/// of an expression node according to the corresponding children of
|
||||
/// a Grammar.
|
||||
///
|
||||
/// Given a Grammar such as <tt>plus\<T0, T1\></tt>, an expression type
|
||||
/// that matches the grammar such as <tt>plus\<E0, E1\>::::type</tt>, a
|
||||
/// state \c S and a data \c V, the result of applying the
|
||||
/// <tt>pass_through\<plus\<T0, T1\> \></tt> transform is:
|
||||
///
|
||||
/// \code
|
||||
/// plus<
|
||||
/// T0::result<void(E0, S, V)>::type
|
||||
/// , T1::result<void(E1, S, V)>::type
|
||||
/// >::type
|
||||
/// \endcode
|
||||
///
|
||||
/// The above demonstrates how child transforms and child expressions
|
||||
/// are applied pairwise, and how the results are reassembled into a new
|
||||
/// expression node with the same tag type as the original.
|
||||
///
|
||||
/// The explicit use of <tt>pass_through\<\></tt> is not usually needed,
|
||||
/// since the expression generator metafunctions such as
|
||||
/// <tt>plus\<\></tt> have <tt>pass_through\<\></tt> as their default
|
||||
/// transform. So, for instance, these are equivalent:
|
||||
///
|
||||
/// \code
|
||||
/// // Within a grammar definition, these are equivalent:
|
||||
/// when< plus<X, Y>, pass_through< plus<X, Y> > >
|
||||
/// when< plus<X, Y>, plus<X, Y> >
|
||||
/// when< plus<X, Y> > // because of when<class X, class Y=X>
|
||||
/// plus<X, Y> // because plus<> is both a
|
||||
/// // grammar and a transform
|
||||
/// \endcode
|
||||
///
|
||||
/// For example, consider the following transform that promotes all
|
||||
/// \c float terminals in an expression to \c double.
|
||||
///
|
||||
/// \code
|
||||
/// // This transform finds all float terminals in an expression and promotes
|
||||
/// // them to doubles.
|
||||
/// struct Promote
|
||||
/// : or_<
|
||||
/// when<terminal<float>, terminal<double>::type(_value) >
|
||||
/// // terminal<>'s default transform is a no-op:
|
||||
/// , terminal<_>
|
||||
/// // nary_expr<> has a pass_through<> transform:
|
||||
/// , nary_expr<_, vararg<Promote> >
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
template<typename Grammar>
|
||||
struct pass_through
|
||||
: transform<pass_through<Grammar> >
|
||||
{
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: detail::pass_through_impl<Grammar, Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
template<typename Grammar>
|
||||
struct is_callable<pass_through<Grammar> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
}} // namespace boost::proto
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template<typename Grammar, typename Expr, typename State, typename Data>
|
||||
struct pass_through_impl<Grammar, Expr, State, Data, N>
|
||||
: transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef proto::expr<
|
||||
typename remove_reference<Expr>::type::proto_tag
|
||||
, BOOST_PP_CAT(list, N)<
|
||||
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM_TYPE, ~)
|
||||
>
|
||||
> result_type;
|
||||
|
||||
result_type operator ()(
|
||||
typename pass_through_impl::expr_param e
|
||||
, typename pass_through_impl::state_param s
|
||||
, typename pass_through_impl::data_param d
|
||||
) const
|
||||
{
|
||||
result_type that = {
|
||||
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM, ~)
|
||||
};
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
|
||||
// Without this, MSVC complains that "that" is uninitialized,
|
||||
// and it actually triggers a runtime check in debug mode when
|
||||
// built with VC8.
|
||||
&that;
|
||||
#endif
|
||||
return that;
|
||||
}
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
189
libraries/include/boost/proto/transform/when.hpp
Normal file
189
libraries/include/boost/proto/transform/when.hpp
Normal file
@@ -0,0 +1,189 @@
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file when.hpp
|
||||
/// Definition of when transform.
|
||||
//
|
||||
// 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_PROTO_TRANSFORM_WHEN_HPP_EAN_10_29_2007
|
||||
#define BOOST_PROTO_TRANSFORM_WHEN_HPP_EAN_10_29_2007
|
||||
|
||||
#include <boost/proto/detail/prefix.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/proto/proto_fwd.hpp>
|
||||
#include <boost/proto/traits.hpp>
|
||||
#include <boost/proto/transform/call.hpp>
|
||||
#include <boost/proto/transform/make.hpp>
|
||||
#include <boost/proto/transform/impl.hpp>
|
||||
#include <boost/proto/detail/suffix.hpp>
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
/// \brief A grammar element and a PrimitiveTransform that associates
|
||||
/// a transform with the grammar.
|
||||
///
|
||||
/// Use <tt>when\<\></tt> to override a grammar's default transform
|
||||
/// with a custom transform. It is for used when composing larger
|
||||
/// transforms by associating smaller transforms with individual
|
||||
/// rules in your grammar, as in the following transform which
|
||||
/// counts the number of terminals in an expression.
|
||||
///
|
||||
/// \code
|
||||
/// // Count the terminals in an expression tree.
|
||||
/// // Must be invoked with initial state == mpl::int_<0>().
|
||||
/// struct CountLeaves
|
||||
/// : or_<
|
||||
/// when<terminal<_>, mpl::next<_state>()>
|
||||
/// , otherwise<fold<_, _state, CountLeaves> >
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
///
|
||||
/// In <tt>when\<G, T\></tt>, when \c T is a class type it is a
|
||||
/// PrimitiveTransform and the following equivalencies hold:
|
||||
///
|
||||
/// <tt>when\<G,T\>::::result\<void(E,S,V)\>::::type</tt> is the same as
|
||||
/// <tt>T::result\<void(E,S,V)\>::::type</tt>.
|
||||
///
|
||||
/// <tt>when\<G,T\>()(e,s,v)</tt> is the same as
|
||||
/// <tt>T()(e,s,v)</tt>.
|
||||
template<typename Grammar, typename PrimitiveTransform BOOST_PROTO_WHEN_BUILDING_DOCS(= Grammar)>
|
||||
struct when
|
||||
: PrimitiveTransform
|
||||
{
|
||||
typedef typename Grammar::proto_base_expr proto_base_expr;
|
||||
};
|
||||
|
||||
/// \brief A specialization that treats function pointer Transforms as
|
||||
/// if they were function type Transforms.
|
||||
///
|
||||
/// This specialization requires that \c Fun is actually a function type.
|
||||
///
|
||||
/// This specialization is required for nested transforms such as
|
||||
/// <tt>when\<G, T0(T1(_))\></tt>. In C++, functions that are used as
|
||||
/// parameters to other functions automatically decay to funtion
|
||||
/// pointer types. In other words, the type <tt>T0(T1(_))</tt> is
|
||||
/// indistinguishable from <tt>T0(T1(*)(_))</tt>. This specialization
|
||||
/// is required to handle these nested function pointer type transforms
|
||||
/// properly.
|
||||
template<typename Grammar, typename Fun>
|
||||
struct when<Grammar, Fun *>
|
||||
: when<Grammar, Fun>
|
||||
{};
|
||||
|
||||
/// \brief Syntactic sugar for <tt>when\<_, Fun\></tt>, for use
|
||||
/// in grammars to handle all the cases not yet handled.
|
||||
///
|
||||
/// Use <tt>otherwise\<T\></tt> in your grammars as a synonym for
|
||||
/// <tt>when\<_, T\></tt> as in the following transform which
|
||||
/// counts the number of terminals in an expression.
|
||||
///
|
||||
/// \code
|
||||
/// // Count the terminals in an expression tree.
|
||||
/// // Must be invoked with initial state == mpl::int_<0>().
|
||||
/// struct CountLeaves
|
||||
/// : or_<
|
||||
/// when<terminal<_>, mpl::next<_state>()>
|
||||
/// , otherwise<fold<_, _state, CountLeaves> >
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
template<typename Fun>
|
||||
struct otherwise
|
||||
: when<_, Fun>
|
||||
{};
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/when.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
}} // namespace boost::proto
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
/// \brief A grammar element and a PrimitiveTransform that associates
|
||||
/// a transform with the grammar.
|
||||
///
|
||||
/// Use <tt>when\<\></tt> to override a grammar's default transform
|
||||
/// with a custom transform. It is for used when composing larger
|
||||
/// transforms by associating smaller transforms with individual
|
||||
/// rules in your grammar, as in the following transform which
|
||||
/// counts the number of terminals in an expression.
|
||||
///
|
||||
/// \code
|
||||
/// // Count the terminals in an expression tree.
|
||||
/// // Must be invoked with initial state == mpl::int_<0>().
|
||||
/// struct CountLeaves
|
||||
/// : or_<
|
||||
/// when<terminal<_>, mpl::next<_state>()>
|
||||
/// , otherwise<fold<_, _state, CountLeaves> >
|
||||
/// >
|
||||
/// {};
|
||||
/// \endcode
|
||||
///
|
||||
/// The <tt>when\<G, R(A0,A1,...)\></tt> form accepts either a
|
||||
/// CallableTransform or an ObjectTransform as its second parameter.
|
||||
/// <tt>when\<\></tt> uses <tt>is_callable\<R\>::::value</tt> to
|
||||
/// distinguish between the two, and uses <tt>call\<\></tt> to
|
||||
/// evaluate CallableTransforms and <tt>make\<\></tt> to evaluate
|
||||
/// ObjectTransforms.
|
||||
template<typename Grammar, typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
|
||||
struct when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
: transform<when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))> >
|
||||
{
|
||||
typedef typename Grammar::proto_base_expr proto_base_expr;
|
||||
|
||||
// Note: do not evaluate is_callable<R> in this scope.
|
||||
// R may be an incomplete type at this point.
|
||||
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl : transform_impl<Expr, State, Data>
|
||||
{
|
||||
typedef call<R(BOOST_PP_ENUM_PARAMS(N, A))> call_;
|
||||
typedef make<R(BOOST_PP_ENUM_PARAMS(N, A))> make_;
|
||||
|
||||
typedef
|
||||
typename mpl::if_c<
|
||||
// OK to evaluate is_callable<R> here.
|
||||
// R should be compete by now.
|
||||
is_callable<R>::value
|
||||
, call_ // "R" is a function to call
|
||||
, make_ // "R" is an object to construct
|
||||
>::type
|
||||
which;
|
||||
|
||||
typedef typename which::template impl<Expr, State, Data>::result_type result_type;
|
||||
|
||||
/// Evaluate <tt>R(A0,A1,...)</tt> as a transform either with
|
||||
/// <tt>call\<\></tt> or with <tt>make\<\></tt> depending on
|
||||
/// whether <tt>is_callable\<R\>::::value</tt> is \c true or
|
||||
/// \c false.
|
||||
///
|
||||
/// \param e The current expression
|
||||
/// \param s The current state
|
||||
/// \param d An arbitrary data
|
||||
/// \pre <tt>matches\<Expr, Grammar\>::::value</tt> is \c true
|
||||
/// \return <tt>result\<void(Expr, State, Data)\>::::impl()(e, s, d)</tt>
|
||||
result_type operator ()(
|
||||
typename impl::expr_param e
|
||||
, typename impl::state_param s
|
||||
, typename impl::data_param d
|
||||
) const
|
||||
{
|
||||
return typename which::template impl<Expr, State, Data>()(e, s, d);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user