307 lines
14 KiB
XML
307 lines
14 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
Copyright 2012 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)
|
|
-->
|
|
<header name="boost/proto/transform/impl.hpp">
|
|
<para>Contains definition of transform<> and transform_impl<> helpers. </para>
|
|
<namespace name="boost">
|
|
<namespace name="proto">
|
|
|
|
<!-- proto::transform -->
|
|
<struct name="transform">
|
|
<template>
|
|
<template-type-parameter name="PrimitiveTransform"/>
|
|
</template>
|
|
<purpose>Inherit from this to make your type a <conceptname>PrimitiveTransform</conceptname>.</purpose>
|
|
<struct-specialization name="result">
|
|
<template>
|
|
<template-type-parameter name="This"/>
|
|
<template-type-parameter name="Expr"/>
|
|
</template>
|
|
<specialization>
|
|
<template-arg>This(Expr)</template-arg>
|
|
</specialization>
|
|
<typedef name="type">
|
|
<type>typename PrimitiveTransform::template impl< Expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable> >::result_type</type>
|
|
</typedef>
|
|
</struct-specialization>
|
|
<struct-specialization name="result">
|
|
<template>
|
|
<template-type-parameter name="This"/>
|
|
<template-type-parameter name="Expr"/>
|
|
<template-type-parameter name="State"/>
|
|
</template>
|
|
<specialization>
|
|
<template-arg>This(Expr, State)</template-arg>
|
|
</specialization>
|
|
<typedef name="type">
|
|
<type>typename PrimitiveTransform::template impl< Expr, State, <replaceable>unspecified</replaceable> >::result_type</type>
|
|
</typedef>
|
|
</struct-specialization>
|
|
<struct-specialization name="result">
|
|
<template>
|
|
<template-type-parameter name="This"/>
|
|
<template-type-parameter name="Expr"/>
|
|
<template-type-parameter name="State"/>
|
|
<template-type-parameter name="Data"/>
|
|
</template>
|
|
<specialization>
|
|
<template-arg>This(Expr, State, Data)</template-arg>
|
|
</specialization>
|
|
<typedef name="type">
|
|
<type>typename PrimitiveTransform::template impl< Expr, State, Data >::result_type</type>
|
|
</typedef>
|
|
</struct-specialization>
|
|
<typedef name="transform_type">
|
|
<type>PrimitiveTransform</type>
|
|
</typedef>
|
|
<method-group name="public member functions">
|
|
<method name="operator()" cv="const">
|
|
<type>typename PrimitiveTransform::template impl<Expr &, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>>::result_type</type>
|
|
<template>
|
|
<template-type-parameter name="Expr"/>
|
|
</template>
|
|
<parameter name="expr">
|
|
<paramtype>Expr &</paramtype>
|
|
</parameter>
|
|
<returns>
|
|
<computeroutput>
|
|
typename PrimitiveTransform::template impl<Expr &, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>>()(expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>)
|
|
</computeroutput>
|
|
</returns>
|
|
</method>
|
|
<method name="operator()" cv="const">
|
|
<type>typename PrimitiveTransform::template impl<Expr &, State &, <replaceable>unspecified</replaceable>>::result_type</type>
|
|
<template>
|
|
<template-type-parameter name="Expr"/>
|
|
<template-type-parameter name="State"/>
|
|
</template>
|
|
<parameter name="expr">
|
|
<paramtype>Expr &</paramtype>
|
|
</parameter>
|
|
<parameter name="state">
|
|
<paramtype>State &</paramtype>
|
|
</parameter>
|
|
<returns>
|
|
<computeroutput>
|
|
typename PrimitiveTransform::template impl<Expr &, State &, <replaceable>unspecified</replaceable>>()(expr, state, <replaceable>unspecified</replaceable>)
|
|
</computeroutput>
|
|
</returns>
|
|
</method>
|
|
<method name="operator()" cv="const">
|
|
<type>typename PrimitiveTransform::template impl<Expr &, State const &, <replaceable>unspecified</replaceable>>::result_type</type>
|
|
<template>
|
|
<template-type-parameter name="Expr"/>
|
|
<template-type-parameter name="State"/>
|
|
</template>
|
|
<parameter name="expr">
|
|
<paramtype>Expr &</paramtype>
|
|
</parameter>
|
|
<parameter name="state">
|
|
<paramtype>State const &</paramtype>
|
|
</parameter>
|
|
<returns>
|
|
<computeroutput>
|
|
typename PrimitiveTransform::template impl<Expr &, State const &, <replaceable>unspecified</replaceable>>()(expr, state, <replaceable>unspecified</replaceable>)
|
|
</computeroutput>
|
|
</returns>
|
|
</method>
|
|
<method name="operator()" cv="const">
|
|
<type>typename PrimitiveTransform::template impl<Expr &, State &, Data &>::result_type</type>
|
|
<template>
|
|
<template-type-parameter name="Expr"/>
|
|
<template-type-parameter name="State"/>
|
|
<template-type-parameter name="Data"/>
|
|
</template>
|
|
<parameter name="expr">
|
|
<paramtype>Expr &</paramtype>
|
|
</parameter>
|
|
<parameter name="state">
|
|
<paramtype>State &</paramtype>
|
|
</parameter>
|
|
<parameter name="data">
|
|
<paramtype>Data &</paramtype>
|
|
</parameter>
|
|
<returns>
|
|
<computeroutput>
|
|
typename PrimitiveTransform::template impl<Expr &, State &, Data &>()(expr, state, data)
|
|
</computeroutput>
|
|
</returns>
|
|
</method>
|
|
<method name="operator()" cv="const">
|
|
<type>typename PrimitiveTransform::template impl<Expr &, State const &, Data &>::result_type</type>
|
|
<template>
|
|
<template-type-parameter name="Expr"/>
|
|
<template-type-parameter name="State"/>
|
|
<template-type-parameter name="Data"/>
|
|
</template>
|
|
<parameter name="expr">
|
|
<paramtype>Expr &</paramtype>
|
|
</parameter>
|
|
<parameter name="state">
|
|
<paramtype>State const &</paramtype>
|
|
</parameter>
|
|
<parameter name="data">
|
|
<paramtype>Data &</paramtype>
|
|
</parameter>
|
|
<returns>
|
|
<computeroutput>
|
|
typename PrimitiveTransform::template impl<Expr &, State const &, Data &>()(expr, state, data)
|
|
</computeroutput>
|
|
</returns>
|
|
</method>
|
|
</method-group>
|
|
</struct>
|
|
|
|
<!-- proto::transform_impl -->
|
|
<struct name="transform_impl">
|
|
<template>
|
|
<template-type-parameter name="Expr"/>
|
|
<template-type-parameter name="State"/>
|
|
<template-type-parameter name="Data"/>
|
|
</template>
|
|
<typedef name="expr">
|
|
<type>typename boost::remove_reference<Expr const>::type</type>
|
|
</typedef>
|
|
<typedef name="expr_param">
|
|
<type>typename boost::add_reference<Expr const>::type</type>
|
|
</typedef>
|
|
<typedef name="state">
|
|
<type>typename boost::remove_reference<State const>::type</type>
|
|
</typedef>
|
|
<typedef name="state_param">
|
|
<type>typename boost::add_reference<State const>::type</type>
|
|
</typedef>
|
|
<typedef name="data">
|
|
<type>typename boost::remove_reference<Data const>::type</type>
|
|
</typedef>
|
|
<typedef name="data_param">
|
|
<type>typename boost::add_reference<Data const>::type</type>
|
|
</typedef>
|
|
</struct>
|
|
|
|
<!-- proto::pack -->
|
|
<struct name="pack">
|
|
<purpose>To turn an expression into a pseudo-parameter pack containing the
|
|
expression's children, for the purpose of expanding the pack expression within
|
|
a <conceptname>CallableTransform</conceptname> or
|
|
<conceptname>ObjectTransform</conceptname>.</purpose>
|
|
<description>
|
|
<para>
|
|
<computeroutput>proto::pack</computeroutput> is useful within
|
|
<conceptname>CallableTransform</conceptname>s and
|
|
<conceptname>ObjectTransform</conceptname>s when one wishes to unpack an expression
|
|
into a function call or an object constructor. <computeroutput>proto::pack</computeroutput>
|
|
turns a Proto expression into a pseudo-parameter pack, which may appear in an unpacking
|
|
pattern to be expanded with the "<computeroutput>...</computeroutput>" syntax.
|
|
</para>
|
|
|
|
<para>
|
|
<emphasis role="bold">Example:</emphasis>
|
|
</para>
|
|
|
|
<para>
|
|
<programlisting>// The following demonstrates how to use a pseudo-pack expansion
|
|
// to unpack an expression into a function call.
|
|
|
|
struct do_sum : <classname alt="boost::proto::callable">proto::callable</classname>
|
|
{
|
|
typedef int result_type;
|
|
|
|
int operator()(int i) const { return i; }
|
|
int operator()(int i, int j) const { return i + j; }
|
|
int operator()(int i, int j, int k) const { return i + j + k; }
|
|
};
|
|
|
|
// Take any n-ary expression where the children are all int terminals and sum all the ints
|
|
struct sum
|
|
: <classname alt="boost::proto::when">proto::when</classname><
|
|
|
|
// Match any nary expression where the children are all int terminals
|
|
<classname alt="boost::proto::nary_expr">proto::nary_expr</classname><<classname alt="boost::proto::_">_</classname>, <classname alt="boost::proto::vararg">proto::vararg</classname><<classname alt="boost::proto::terminal">proto::terminal</classname><int> > >
|
|
|
|
// Turn the current expression into a pseudo-parameter pack, then expand it,
|
|
// extracting the value from each child in turn.
|
|
, do_sum(<classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>))...)
|
|
>
|
|
{};
|
|
|
|
int main()
|
|
{
|
|
<classname alt="boost::proto::terminal">proto::terminal</classname><int>::type i = {42};
|
|
int result = sum()( i(3,5) ); // Creates a ternary functional-call expression
|
|
std::cout << "Sum of 42, 3, and 5 : " << result << std::endl;
|
|
}</programlisting>
|
|
</para>
|
|
|
|
<para>
|
|
The above program displays:
|
|
</para>
|
|
|
|
<para>
|
|
<computeroutput>Sum of 42, 3, and 5 : 50</computeroutput>
|
|
</para>
|
|
|
|
<para>
|
|
In the above example, the type
|
|
<computeroutput>
|
|
<classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>))
|
|
</computeroutput>
|
|
is a so-called <emphasis>unpacking pattern</emphasis>, described below.
|
|
</para>
|
|
|
|
<para>
|
|
<emphasis role="bold">Unpacking Patterns:</emphasis>
|
|
</para>
|
|
|
|
<para>
|
|
Composite transforms (either <conceptname>CallableTransform</conceptname>s or
|
|
<conceptname>ObjectTransform</conceptname>s) usually have the form
|
|
<computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>.
|
|
However, when the argument list in a composite transform is terminated with a C-style
|
|
vararg ellipsis as in <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
|
|
the final argument <computeroutput>A<subscript>n</subscript></computeroutput> is treated
|
|
as an <emphasis>unpacking pattern</emphasis>.
|
|
</para>
|
|
|
|
<para>
|
|
An unpacking pattern must itself be a composite transform; that is, it must be a
|
|
function type representing either a <conceptname>CallableTransform</conceptname> or
|
|
an <conceptname>ObjectTransform</conceptname>. The type <computeroutput>proto::pack(_)</computeroutput>
|
|
must appear exactly once in the unpacking pattern. This type will receive a substitution
|
|
when the unpacking pattern is expanded.
|
|
</para>
|
|
|
|
<para>
|
|
A composite transform like <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
|
|
when evaluated against a given expression <replaceable>E</replaceable>, state and data, is evaluated as if it were
|
|
<computeroutput>X(A<subscript>0</subscript>,…A<subscript>n-1</subscript>,<replaceable>S</replaceable>)</computeroutput>
|
|
where <replaceable>S</replaceable> is a type sequence computed as follows:
|
|
</para>
|
|
<para>
|
|
Let <computeroutput><replaceable>SUB</replaceable>(A,B)</computeroutput> be a type function that replaces every occurence of
|
|
<computeroutput>proto::pack(_)</computeroutput> within <computeroutput>A</computeroutput> with <computeroutput>B</computeroutput>.
|
|
<itemizedlist>
|
|
<listitem>
|
|
If the expression <replaceable>E</replaceable> is a terminal (i.e. it has arity 0), <replaceable>S</replaceable>
|
|
is the one-element sequence containing <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_value">proto::_value</classname>)</computeroutput>.
|
|
</listitem>
|
|
<listitem>
|
|
If the expression <replaceable>E</replaceable> is a non-terminal, <replaceable>S</replaceable> is the sequence
|
|
<computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname><0>),…
|
|
<replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname><<replaceable>M</replaceable>-1>)</computeroutput>, where
|
|
<replaceable>M</replaceable> is the arity of the expression <replaceable>E</replaceable>.
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</description>
|
|
</struct>
|
|
|
|
</namespace>
|
|
</namespace>
|
|
</header>
|