/usr/include/boost/proto/context/callable.hpp is in libboost1.54-dev 1.54.0-4ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | ///////////////////////////////////////////////////////////////////////////////
/// \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/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
namespace boost { namespace proto
{
namespace detail
{
template<typename Context>
struct callable_context_wrapper
: remove_cv<Context>::type
{
callable_context_wrapper();
typedef private_type_ fun_type(...);
operator fun_type *() const;
private:
callable_context_wrapper &operator =(callable_context_wrapper const &);
};
template<typename T>
yes_type check_is_expr_handled(T const &);
no_type check_is_expr_handled(private_type_ const &);
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> &sctx_;
static Expr &sexpr_;
static typename Expr::proto_tag &stag_;
static const 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 // = 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_PROTO_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 // = 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_c<
detail::is_expr_handled<Expr, Context>::value
, callable_eval<Expr, ThisContext>
, typename DefaultCtx::template eval<Expr, Context>
>::type
{};
};
}
#include <boost/proto/context/detail/callable_eval.hpp>
}}
#endif
|