[DEV] add v1.66.0

This commit is contained in:
2018-01-12 21:47:58 +01:00
parent 87059bb1af
commit a97e9ae7d4
49032 changed files with 7668950 additions and 0 deletions

View File

@@ -0,0 +1,485 @@
<?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/arg.hpp">
<para>Contains definition of the childN transforms and friends.</para>
<namespace name="boost">
<namespace name="proto">
<struct name="_expr">
<inherit><classname>proto::transform</classname>&lt; _expr &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns the current expression unmodified. </purpose>
<description>
<para>
Example:
<programlisting><classname>proto::terminal</classname>&lt;int&gt;::type i = {42};
<classname>proto::terminal</classname>&lt;int&gt;::type &amp; j = proto::_expr()(i);
assert( boost::addressof(i) == boost::addressof(j) );</programlisting>
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
<typedef name="result_type">
<type>Expr</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>Expr</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
<description>
<para>The current expression. </para>
</description>
</parameter>
<parameter name="">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<para>
Returns the current expression.
</para>
</description>
<returns>
<para>
<computeroutput>expr</computeroutput>
</para>
</returns>
<throws>
<simpara>Will not throw.</simpara>
</throws>
</method>
</method-group>
</struct>
</struct>
<struct name="_state">
<inherit><classname>proto::transform</classname>&lt; _state &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns the current state unmodified. </purpose>
<description>
<para>
Example:
<programlisting><classname>proto::terminal</classname>&lt;int&gt;::type i = {42};
char ch = proto::_state()(i, 'a');
assert( ch == 'a' );</programlisting>
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
<typedef name="result_type">
<type>State</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>State</type>
<parameter name="">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
<description>
<para>The current state. </para>
</description>
</parameter>
<parameter name="">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<para>
Returns the current state.
</para>
</description>
<returns>
<para>
<computeroutput>state</computeroutput>
</para>
</returns>
<throws>
<simpara>Will not throw.</simpara>
</throws>
</method>
</method-group>
</struct>
</struct>
<struct name="_data">
<inherit><classname>proto::transform</classname>&lt; _data &gt;</inherit>
<purpose>
A <conceptname>PrimitiveTransform</conceptname> that returns the current data unmodified.
If the data (third) parameter is a transform environment, it returns the value associated
with the <code><classname>proto::data_type</classname></code> key. Otherwise, it returns
the data parameter unmodified.
</purpose>
<description>
<para>
If the data (third) parameter is a transform environment, it returns the value associated
with the <code><classname>proto::data_type</classname></code> key. Otherwise, it returns
the data parameter unmodified.
</para>
<para>
<emphasis role="bold">Example:</emphasis>
<programlisting><classname>proto::terminal</classname>&lt;int&gt;::type i = {42};
std::string str("hello");
std::string &amp; d1 = proto::_data()(i, 'a', str);
assert( &amp;str == &amp;d1 );
std::string &amp; d2 = proto::_data()(i, 'a', (<globalname>proto::data</globalname> = boost::ref(str)));
assert( &amp;str == &amp;d2 );</programlisting>
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><type>
mpl::if_c&lt;
<classname>proto::is_env</classname>&lt;Data&gt;::value,
<classname>proto::_env_var</classname>&lt;<classname>proto::data_type</classname>&gt;,
<classname>proto::_env</classname>
&gt;::type::template impl&lt;Expr, State, Data&gt;</type></inherit>
</struct>
</struct>
<struct name="_child_c">
<template>
<template-nontype-parameter name="N">
<type>int</type>
</template-nontype-parameter>
</template>
<inherit><classname>proto::transform</classname>&lt; _child_c&lt;N&gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns N-th child of the current expression. </purpose>
<description>
<para>
Example:
<programlisting><classname>proto::terminal</classname>&lt;int&gt;::type i = {42};
<classname>proto::terminal</classname>&lt;int&gt;::type &amp; j = proto::_child_c&lt;0&gt;()(-i);
assert( boost::addressof(i) == boost::addressof(j) );</programlisting>
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
<typedef name="result_type">
<type>typename <classname>proto::result_of::child_c</classname>&lt; Expr, N &gt;::type</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>typename <classname>proto::result_of::child_c</classname>&lt; Expr, N &gt;::type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
<description>
<para>The current expression. </para>
</description>
</parameter>
<parameter name="">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<para>
Returns the N-th child of <computeroutput>expr</computeroutput>
</para>
</description>
<requires>
<para>
<computeroutput>Expr::proto_arity::value &gt; N</computeroutput>
</para>
</requires>
<returns>
<para>
<computeroutput><functionname>proto::child_c</functionname>&lt;N&gt;(expr)</computeroutput>
</para>
</returns>
<throws>
<simpara>Will not throw.</simpara>
</throws>
</method>
</method-group>
</struct>
</struct>
<struct name="_value">
<inherit><classname>proto::transform</classname>&lt; _value &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns the value of the current terminal expression. </purpose>
<description>
<para>
Example:
<programlisting><classname>proto::terminal</classname>&lt;int&gt;::type i = {42};
int j = proto::_value()(i);
assert( 42 == j );</programlisting>
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
<typedef name="result_type">
<type>typename <classname>proto::result_of::value</classname>&lt; Expr &gt;::type</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>typename <classname>proto::result_of::value</classname>&lt; Expr &gt;::type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
<description>
<para>The current expression. </para>
</description>
</parameter>
<parameter name="">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<para>
Returns the value of the specified terminal expression.
</para>
</description>
<requires>
<para>
<computeroutput>Expr::proto_arity::value == 0</computeroutput>.
</para>
</requires>
<returns>
<para>
<computeroutput><functionname>proto::value</functionname>(expr)</computeroutput>
</para>
</returns>
<throws>
<simpara>Will not throw.</simpara>
</throws>
</method>
</method-group>
</struct>
</struct>
<struct name="_void">
<inherit><classname>proto::transform</classname>&lt; _void &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that does nothing and returns void. </purpose>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
<typedef name="result_type">
<type>void</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>void</type>
<parameter name="">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<para>
Does nothing.
</para>
</description>
<throws>
<simpara>Will not throw.</simpara>
</throws>
</method>
</method-group>
</struct>
</struct>
<struct name="_byref">
<inherit><classname>proto::callable</classname></inherit>
<purpose>A unary callable <conceptname>PolymorphicFunctionObject</conceptname> that wraps its argument
in a <computeroutput>boost::reference_wrapper&lt;&gt;</computeroutput>.</purpose>
<description>
<para>
Example:
<programlisting><classname>proto::terminal</classname>&lt;int&gt;::type i = {42};
boost::reference_wrapper&lt;<classname>proto::terminal</classname>&lt;int&gt;::type&gt; j
= <classname>proto::when</classname>&lt;<classname>proto::_</classname>, proto::_byref(_)&gt;()(i);
assert( boost::addressof(i) == boost::addressof(j.get()) );</programlisting>
</para>
</description>
<struct-specialization name="result">
<template>
<template-type-parameter name="This"/>
<template-type-parameter name="T"/>
</template>
<specialization>
<template-arg>This(T &amp;)</template-arg>
</specialization>
<typedef name="type">
<type>boost::reference_wrapper&lt; T &gt; const</type>
</typedef>
</struct-specialization>
<struct-specialization name="result">
<template>
<template-type-parameter name="This"/>
<template-type-parameter name="T"/>
</template>
<specialization>
<template-arg>This(T)</template-arg>
</specialization>
<typedef name="type">
<type>boost::reference_wrapper&lt; T const &gt; const</type>
</typedef>
</struct-specialization>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>boost::reference_wrapper&lt; T &gt; const</type>
<template>
<template-type-parameter name="T"/>
</template>
<parameter name="t">
<paramtype>T &amp;</paramtype>
<description>
<para>The object to wrap </para>
</description>
</parameter>
<description>
<para>
Wrap the parameter <computeroutput>t</computeroutput> in a
<computeroutput>boost::reference_wrapper&lt;&gt;</computeroutput>
</para>
</description>
<returns>
<para>
<computeroutput>boost::ref(t)</computeroutput>
</para>
</returns>
<throws>
<simpara>Will not throw.</simpara>
</throws>
</method>
<method name="operator()" cv="const">
<type>boost::reference_wrapper&lt; T const &gt; const</type>
<template>
<template-type-parameter name="T"/>
</template>
<parameter name="t">
<paramtype>T const &amp;</paramtype>
</parameter>
<description>
<para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para>
</description>
</method>
</method-group>
</struct>
<struct name="_byval">
<inherit><classname>proto::callable</classname></inherit>
<purpose>
A unary callable <conceptname>PolymorphicFunctionObject</conceptname> that strips references and
<computeroutput>boost::reference_wrapper&lt;&gt;</computeroutput> from its argument.
</purpose>
<description>
<para>
Example:
<programlisting><classname>proto::terminal</classname>&lt;int&gt;::type i = {42};
int j = 67;
int k = <classname>proto::when</classname>&lt;<classname>proto::_</classname>, proto::_byval(<classname>proto::_state</classname>)&gt;()(i, boost::ref(j));
assert( 67 == k );</programlisting>
</para>
</description>
<struct-specialization name="result">
<template>
<template-type-parameter name="This"/>
<template-type-parameter name="T"/>
</template>
<specialization>
<template-arg>This(boost::reference_wrapper&lt; T &gt;)</template-arg>
</specialization>
<inherit>result&lt;This(T)&gt;</inherit>
</struct-specialization>
<struct-specialization name="result">
<template>
<template-type-parameter name="This"/>
<template-type-parameter name="T"/>
</template>
<specialization>
<template-arg>This(T &amp;)</template-arg>
</specialization>
<inherit>result&lt;This(T)&gt;</inherit>
</struct-specialization>
<struct-specialization name="result">
<template>
<template-type-parameter name="This"/>
<template-type-parameter name="T"/>
</template>
<specialization>
<template-arg>This(T)</template-arg>
</specialization>
<typedef name="type">
<type>T</type>
</typedef>
</struct-specialization>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>T</type>
<template>
<template-type-parameter name="T"/>
</template>
<parameter name="t">
<paramtype>T const &amp;</paramtype>
<description>
<para>The object to unref </para>
</description>
</parameter>
<returns>
<para>
<computeroutput>t</computeroutput>
</para>
</returns>
<throws>
<simpara>Will not throw.</simpara>
</throws>
</method>
<method name="operator()" cv="const">
<type>T</type>
<template>
<template-type-parameter name="T"/>
</template>
<parameter name="t">
<paramtype>boost::reference_wrapper&lt; T &gt; const &amp;</paramtype>
</parameter>
<description>
<para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para>
</description>
</method>
</method-group>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,231 @@
<?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/call.hpp">
<para>Contains definition of the call&lt;&gt; transform. </para>
<namespace name="boost">
<namespace name="proto">
<struct name="call">
<template>
<template-type-parameter name="T"/>
</template>
<purpose>Make the given <conceptname>CallableTransform</conceptname> into a <conceptname>PrimitiveTransform</conceptname>.</purpose>
<description>
<para>
The purpose of <computeroutput>proto::call&lt;&gt;</computeroutput> is to annotate a transform as callable
so that <computeroutput><classname alt="proto::when">proto::when&lt;&gt;</classname></computeroutput> knows
how to apply it. The template parameter must be either a <conceptname>PrimitiveTransform</conceptname> or a
<conceptname>CallableTransform</conceptname>; that is, a function type for which the return type is a callable
<conceptname>PolymorphicFunctionObject</conceptname>.
</para>
<para>
For the complete description of the behavior of the <computeroutput>proto::call&lt;&gt;</computeroutput>
transform, see the documentation for the nested
<computeroutput>
<classname alt="proto::call::impl">proto::call::impl&lt;&gt;</classname>
</computeroutput>
class template.
</para>
</description>
<inherit><type><classname>proto::transform</classname>&lt; call&lt;T&gt; &gt;</type></inherit>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><type><classname>proto::transform_impl</classname>&lt;Expr, State, Data&gt;</type></inherit>
<typedef name="result_type">
<type><replaceable>see-below</replaceable></type>
<description>
<para>
In the description that follows, a type <computeroutput>T</computeroutput> is determined to model the
<conceptname>PrimitiveTransform</conceptname> concept if
<computeroutput><classname>proto::is_transform</classname>&lt;T&gt;::value</computeroutput> is
<computeroutput>true</computeroutput>.
</para>
<para>
<computeroutput><classname>proto::call</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::result_type</computeroutput>
is computed as follows:
<itemizedlist>
<listitem>
<para>
If <computeroutput>T</computeroutput> if of the form
<computeroutput><conceptname>PrimitiveTransform</conceptname></computeroutput> or
<computeroutput><conceptname>PrimitiveTransform</conceptname>()</computeroutput>, then
<computeroutput>result_type</computeroutput> is:
<programlisting>typename boost::result_of&lt;PrimitiveTransform(Expr, State, Data)&gt;::type</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>)</computeroutput>, then
<computeroutput>result_type</computeroutput> is:
<programlisting>typename boost::result_of&lt;PrimitiveTransform(
typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;(Expr, State, Data)&gt;::type,
State,
Data
)&gt;::type</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>, A<subscript>1</subscript>)</computeroutput>, then
<computeroutput>result_type</computeroutput> is:
<programlisting>typename boost::result_of&lt;PrimitiveTransform(
typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;(Expr, State, Data)&gt;::type,
typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>1</subscript>&gt;(Expr, State, Data)&gt;::type,
Data
)&gt;::type</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>, A<subscript>1</subscript>, A<subscript>2</subscript>)</computeroutput>, then
<computeroutput>result_type</computeroutput> is:
<programlisting>typename boost::result_of&lt;PrimitiveTransform(
typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;(Expr, State, Data)&gt;::type,
typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>1</subscript>&gt;(Expr, State, Data)&gt;::type,
typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>2</subscript>&gt;(Expr, State, Data)&gt;::type
)&gt;::type</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then
<computeroutput>result_type</computeroutput> is:
<programlisting>typename boost::result_of&lt;PolymorphicFunctionObject(
typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;(Expr, State, Data)&gt;::type,
typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>n</subscript>&gt;(Expr, State, Data)&gt;::type
&gt;::type</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, then
let <computeroutput>T&apos;</computeroutput> be <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>.
Then, <computeroutput>result_type</computeroutput> is:
<programlisting><computeroutput>typename <classname>proto::call</classname>&lt;T&apos;&gt;::impl&lt;Expr,State,Data&gt;::result_type</computeroutput></programlisting>
</para>
</listitem>
</itemizedlist>
</para>
</description>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<para>
In the description that follows, a type <computeroutput>T</computeroutput> is determined to model the
<conceptname>PrimitiveTransform</conceptname> concept if
<computeroutput><classname>proto::is_transform</classname>&lt;T&gt;::value</computeroutput> is
<computeroutput>true</computeroutput>.
</para>
<para>
<computeroutput><classname>proto::call</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::operator()</computeroutput> behaves as follows:
<itemizedlist>
<listitem>
<para>
If <computeroutput>T</computeroutput> if of the form
<computeroutput><conceptname>PrimitiveTransform</conceptname></computeroutput> or
<computeroutput><conceptname>PrimitiveTransform</conceptname>()</computeroutput>, then
return
<programlisting>PrimitiveTransform()(expr, state, data)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>)</computeroutput>, then
return
<programlisting>PrimitiveTransform()(
<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
state,
sata
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>, A<subscript>1</subscript>)</computeroutput>, then
return:
<programlisting>PrimitiveTransform()(
<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
<classname>when</classname>&lt;<classname>_</classname>,A<subscript>1</subscript>&gt;()(expr, state, data),
Data
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>, A<subscript>1</subscript>, A<subscript>2</subscript>)</computeroutput>, then
return
<programlisting>PrimitiveTransform()(
<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
<classname>when</classname>&lt;<classname>_</classname>,A<subscript>1</subscript>&gt;()(expr, state, data),
<classname>when</classname>&lt;<classname>_</classname>,A<subscript>2</subscript>&gt;()(expr, state, data)
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then
return:
<programlisting>PolymorphicFunctionObject()(
<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
...
<classname>when</classname>&lt;<classname>_</classname>,A<subscript>n</subscript>&gt;()(expr, state, data)
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, then
let <computeroutput>T&apos;</computeroutput> be <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>.
Then, return:
<programlisting><computeroutput><classname>proto::call</classname>&lt;T&apos;&gt;()(expr, state, data)</computeroutput></programlisting>
</para>
</listitem>
</itemizedlist>
</para>
</description>
</method>
</method-group>
</struct>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,227 @@
<?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/default.hpp">
<namespace name="boost">
<namespace name="proto">
<struct name="_default">
<template>
<template-type-parameter name="Grammar">
<default><replaceable>unspecified</replaceable></default>
</template-type-parameter>
</template>
<inherit><classname>proto::transform</classname>&lt; _default&lt;Grammar&gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that gives expressions their
usual C++ behavior</purpose>
<description>
<para>
For the complete description of the behavior of the <computeroutput>proto::_default</computeroutput>
transform, see the documentation for the nested <computeroutput>
<classname>proto::_default::impl&lt;&gt;</classname>
</computeroutput> class template.
</para>
<para>
When used without specifying a <computeroutput>Grammar</computeroutput> parameter,
<computeroutput>proto::_default</computeroutput> behaves as if the parameter were
<computeroutput>proto::_default&lt;&gt;</computeroutput>.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><type><classname>proto::transform_impl</classname>&lt;Expr, State, Data&gt;</type></inherit>
<typedef name="Tag">
<purpose>For exposition only</purpose>
<type>typename Expr::tag_type</type>
</typedef>
<data-member name="s_expr" specifiers="static">
<purpose>For exposition only</purpose>
<type>Expr</type>
</data-member>
<data-member name="s_state" specifiers="static">
<purpose>For exposition only</purpose>
<type>State</type>
</data-member>
<data-member name="s_data" specifiers="static">
<purpose>For exposition only</purpose>
<type>Data</type>
</data-member>
<typedef name="result_type">
<type><emphasis>see-below</emphasis></type>
<description>
<itemizedlist>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> corresponds to a unary prefix operator,
then the result type is
<programlisting>decltype(
OP Grammar()(<functionname>proto::child</functionname>(s_expr), s_state, s_data)
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> corresponds to a unary postfix operator,
then the result type is
<programlisting>decltype(
Grammar()(<functionname>proto::child</functionname>(s_expr), s_state, s_data) OP
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> corresponds to a binary infix operator,
then the result type is
<programlisting>decltype(
Grammar()(<functionname>proto::left</functionname>(s_expr), s_state, s_data) OP
Grammar()(<functionname>proto::right</functionname>(s_expr), s_state, s_data)
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> is <computeroutput>
<classname>proto::tag::subscript</classname>
</computeroutput>,
then the result type is
<programlisting>decltype(
Grammar()(<functionname>proto::left</functionname>(s_expr), s_state, s_data) [
Grammar()(<functionname>proto::right</functionname>(s_expr), s_state, s_data) ]
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> is <computeroutput>
<classname>proto::tag::if_else_</classname>
</computeroutput>,
then the result type is
<programlisting>decltype(
Grammar()(<functionname>proto::child_c</functionname>&lt;0&gt;(s_expr), s_state, s_data) ?
Grammar()(<functionname>proto::child_c</functionname>&lt;1&gt;(s_expr), s_state, s_data) :
Grammar()(<functionname>proto::child_c</functionname>&lt;2&gt;(s_expr), s_state, s_data)
)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> is <computeroutput>
<classname>proto::tag::function</classname>
</computeroutput>,
then the result type is
<programlisting>decltype(
Grammar()(<functionname>proto::child_c</functionname>&lt;0&gt;(s_expr), s_state, s_data) (
Grammar()(<functionname>proto::child_c</functionname>&lt;1&gt;(s_expr), s_state, s_data),
...
Grammar()(<functionname>proto::child_c</functionname>&lt;N&gt;(s_expr), s_state, s_data) )
)</programlisting>
</para>
</listitem>
</itemizedlist>
</description>
</typedef>
<description>
<para>
Let <computeroutput><computeroutput>OP</computeroutput></computeroutput> be the C++ operator
corresponding to <computeroutput>Expr::proto_tag</computeroutput>. (For example, if
<computeroutput>Tag</computeroutput> is <computeroutput>
<classname>proto::tag::plus</classname></computeroutput>, let <computeroutput>
<computeroutput>OP</computeroutput></computeroutput> be <computeroutput>+</computeroutput>.)
</para>
</description>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<computeroutput>
<classname>proto::_default</classname>&lt;Grammar&gt;::impl&lt;Expr, State, Data&gt;::operator()
</computeroutput> returns the following:
<itemizedlist>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> corresponds to a unary prefix operator,
then return
<programlisting>OP Grammar()(<functionname>proto::child</functionname>(expr), state, data)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> corresponds to a unary postfix operator,
then return
<programlisting>Grammar()(<functionname>proto::child</functionname>(expr), state, data) OP</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> corresponds to a binary infix operator,
then return
<programlisting>Grammar()(<functionname>proto::left</functionname>(expr), state, data) OP
Grammar()(<functionname>proto::right</functionname>(expr), state, data)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> is <computeroutput>
<classname>proto::tag::subscript</classname>
</computeroutput>,
then return
<programlisting>Grammar()(<functionname>proto::left</functionname>(expr), state, data) [
Grammar()(<functionname>proto::right</functionname>(expr), state, data) ]</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> is <computeroutput>
<classname>proto::tag::if_else_</classname>
</computeroutput>,
then return
<programlisting>Grammar()(<functionname>proto::child_c</functionname>&lt;0&gt;(expr), state, data) ?
Grammar()(<functionname>proto::child_c</functionname>&lt;1&gt;(expr), state, data) :
Grammar()(<functionname>proto::child_c</functionname>&lt;2&gt;(expr), state, data)</programlisting>
</para>
</listitem>
<listitem>
<para>
If <computeroutput>Tag</computeroutput> is <computeroutput>
<classname>proto::tag::function</classname>
</computeroutput>,
then return
<programlisting>Grammar()(<functionname>proto::child_c</functionname>&lt;0&gt;(expr), state, data) (
Grammar()(<functionname>proto::child_c</functionname>&lt;1&gt;(expr), state, data),
...
Grammar()(<functionname>proto::child_c</functionname>&lt;N&gt;(expr), state, data) )</programlisting>
</para>
</listitem>
</itemizedlist>
</description>
</method>
</method-group>
<description>
<para>
The behavior of this class is specified in terms of the C++0x <computeroutput>decltype</computeroutput>
keyword. In systems where this keyword is not available, Proto uses the Boost.Typeof library to
approximate the behavior.
</para>
</description>
</struct>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,775 @@
<?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/env.hpp">
<namespace name="boost">
<namespace name="proto">
<struct name="key_not_found">
<purpose>
The type of objects returned when a key-based lookup fails in a
transform environment.
</purpose>
</struct>
<!-- empty_env -->
<struct name="empty_env">
<purpose>
The type of an object that represents a transform environment
with no key/value pairs in it.
</purpose>
<method-group name="public member functions">
<method name="operator[]" cv="const">
<type><classname>proto::key_not_found</classname></type>
<parameter name="">
<paramtype><replaceable>unspecified</replaceable></paramtype>
</parameter>
<description>
<para>The type of the argument to this function has a
user-defined implicit conversion from any type.</para>
</description>
</method>
</method-group>
</struct>
<!-- env -->
<struct name="env">
<template>
<template-type-parameter name="Key"/>
<template-type-parameter name="Value"/>
<template-type-parameter name="Env">
<default><classname>proto::empty_env</classname></default>
</template-type-parameter>
</template>
<constructor specifiers="explicit">
<parameter name="value">
<paramtype>Value const &amp;</paramtype>
<description>
<para>
The value to be associated with the <code>Key</code>.
</para>
</description>
</parameter>
<parameter name="other">
<paramtype>Env const &amp;</paramtype>
<default>Env()</default>
<description>
<para>
Another key/value store.
</para>
</description>
</parameter>
</constructor>
<method-group name="public member functions">
<method name="operator[]" cv="const">
<type><replaceable>see-below</replaceable></type>
<parameter name="">
<paramtype><replaceable>see-below</replaceable></paramtype>
</parameter>
<description>
<para>
If called with an object that is implicitly convertible to type <code>Key</code>,
this function returns the <code>Value</code> passed to the constructor. Otherwise, it returns
the result of calling <code>operator[]</code> on the <code>Env</code> passed to
the constructor.
</para>
</description>
</method>
</method-group>
</struct>
<!-- is_env -->
<struct name="is_env">
<template>
<template-type-parameter name="T"/>
</template>
<inherit><type>mpl::bool_&lt;<replaceable>true-or-false</replaceable>&gt;</type></inherit>
<purpose>
<para>A Boolean metafuntion for determining whether or not a type is a Proto
transform environment.</para>
</purpose>
<description>
<para><code>is_env&lt;T&gt;</code> inherits from <code>mpl::true_</code> under the following
conditions:
<itemizedlist>
<listitem>If <code>T</code> is <classname>proto::empty_env</classname>.</listitem>
<listitem>If <code>T</code> is a specialization of <classname>proto::env&lt;&gt;</classname>.</listitem>
<listitem>If <code>T</code> is derived from any of the above.</listitem>
<listitem>If <code>T</code> is a cv-qualified variant of any of the above.</listitem>
<listitem>If <code>T</code> is a reference to any of the above.</listitem>
</itemizedlist>
</para>
<para>Otherwise, <code>is_env&lt;T&gt;</code> inherits from <code>mpl::false_</code>.
</para>
</description>
</struct>
<struct name="data_type">
<purpose>
The type of <code><globalname>proto::data</globalname></code>, a key for use when creating
a transform environment that associates a piece of data with this type.
</purpose>
<description>
<para>
The <code>proto::data_type</code> type, along with the <code><globalname>proto::data</globalname></code>
global, are declared using the <code><macroname>BOOST_PROTO_DEFINE_ENV_VAR</macroname>()</code> macro.
</para>
</description>
<method-group name="public member functions">
<overloaded-method name="operator=">
<signature cv="const">
<template>
<template-type-parameter name="Value"/>
</template>
<type><classname>env</classname>&lt;data_type, <replaceable>see-below</replaceable>&gt;</type>
<parameter name="value">
<paramtype>Value &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<template>
<template-type-parameter name="Value"/>
</template>
<type><classname>env</classname>&lt;data_type, <replaceable>see-below</replaceable>&gt;</type>
<parameter name="value">
<paramtype>Value const &amp;</paramtype>
</parameter>
</signature>
<description>
<para>
If <code>Value</code> is a specialization <code>boost::reference_wrapper&lt;T&gt;</code>,
this function returns <code><classname>env</classname>&lt;data_type, T &amp;&gt;(value.get())</code>.
</para>
<para>
Else, if the type <code>Value</code> is non-copyable (i.e., a function, an array, abstract, or an ostream),
this function returns <code><classname>env</classname>&lt;data_type, Value <replaceable>cv</replaceable> &amp;&gt;(value)</code>,
where <code><replaceable>cv</replaceable></code> is <code>const</code> for the second overload, and empty
for the first.
</para>
<para>
Otherwise, this function returns <code><classname>env</classname>&lt;data_type, Value&gt;(value)</code>.
</para>
</description>
</overloaded-method>
</method-group>
</struct>
<data-member name="data">
<description>
<para>A key used for creating a transform environment.</para>
</description>
<type><classname>proto::data_type</classname> const</type>
</data-member>
<namespace name="functional">
<!-- functional::as_env -->
<struct name="as_env">
<inherit><classname>proto::callable</classname></inherit>
<purpose>
A unary <conceptname>PolymorphicFunctionObject</conceptname> for ensuring that an object
is a transform environment. If it isn't already, it is turned into one such that the
object is associated with the <classname>proto::data_type</classname> key.
</purpose>
<struct name="result">
<template>
<template-type-parameter name="Sig"/>
</template>
<typedef name="type">
<type><replaceable>see-below</replaceable></type>
<description>
<para>See <code><methodname>proto::functional::as_env::operator()</methodname></code>.</para>
</description>
</typedef>
<description>
<para>
Encodes the return type of <code><methodname>proto::functional::as_env::operator()</methodname></code>.
The presence of this member template makes <code><classname>proto::functional::as_env</classname></code>
a valid TR1-style function object type usable with <code>boost::result_of&lt;&gt;</code>.
</para>
</description>
</struct>
<method-group name="public member functions">
<overloaded-method name="operator()">
<signature cv="const">
<template>
<template-type-parameter name="T"/>
</template>
<type><replaceable>see-below</replaceable></type>
<parameter name="t">
<paramtype>T &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<template>
<template-type-parameter name="T"/>
</template>
<type><replaceable>see-below</replaceable></type>
<parameter name="t">
<paramtype>T const &amp;</paramtype>
</parameter>
</signature>
<description>
<para>
If <code><classname>proto::is_env</classname>&lt;T&gt;::value</code> is <code>false</code>,
this function returns the result of <code>(<globalname>proto::data</globalname> = t)</code>.
See <code><methodname>proto::data_type::operator=</methodname></code> for details.
</para>
<para>
Otherwise, this function returns <code>t</code> by reference.
</para>
</description>
</overloaded-method>
</method-group>
</struct>
<!-- functional::has_env_var -->
<struct name="has_env_var">
<inherit><classname>proto::callable</classname></inherit>
<template>
<template-type-parameter name="Key"/>
</template>
<purpose>
A unary boolean <conceptname>PolymorphicFunctionObject</conceptname> used for determining whether a particular
transform environment has a value associated with a particular key.
</purpose>
<struct name="result">
<template>
<template-type-parameter name="Sig"/>
</template>
<typedef name="type">
<type><replaceable>see-below</replaceable></type>
<description>
<para>See <code><methodname>proto::functional::has_env_var::operator()</methodname></code>.</para>
</description>
</typedef>
<description>
<para>
Encodes the return type of <code><methodname>proto::functional::has_env_var::operator()</methodname></code>.
The presence of this member template makes <code><classname>proto::functional::has_env_var</classname></code>
a valid TR1-style function object type usable with <code>boost::result_of&lt;&gt;</code>.
</para>
</description>
</struct>
<method-group name="public member functions">
<method name="operator()" cv="const">
<template>
<template-type-parameter name="Env"/>
</template>
<type><replaceable>see-below</replaceable></type>
<parameter name="e">
<paramtype>Env const &amp;</paramtype>
</parameter>
<description>
<para>
This function behaves as follows:
<itemizedlist>
<listitem>
If <code><classname>proto::is_env</classname>&lt;Env&gt;::value</code> is <code>true</code>:
<itemizedlist>
<listitem>
If <code>e[Key()]</code> returns an instance of
<code><classname>proto::key_not_found</classname></code>, return
<code>mpl::false_</code>. See <code><methodname>proto::env::operator[]</methodname></code>
for more information.
</listitem>
<listitem>
Otherwise, return <code>mpl::true_</code>.
</listitem>
</itemizedlist>
</listitem>
<listitem>
Otherwise:
<itemizedlist>
<listitem>
If <code>Key</code> is <code><classname>proto::data_type</classname></code>,
return <code>mpl::true_</code>.
</listitem>
<listitem>
Otherwise, return <code>mpl::false_</code>.
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</para>
</description>
</method>
</method-group>
</struct>
<!-- functional::env_var -->
<struct name="env_var">
<inherit><classname>proto::callable</classname></inherit>
<template>
<template-type-parameter name="Key"/>
</template>
<purpose>
A unary <conceptname>PolymorphicFunctionObject</conceptname> used for fetching the value
associated with a particular key in a transform environment.
</purpose>
<struct name="result">
<template>
<template-type-parameter name="Sig"/>
</template>
<typedef name="type">
<type><replaceable>see-below</replaceable></type>
<description>
<para>See <code><methodname>proto::functional::env_var::operator()</methodname></code>.</para>
</description>
</typedef>
<description>
<para>
Encodes the return type of <code><methodname>proto::functional::env_var::operator()</methodname></code>.
The presence of this member template makes <code><classname>proto::functional::env_var</classname></code>
a valid TR1-style function object type usable with <code>boost::result_of&lt;&gt;</code>.
</para>
</description>
</struct>
<method-group name="public member functions">
<method name="operator()" cv="const">
<template>
<template-type-parameter name="Env"/>
</template>
<type><replaceable>see-below</replaceable></type>
<parameter name="e">
<paramtype>Env const &amp;</paramtype>
</parameter>
<description>
<para>
This function behaves as follows:
<itemizedlist>
<listitem>
If <code>Key</code> is <code><classname>proto::data_type</classname></code>:
<itemizedlist>
<listitem>
If <code><classname>proto::is_env</classname>&lt;Env&gt;::value</code> is <code>true</code>,
return <code>e[<globalname>proto::data</globalname>]</code>.
</listitem>
<listitem>
Otherwise, return <code>e</code>.
</listitem>
</itemizedlist>
</listitem>
<listitem>
Otherwise, return <code>e[Key()]</code>.
</listitem>
</itemizedlist>
</para>
<para>
See <code><methodname>proto::env::operator[]</methodname></code> for additional information.
</para>
</description>
</method>
</method-group>
</struct>
</namespace>
<namespace name="result_of">
<struct name="as_env">
<template>
<template-type-parameter name="T"/>
</template>
<inherit><type>boost::result_of&lt;<classname>proto::functional::as_env</classname>(T)&gt;</type></inherit>
<purpose>
Metafunction for computing the return type of <code><functionname>proto::as_env()</functionname></code>.
</purpose>
</struct>
<struct name="has_env_var">
<template>
<template-type-parameter name="Env"/>
<template-type-parameter name="Key"/>
</template>
<inherit><type>boost::result_of&lt;<classname>proto::functional::has_env_var</classname>&lt;Key&gt;(Env)&gt;::type</type></inherit>
<purpose>
Metafunction for computing the return type of <code><functionname>proto::has_env_var()</functionname></code>.
</purpose>
</struct>
<struct name="env_var">
<template>
<template-type-parameter name="Env"/>
<template-type-parameter name="Key"/>
</template>
<inherit><type>boost::result_of&lt;<classname>proto::functional::env_var</classname>&lt;Key&gt;(Env)&gt;</type></inherit>
<purpose>
Metafunction for computing the return type of <code><functionname>proto::env_var()</functionname></code>.
</purpose>
</struct>
</namespace>
<!-- proto::as_env -->
<overloaded-function name="as_env">
<signature>
<template>
<template-type-parameter name="T"/>
</template>
<type>typename <classname>proto::result_of::as_env</classname>&lt;T &amp;&gt;::type</type>
<parameter name="t">
<paramtype>T &amp;</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
</template>
<type>typename <classname>proto::result_of::as_env</classname>&lt;T const &amp;&gt;::type</type>
<parameter name="t">
<paramtype>T const &amp;</paramtype>
</parameter>
</signature>
<purpose>
For ensuring that the given argument is a transform environment. If it is not already,
it is made one as if by <code>(<globalname>proto::data</globalname> = t)</code>.
</purpose>
<description>
<para>
See also:
<itemizedlist>
<listitem>
<code><methodname>proto::data_type::operator=</methodname></code>
</listitem>
<listitem>
<code><methodname>proto::functional::as_env::operator()</methodname></code>
</listitem>
</itemizedlist>
</para>
</description>
<returns><code><classname>proto::functional::as_env</classname>()(t)</code></returns>
</overloaded-function>
<!-- proto::has_env_var -->
<overloaded-function name="has_env_var">
<signature>
<template>
<template-type-parameter name="Key"/>
<template-type-parameter name="Env"/>
</template>
<type>typename <classname>proto::result_of::has_env_var</classname>&lt;Env &amp;, Key&gt;::type</type>
<parameter name="e">
<paramtype>Env &amp;</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Key"/>
<template-type-parameter name="Env"/>
</template>
<type>typename <classname>proto::result_of::has_env_var</classname>&lt;Env const &amp;, Key&gt;::type</type>
<parameter name="e">
<paramtype>Env const &amp;</paramtype>
</parameter>
</signature>
<purpose>
For testing to see whether a value exists in a transform environment corresponding to the
specified <code>Key</code>.
</purpose>
<description>
<para>
See also:
<itemizedlist>
<listitem>
<code><methodname>proto::functional::has_env_var::operator()</methodname></code>
</listitem>
</itemizedlist>
</para>
</description>
<returns><code><classname>proto::functional::has_env_var&lt;Key&gt;</classname>()(e)</code></returns>
</overloaded-function>
<!-- proto::env_var -->
<overloaded-function name="env_var">
<signature>
<template>
<template-type-parameter name="Key"/>
<template-type-parameter name="Env"/>
</template>
<type>typename <classname>proto::result_of::env_var</classname>&lt;Env &amp;, Key&gt;::type</type>
<parameter name="e">
<paramtype>Env &amp;</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Key"/>
<template-type-parameter name="Env"/>
</template>
<type>typename <classname>proto::result_of::env_var</classname>&lt;Env const &amp;, Key&gt;::type</type>
<parameter name="e">
<paramtype>Env const &amp;</paramtype>
</parameter>
</signature>
<purpose>
For fetching the value from a transform environment corresponding to the
specified <code>Key</code>.
</purpose>
<description>
<para>
See also:
<itemizedlist>
<listitem>
<code><methodname>proto::functional::env_var::operator()</methodname></code>
</listitem>
</itemizedlist>
</para>
</description>
<returns><code><classname>proto::functional::env_var&lt;Key&gt;</classname>()(e)</code></returns>
</overloaded-function>
<!-- proto::operator, -->
<overloaded-function name="operator,">
<signature>
<template>
<template-type-parameter name="Env"/>
<template-type-parameter name="Key"/>
<template-type-parameter name="Value"/>
</template>
<type><classname>proto::env</classname>&lt;Key, Value, <replaceable>UNCVREF</replaceable>(typename <classname>proto::result_of::as_env</classname>&lt;Env &amp;&gt;::type)&gt;</type>
<parameter name="other">
<paramtype>Env &amp;</paramtype>
</parameter>
<parameter name="head">
<paramtype><classname>proto::env</classname>&lt;Key, Value&gt; const &amp;</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Env"/>
<template-type-parameter name="Key"/>
<template-type-parameter name="Value"/>
</template>
<type><classname>proto::env</classname>&lt;Key, Value, <replaceable>UNCVREF</replaceable>(typename <classname>proto::result_of::as_env</classname>&lt;Env const &amp;&gt;::type)&gt;</type>
<parameter name="other">
<paramtype>Env const &amp;</paramtype>
</parameter>
<parameter name="head">
<paramtype><classname>proto::env</classname>&lt;Key, Value&gt; const &amp;</paramtype>
</parameter>
</signature>
<purpose>
For composing a larger transform environment from two smaller ones.
</purpose>
<description>
<para>
The effect of this function is to take two transform environments and compose them into
a larger environment that contains the key/values pairs of the two. The first argument
is allowed to not be a transform environment, in which case it is turned into one with
the <functionname>proto::as_env()</functionname> function before composition with the
second argument. The second argument is required to be a transform environment with exactly
one key/value pair.
</para>
<para>
<emphasis role="bold">Example:</emphasis>
</para>
<para>
Given user-defined keys <code>key0</code> and <code>key1</code> of types <code>key0_type</code>
and <code>key1_type</code>, the following code demonstrates how the chained use of <code>operator,</code>
can build a composite transform environment containing a number of key/value pairs:
<programlisting><classname>proto::env</classname>&lt;
key1_type
, int
, <classname>proto::env</classname>&lt;
key0_type
, char const (&amp;)[6]
, <classname>proto::env</classname>&lt;<classname>proto::data_type</classname>, int&gt;
&gt;
&gt; myenv = (<globalname>proto::data</globalname> = 1, key0 = "hello", key1 = 42);
// NOTE: operator, here --^ and here --^
// Check the results:
assert(1 == myenv[proto::data]);
assert(0 == std::strcmp(myenv[key0], "hello"));
assert(42 == myenv[key1]);</programlisting>
</para>
<para>
<emphasis role="bold">Note:</emphasis> In the return type and the "Returns" clause, <code><replaceable>UNCVREF</replaceable>(X)</code> is
the type <code>X</code> stripped of top-level reference and cv-qualifiers.
</para>
<para>
<emphasis role="bold">Note:</emphasis> In the "Returns" clause, <code><replaceable>cv</replaceable></code> is replaced with <code>const</code>
for the second overload, and nothing for the first.
</para>
<para>
<emphasis role="bold">See also:</emphasis>
<itemizedlist>
<listitem>
<code><methodname>proto::env::operator[]</methodname></code>
</listitem>
</itemizedlist>
</para>
</description>
<returns><code><classname>proto::env</classname>&lt;Key, Value, <replaceable>UNCVREF</replaceable>(typename <classname>proto::result_of::as_env</classname>&lt;Env <replaceable>cv</replaceable> &amp;&gt;::type)&gt;(head[Key()], <functionname>proto::as_env</functionname>(other))</code></returns>
</overloaded-function>
<!-- struct _env_var -->
<struct name="_env_var">
<template>
<template-type-parameter name="Key"/>
</template>
<purpose>
A primitive transform that returns the value associated with a particular <code>Key</code>
in the current transform environment.
</purpose>
<inherit>
<type><classname>proto::transform</classname>&lt;_env_var&lt;Key&gt; &gt;</type>
</inherit>
<struct name="impl">
<template>
<template-type-name name="Expr"/>
<template-type-name name="State"/>
<template-type-name name="Data"/>
</template>
<inherit>
<type><classname>proto::transform_impl</classname>&lt;Expr, State, Data&gt; &gt;</type>
</inherit>
<typedef name="result_type">
<type>typename <classname>proto::result_of::env_var</classname>&lt;Data, Key&gt;::type</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
<description>
<para>The current transform environment</para>
</description>
</parameter>
<description>
<para>
Fetches the value associated with <code>Key</code> from the transform environment
passed in the data (third) parameter.
</para>
</description>
<requires>
<para>
<code><classname>proto::is_env</classname>&lt;Data&gt;::value</code>
is <code>true</code>.
</para>
</requires>
<returns>
<para>
<code><functionname>proto::env_var</functionname>(data)</code>
</para>
</returns>
</method>
</method-group>
</struct>
<description>
<para>
See <code><classname>proto::_env_var::impl</classname></code> for the full details.
</para>
</description>
</struct>
<!-- struct _env -->
<struct name="_env">
<purpose>
A primitive transform that returns the current transform environment unmodified.
</purpose>
<inherit>
<type><classname>proto::transform</classname>&lt;_env&gt;</type>
</inherit>
<struct name="impl">
<template>
<template-type-name name="Expr"/>
<template-type-name name="State"/>
<template-type-name name="Data"/>
</template>
<inherit>
<type><classname>proto::transform_impl</classname>&lt;Expr, State, Data&gt;</type>
</inherit>
<typedef name="result_type">
<type>Data</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
<description>
<para>The current transform environment </para>
</description>
</parameter>
<description>
<para>
Returns the current transform environment
passed in the data (third) parameter.
</para>
</description>
<returns>
<para>
<code>data</code>
</para>
</returns>
</method>
</method-group>
</struct>
<description>
<para>
See <code><classname>proto::_env::impl</classname></code> for the full details.
</para>
</description>
</struct>
</namespace>
</namespace>
<!-- BOOST_PROTO_DEFINE_ENV_VAR() -->
<macro name="BOOST_PROTO_DEFINE_ENV_VAR" kind="functionlike">
<macro-parameter name="Type"/>
<macro-parameter name="Name"/>
<purpose>
Define a type and a global variable of that type that can be used
to initialize a slot in a Proto transform environment.
</purpose>
<description>
<para>
Proto primitive transforms can optionally accept an environment in
their third parameter which is a key/value store of environment
variables. Use the <code>BOOST_PROTO_DEFINE_ENV_VAR()</code> macro
to define the keys.
</para>
<para>
See the description for <code><classname alt="boost::proto::data_type">proto::data_type</classname></code>
for an example of the class interface created by this macro.
</para>
<para>
<emphasis role="bold">Example:</emphasis>
</para>
<para>
<programlisting>BOOST_PROTO_DEFINE_ENV_VAR(mykey_type, mykey);
struct FetchMyKey
: <classname alt="boost::proto::when">proto::when</classname>&lt; <classname alt="boost::proto::_">_</classname>, <classname alt="boost::proto::_env_var">proto::_env_var</classname>&lt;mykey_type&gt; &gt;
{};
int main()
{
<classname alt="boost::proto::terminal">proto::terminal</classname>&lt;int&gt;::type i = {42};
char const * sz = FetchMyKey()(i, 0, (mykey = "hello!"));
assert(0 == std::strcmp(sz, "hello!");
}</programlisting>
</para>
</description>
</macro>
</header>

View File

@@ -0,0 +1,125 @@
<?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/fold.hpp">
<para>Contains definition of the
<computeroutput>
<classname alt="boost::proto::fold">proto::fold&lt;&gt;</classname>
</computeroutput> and
<computeroutput>
<classname alt="boost::proto::reverse_fold">proto::reverse_fold&lt;&gt;</classname>
</computeroutput>
transforms.</para>
<namespace name="boost">
<namespace name="proto">
<struct name="fold">
<template>
<template-type-parameter name="Sequence"/>
<template-type-parameter name="State0"/>
<template-type-parameter name="Fun"/>
</template>
<inherit>
<classname>proto::transform</classname>&lt; fold&lt;Sequence, State0, Fun&gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that invokes the
<computeroutput>fusion::fold&lt;&gt;</computeroutput> algorithm to accumulate a value.</purpose>
<description>
<para>
For the complete description of the behavior of the <computeroutput>proto::fold&lt;&gt;</computeroutput>
transform, see the documentation for the nested <computeroutput>
<classname>proto::fold::impl&lt;&gt;</classname>
</computeroutput> class template.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
<typedef name="X">
<purpose>For exposition only</purpose>
<type><classname>when</classname>&lt;<classname>_</classname>, Sequence&gt;</type>
</typedef>
<typedef name="Y">
<purpose>For exposition only</purpose>
<type><classname>when</classname>&lt;<classname>_</classname>, State0&gt;</type>
</typedef>
<typedef name="seq">
<purpose>A Fusion sequence, for exposition only</purpose>
<type>typename boost::result_of&lt;X(Expr, State, Data)&gt;::type</type>
</typedef>
<typedef name="state0">
<purpose>An initial state for the fold, for exposition only</purpose>
<type>typename boost::result_of&lt;Y(Expr, State, Data)&gt;::type</type>
</typedef>
<typedef name="fun">
<purpose><computeroutput>fun(d)(s,e) == when&lt;_,Fun&gt;()(e,s,d)</computeroutput></purpose>
<type><emphasis>unspecified</emphasis></type>
</typedef>
<typedef name="result_type">
<type>typename fusion::result_of::fold&lt;seq, state0, fun&gt;::type</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
<description>
<para>The current expression </para>
</description>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
<description>
<para>The current state </para>
</description>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
<description>
<para>An arbitrary data </para>
</description>
</parameter>
<description>
<para>
Let <computeroutput>seq</computeroutput> be
<computeroutput><classname>when</classname>&lt;<classname>_</classname>, Sequence&gt;()(expr, state, data)</computeroutput>,
let <computeroutput>state0</computeroutput> be
<computeroutput><classname>when</classname>&lt;<classname>_</classname>, State0&gt;()(expr, state, data)</computeroutput>,
and let <computeroutput>fun(data)</computeroutput> be an object such that
<computeroutput>fun(data)(state, expr)</computeroutput> is equivalent to
<computeroutput><classname>when</classname>&lt;<classname>_</classname>, Fun&gt;()(expr, state, data)</computeroutput>. Then,
this function returns <computeroutput>fusion::fold(seq, state0, fun(data))</computeroutput>.
</para>
</description>
</method>
</method-group>
</struct>
</struct>
<struct name="reverse_fold">
<template>
<template-type-parameter name="Sequence"/>
<template-type-parameter name="State0"/>
<template-type-parameter name="Fun"/>
</template>
<inherit><classname>proto::fold</classname>&lt; <classname>proto::_reverse</classname>(Sequence), State0, Fun &gt;</inherit>
<purpose>
A <conceptname>PrimitiveTransform</conceptname> that is the same as the <computeroutput><classname>proto::fold&lt;&gt;</classname></computeroutput>
transform, except that it folds back-to-front instead of front-to-back. It uses the
<computeroutput>
<classname>proto::_reverse</classname>
</computeroutput> callable <conceptname>PolymorphicFunctionObject</conceptname> to create a
<computeroutput>fusion::reverse_view&lt;&gt;</computeroutput> of the sequence before invoking
<computeroutput>fusion::fold&lt;&gt;</computeroutput>.
</purpose>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,141 @@
<?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/fold_tree.hpp">
<para>
Contains definition of the
<computeroutput>
<classname alt="boost::proto::fold_tree">proto::fold_tree&lt;&gt;</classname>
</computeroutput> and
<computeroutput>
<classname alt="boost::proto::reverse_fold_tree">proto::reverse_fold_tree&lt;&gt;</classname>
</computeroutput>
transforms.
</para>
<namespace name="boost">
<namespace name="proto">
<struct name="fold_tree">
<template>
<template-type-parameter name="Sequence"/>
<template-type-parameter name="State0"/>
<template-type-parameter name="Fun"/>
</template>
<inherit><classname>proto::transform</classname>&lt; fold_tree&lt;Sequence, State0, Fun&gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that recursively applies the
<computeroutput><classname>proto::fold</classname>&lt;&gt;</computeroutput> transform to sub-trees
that all share a common tag type.</purpose>
<description>
<para>
<computeroutput>proto::fold_tree&lt;&gt;</computeroutput> is useful for flattening trees into lists;
for example, you might use <computeroutput>proto::fold_tree&lt;&gt;</computeroutput> to flatten an
expression tree like <computeroutput>a | b | c</computeroutput> into a Fusion list like
<computeroutput>cons(c, cons(b, cons(a)))</computeroutput>.
</para>
<para>
<computeroutput>proto::fold_tree&lt;&gt;</computeroutput> is easily understood in terms of a
<computeroutput>recurse_if_&lt;&gt;</computeroutput> helper, defined as follows:
<programlisting> template&lt;typename Tag, typename Fun&gt;
struct recurse_if_ :
<classname>proto::if_</classname>&lt;
// If the current node has type type "Tag" ...
boost::is_same&lt;<classname>proto::tag_of</classname>&lt;<classname>proto::_</classname>&gt;, Tag&gt;(),
// ... recurse, otherwise ...
<classname>proto::fold</classname>&lt;<classname>proto::_</classname>, <classname>proto::_state</classname>, recurse_if_&lt;Tag, Fun&gt; &gt;,
// ... apply the Fun transform.
Fun
&gt;
{};</programlisting>
</para>
<para>
With <computeroutput>recurse_if_&lt;&gt;</computeroutput> as defined above,
<computeroutput>proto::fold_tree&lt;Sequence, State0, Fun&gt;()(expr, state, data)</computeroutput>
is equivalent to:
<programlisting><classname>proto::fold</classname>&lt;
Sequence,
State0,
recurse_if_&lt;typename Expr::proto_tag, Fun&gt;
&gt;()(expr, state, data).</programlisting>
It has the effect of folding a tree front-to-back, recursing into child nodes that share a
tag type with the parent node.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit>
<type>
<classname>proto::fold</classname>&lt;Sequence, State0, recurse_if_&lt;typename Expr::proto_tag, Fun&gt; &gt;
::template impl&lt;Expr, State, Data&gt;</type>
</inherit>
</struct>
</struct>
<struct name="reverse_fold_tree">
<template>
<template-type-parameter name="Sequence"/>
<template-type-parameter name="State0"/>
<template-type-parameter name="Fun"/>
</template>
<inherit><classname>proto::transform</classname>&lt; reverse_fold_tree&lt;Sequence, State0, Fun&gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that recursively applies the
<computeroutput><classname>proto::reverse_fold&lt;&gt;</classname></computeroutput> transform to
sub-trees that all share a common tag type.</purpose>
<description>
<para>
<computeroutput>proto::reverse_fold_tree&lt;&gt;</computeroutput> is useful for flattening trees
into lists; for example, you might use <computeroutput>proto::reverse_fold_tree&lt;&gt;</computeroutput>
to flatten an expression tree like <computeroutput>a | b | c</computeroutput> into a Fusion list like
<computeroutput>cons(a, cons(b, cons(c)))</computeroutput>.
</para>
<para>
<computeroutput>proto::reverse_fold_tree&lt;&gt;</computeroutput> is easily understood in terms of
a <computeroutput>recurse_if_&lt;&gt;</computeroutput> helper, defined as follows:
<programlisting> template&lt;typename Tag, typename Fun&gt;
struct recurse_if_ :
<classname>proto::if_</classname>&lt;
// If the current node has type type "Tag" ...
boost::is_same&lt;<classname>proto::tag_of</classname>&lt;<classname>proto::_</classname>&gt;, Tag&gt;(),
// ... recurse, otherwise ...
<classname>proto::reverse_fold</classname>&lt;<classname>proto::_</classname>, <classname>proto::_state</classname>, recurse_if_&lt;Tag, Fun&gt; &gt;,
// ... apply the Fun transform.
Fun
&gt;
{};</programlisting>
</para>
<para>
With <computeroutput>recurse_if_&lt;&gt;</computeroutput> as defined above,
<computeroutput>proto::reverse_fold_tree&lt;Sequence, State0, Fun&gt;()(expr, state, data)</computeroutput>
is equivalent to:
<programlisting><classname>proto::reverse_fold</classname>&lt;
Sequence,
State0,
recurse_if_&lt;typename Expr::proto_tag, Fun&gt;
&gt;()(expr, state, data).</programlisting>
It has the effect of folding a tree back-to-front, recursing into child nodes that share a
tag type with the parent node.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit>
<type>
<classname>proto::reverse_fold</classname>&lt;Sequence, State0, recurse_if_&lt;typename Expr::proto_tag, Fun&gt; &gt;
::template impl&lt;Expr, State, Data&gt;</type>
</inherit>
</struct>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,306 @@
<?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&lt;&gt; and transform_impl&lt;&gt; 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&lt; Expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable> &gt;::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&lt; Expr, State, <replaceable>unspecified</replaceable> &gt;::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&lt; Expr, State, Data &gt;::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&lt;Expr &amp;, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>&gt;::result_type</type>
<template>
<template-type-parameter name="Expr"/>
</template>
<parameter name="expr">
<paramtype>Expr &amp;</paramtype>
</parameter>
<returns>
<computeroutput>
typename PrimitiveTransform::template impl&lt;Expr &amp;, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>&gt;()(expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>)
</computeroutput>
</returns>
</method>
<method name="operator()" cv="const">
<type>typename PrimitiveTransform::template impl&lt;Expr &amp;, State &amp;, <replaceable>unspecified</replaceable>&gt;::result_type</type>
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
</template>
<parameter name="expr">
<paramtype>Expr &amp;</paramtype>
</parameter>
<parameter name="state">
<paramtype>State &amp;</paramtype>
</parameter>
<returns>
<computeroutput>
typename PrimitiveTransform::template impl&lt;Expr &amp;, State &amp;, <replaceable>unspecified</replaceable>&gt;()(expr, state, <replaceable>unspecified</replaceable>)
</computeroutput>
</returns>
</method>
<method name="operator()" cv="const">
<type>typename PrimitiveTransform::template impl&lt;Expr &amp;, State const &amp;, <replaceable>unspecified</replaceable>&gt;::result_type</type>
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
</template>
<parameter name="expr">
<paramtype>Expr &amp;</paramtype>
</parameter>
<parameter name="state">
<paramtype>State const &amp;</paramtype>
</parameter>
<returns>
<computeroutput>
typename PrimitiveTransform::template impl&lt;Expr &amp;, State const &amp;, <replaceable>unspecified</replaceable>&gt;()(expr, state, <replaceable>unspecified</replaceable>)
</computeroutput>
</returns>
</method>
<method name="operator()" cv="const">
<type>typename PrimitiveTransform::template impl&lt;Expr &amp;, State &amp;, Data &amp;&gt;::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 &amp;</paramtype>
</parameter>
<parameter name="state">
<paramtype>State &amp;</paramtype>
</parameter>
<parameter name="data">
<paramtype>Data &amp;</paramtype>
</parameter>
<returns>
<computeroutput>
typename PrimitiveTransform::template impl&lt;Expr &amp;, State &amp;, Data &amp;&gt;()(expr, state, data)
</computeroutput>
</returns>
</method>
<method name="operator()" cv="const">
<type>typename PrimitiveTransform::template impl&lt;Expr &amp;, State const &amp;, Data &amp;&gt;::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 &amp;</paramtype>
</parameter>
<parameter name="state">
<paramtype>State const &amp;</paramtype>
</parameter>
<parameter name="data">
<paramtype>Data &amp;</paramtype>
</parameter>
<returns>
<computeroutput>
typename PrimitiveTransform::template impl&lt;Expr &amp;, State const &amp;, Data &amp;&gt;()(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&lt;Expr const&gt;::type</type>
</typedef>
<typedef name="expr_param">
<type>typename boost::add_reference&lt;Expr const&gt;::type</type>
</typedef>
<typedef name="state">
<type>typename boost::remove_reference&lt;State const&gt;::type</type>
</typedef>
<typedef name="state_param">
<type>typename boost::add_reference&lt;State const&gt;::type</type>
</typedef>
<typedef name="data">
<type>typename boost::remove_reference&lt;Data const&gt;::type</type>
</typedef>
<typedef name="data_param">
<type>typename boost::add_reference&lt;Data const&gt;::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>&lt;
// Match any nary expression where the children are all int terminals
<classname alt="boost::proto::nary_expr">proto::nary_expr</classname>&lt;<classname alt="boost::proto::_">_</classname>, <classname alt="boost::proto::vararg">proto::vararg</classname>&lt;<classname alt="boost::proto::terminal">proto::terminal</classname>&lt;int&gt; &gt; &gt;
// 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>))...)
&gt;
{};
int main()
{
<classname alt="boost::proto::terminal">proto::terminal</classname>&lt;int&gt;::type i = {42};
int result = sum()( i(3,5) ); // Creates a ternary functional-call expression
std::cout &lt;&lt; "Sum of 42, 3, and 5 : " &lt;&lt; result &lt;&lt; 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>&lt;0&gt;),…
<replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname>&lt;<replaceable>M</replaceable>-1&gt;)</computeroutput>, where
<replaceable>M</replaceable> is the arity of the expression <replaceable>E</replaceable>.
</listitem>
</itemizedlist>
</para>
</description>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,100 @@
<?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/integral_c.hpp">
<para>Contains definition of the integral_c transform and friends.</para>
<namespace name="boost">
<namespace name="proto">
<struct name="integral_c">
<template>
<template-type-parameter name="T"/>
<template-nontype-parameter name="I">
<type>T</type>
</template-nontype-parameter>
</template>
<inherit><classname>proto::transform</classname>&lt; integral_c&lt; T, I &gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns the specified integral constant.</purpose>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
<typedef name="result_type">
<type>T</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>T</type>
<parameter name="">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<returns>
<para>
<computeroutput>I</computeroutput>
</para>
</returns>
<throws>
<simpara>Will not throw.</simpara>
</throws>
</method>
</method-group>
</struct>
</struct>
<struct name="char_">
<template>
<template-nontype-parameter name="I">
<type>char</type>
</template-nontype-parameter>
</template>
<inherit><classname>proto::integral_c</classname>&lt; char, I &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns the specified char.</purpose>
</struct>
<struct name="int_">
<template>
<template-nontype-parameter name="I">
<type>int</type>
</template-nontype-parameter>
</template>
<inherit><classname>proto::integral_c</classname>&lt; int, I &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns the specified int.</purpose>
</struct>
<struct name="long_">
<template>
<template-nontype-parameter name="I">
<type>long</type>
</template-nontype-parameter>
</template>
<inherit><classname>proto::integral_c</classname>&lt; long, I &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns the specified long.</purpose>
</struct>
<struct name="size_t">
<template>
<template-nontype-parameter name="I">
<type>std::size_t</type>
</template-nontype-parameter>
</template>
<inherit><classname>proto::integral_c</classname>&lt; std::size_t, I &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that returns the specified std::size_t.</purpose>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,150 @@
<?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/lazy.hpp">
<para>
Contains definition of the
<computeroutput>
<classname alt="boost::proto::lazy">proto::lazy&lt;&gt;</classname>
</computeroutput> transform.
</para>
<namespace name="boost">
<namespace name="proto">
<struct name="lazy">
<template>
<template-type-parameter name="T"/>
</template>
<inherit><classname>proto::transform</classname>&lt; lazy&lt;T&gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that uses
<computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> to build a
<conceptname>CallableTransform</conceptname>, and then uses
<computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> to apply it.
</purpose>
<description>
<para>
<computeroutput>proto::lazy&lt;&gt;</computeroutput> 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 <computeroutput>
<classname>proto::make&lt;&gt;</classname>
</computeroutput> transform evaluates any nested transforms, and the resulting type is treated
as a <conceptname>CallableTransform</conceptname>, which is evaluated with
<computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput>.
</para>
<para>
For the full description of the behavior of the
<computeroutput>
<classname>proto::lazy&lt;&gt;</classname>
</computeroutput>
transform, see the documentation for the nested
<computeroutput>
<classname>proto::lazy::impl&lt;&gt;</classname>
</computeroutput>
class template.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><type><classname>proto::transform_impl</classname>&lt;Expr, State, Data&gt;</type></inherit>
<typedef name="result_type">
<type><replaceable>see-below</replaceable></type>
<description>
<para>
<computeroutput><classname>proto::lazy</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::result_type</computeroutput>
is calculated as follows:
<itemizedlist>
<listitem>
<para>
If <computeroutput>T</computeroutput> if of the form
<computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;O&gt;(Expr, State, Data)&gt;::type</computeroutput>
and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>.
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> if of the form
<computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, then let <computeroutput>O'</computeroutput>
be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;O&gt;(Expr, State, Data)&gt;::type</computeroutput>
and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>.
</para>
</listitem>
<listitem>
<para>
Otherwise, let <computeroutput>T'</computeroutput>
be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;T&gt;(Expr, State, Data)&gt;::type</computeroutput>.
</para>
</listitem>
</itemizedlist>
<para>
The result type is
<computeroutput>
boost::result_of&lt;<classname>proto::call</classname>&lt;T'&gt;(Expr, State, Data)&gt;::type
</computeroutput>.
</para>
</para>
</description>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<para>
<computeroutput><classname>proto::lazy</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::operator()</computeroutput> behaves as follows:
<itemizedlist>
<listitem>
<para>
If <computeroutput>T</computeroutput> if of the form
<computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;O&gt;(Expr, State, Data)&gt;::type</computeroutput>
and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>.
</para>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> if of the form
<computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, then let <computeroutput>O'</computeroutput>
be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;O&gt;(Expr, State, Data)&gt;::type</computeroutput>
and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>.
</para>
</listitem>
<listitem>
<para>
Otherwise, let <computeroutput>T'</computeroutput>
be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;T&gt;(Expr, State, Data)&gt;::type</computeroutput>.
</para>
</listitem>
</itemizedlist>
</para>
</description>
<returns>
<para>
<computeroutput>
<classname>proto::call</classname>&lt;T'&gt;()(expr, state, data)
</computeroutput>
</para>
</returns>
</method>
</method-group>
</struct>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,362 @@
<?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/make.hpp">
<para>
Contains definition of the
<computeroutput>
<classname alt="boost::proto::make">proto::make&lt;&gt;</classname>
</computeroutput>
and
<computeroutput>
<classname alt="boost::proto::protect">proto::protect&lt;&gt;</classname>
</computeroutput>
transforms.
</para>
<namespace name="boost">
<namespace name="proto">
<struct name="noinvoke">
<template>
<template-type-parameter name="T"/>
</template>
<purpose>A type annotation in an <conceptname>ObjectTransform</conceptname> which instructs
Proto not to look for a nested <computeroutput>::type</computeroutput> within
<computeroutput>T</computeroutput> after type substitution.</purpose>
<description>
<para>
<conceptname>ObjectTransform</conceptname>s are evaluated by
<computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>,
which finds all nested transforms and replaces them with the result of their applications.
If any substitutions are performed, the result is first assumed to be a metafunction to be applied;
that is, Proto checks to see if the result has a nested <computeroutput>::type</computeroutput>
typedef. If it does, that becomes the result. The purpose of <computeroutput>proto::noinvoke&lt;&gt;</computeroutput>
is to prevent Proto from looking for a nested <computeroutput>::type</computeroutput> typedef
in these situations.
</para>
<para>
Example:
<programlisting>struct Test
: <classname>proto::when</classname>&lt;
<classname>_</classname>
, proto::noinvoke&lt;
// This remove_pointer invocation is bloked by noinvoke
boost::remove_pointer&lt;
// This add_pointer invocation is *not* blocked by noinvoke
boost::add_pointer&lt;<classname>_</classname>&gt;
&gt;
&gt;()
&gt;
{};
void test_noinvoke()
{
typedef <classname>proto::terminal</classname>&lt;int&gt;::type Int;
BOOST_MPL_ASSERT((
boost::is_same&lt;
boost::result_of&lt;Test(Int)&gt;::type
, boost::remove_pointer&lt;Int *&gt;
&gt;
));
Int i = {42};
boost::remove_pointer&lt;Int *&gt; t = Test()(i);
}</programlisting>
</para>
</description>
</struct>
<struct name="protect">
<template>
<template-type-parameter name="PrimitiveTransform"/>
</template>
<inherit><classname>proto::transform</classname>&lt; protect&lt;PrimitiveTransform&gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> which prevents another
<conceptname>PrimitiveTransform</conceptname> from being applied in an
<conceptname>ObjectTransform</conceptname>.</purpose>
<description>
<para>
When building higher order transforms with
<computeroutput>
<classname alt="proto::make">proto::make&lt;&gt;</classname>
</computeroutput> or
<computeroutput>
<classname alt="proto::lazy">proto::lazy&lt;&gt;</classname>
</computeroutput>,
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
<computeroutput>proto::_</computeroutput> in
<computeroutput>Bar&lt;proto::_&gt;()</computeroutput>
with <computeroutput>proto::terminal&lt;int&gt;::type</computeroutput>:
</para>
<para>
<programlisting>template&lt;typename T&gt;
struct Bar
{};
struct Foo :
<classname>proto::when</classname>&lt;<classname>proto::_</classname>, Bar&lt;<classname>proto::_</classname>&gt;() &gt;
{};
<classname>proto::terminal</classname>&lt;int&gt;::type i = {0};
int main() {
Foo()(i);
std::cout &lt;&lt; typeid(Foo()(i)).name() &lt;&lt; std::endl;
}</programlisting>
</para>
<para>
If you actually wanted to default-construct an object of type
<computeroutput>Bar&lt;proto::_&gt;</computeroutput>, you would have to protect the
<computeroutput>_</computeroutput> to prevent it from being applied. You can
use <computeroutput>proto::protect&lt;&gt;</computeroutput> as follows:
</para>
<para>
<programlisting>// OK: replace anything with Bar&lt;_&gt;()
struct Foo :
<classname>proto::when</classname>&lt;<classname>proto::_</classname>, Bar&lt;<classname>proto::protect</classname>&lt;<classname>proto::_</classname>&gt; &gt;() &gt;
{};</programlisting>
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name=""/>
<template-type-parameter name=""/>
<template-type-parameter name=""/>
</template>
<typedef name="result_type">
<type>PrimitiveTransform</type>
</typedef>
</struct>
</struct>
<struct name="make">
<template>
<template-type-parameter name="T"/>
</template>
<inherit><classname>proto::transform</classname>&lt; make&lt;T&gt; &gt;</inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that computes a type by evaluating
any nested transforms and then constructs an object of that type. </purpose>
<description>
<para>
The purpose of <computeroutput>proto::make&lt;&gt;</computeroutput> is to annotate a transform as
an <conceptname>ObjectTransform</conceptname> so that
<computeroutput><classname alt="proto::when">proto::when&lt;&gt;</classname></computeroutput> knows
how to apply it.
</para>
<para>
For the full description of the behavior of the
<computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>
transform, see the documentation for the nested
<computeroutput><classname alt="proto::make::impl">proto::make::impl&lt;&gt;</classname></computeroutput>
class template.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
<typedef name="result_type">
<type><emphasis>see-below</emphasis></type>
<description>
<para>
<computeroutput><classname>proto::make</classname>&lt;T&gt;::impl&lt;Expr, State, Data&gt;::result_type</computeroutput> is
computed as follows:
</para>
<para>
If <computeroutput>T</computeroutput> is an <conceptname>ObjectTransform</conceptname> of the form
<computeroutput>Object(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput> or
<computeroutput>Object(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
then let <computeroutput>O</computeroutput> be the return type
<computeroutput>Object</computeroutput>. Otherwise, let <computeroutput>O</computeroutput>
be <computeroutput>T</computeroutput>. The <computeroutput>result_type</computeroutput> typedef is
then computed as follows:
</para>
<para>
<itemizedlist>
<listitem>
<para>
If <computeroutput><classname>proto::is_transform</classname>&lt;O&gt;::value</computeroutput> is
<computeroutput>true</computeroutput>, then let the result type be
<computeroutput>
boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>_</classname>, O&gt;(Expr, State, Data)&gt;::type
</computeroutput>.
Note that a substitution took place.
</para>
</listitem>
<listitem>
If <computeroutput>O</computeroutput> is a template like
<computeroutput><classname>proto::noinvoke</classname>&lt;S&lt;X<subscript>0</subscript>,…X<subscript>n</subscript>&gt; &gt;</computeroutput>,
then the result type is calculated as follows:
<itemizedlist>
<listitem>
<para>
For each <computeroutput>i</computeroutput> in
<computeroutput>[0,n]</computeroutput>, let <computeroutput>
X<subscript>i</subscript>'
</computeroutput> be
<computeroutput>
boost::result_of&lt;<classname>proto::make</classname>&lt;X<subscript>i</subscript>&gt;(Expr, State, Data)&gt;::type
</computeroutput>
(which evaluates this procedure recursively). Note that a substitution took place. (In this case,
Proto merely assumes that a substitution took place for the sake of compile-time efficiency. There
would be no reason to use <computeroutput><classname>proto::noinvoke&lt;&gt;</classname></computeroutput>
otherwise.)
</para>
</listitem>
<listitem>
<para>
The result type is
<computeroutput>
S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
</computeroutput>.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
If <computeroutput>O</computeroutput> is a template like
<computeroutput>S&lt;X<subscript>0</subscript>,…X<subscript>n</subscript>&gt;</computeroutput>,
then the result type is calculated as follows:
<itemizedlist>
<listitem>
<para>
For each <computeroutput>i</computeroutput> in
<computeroutput>[0,n]</computeroutput>, let <computeroutput>
X<subscript>i</subscript>'
</computeroutput> be
<computeroutput>
boost::result_of&lt;<classname>proto::make</classname>&lt;X<subscript>i</subscript>&gt;(Expr, State, Data)&gt;::type
</computeroutput>
(which evaluates this procedure recursively). Note whether any substitutions took place during
this operation.
</para>
</listitem>
<listitem>
<para>
If any substitutions took place in the above step and
<computeroutput>
S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
</computeroutput> has a nested
<computeroutput>type</computeroutput> typedef, the result type is
<computeroutput>
S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;::type
</computeroutput>.
</para>
</listitem>
<listitem>
<para>
Otherwise, the result type is
<computeroutput>
S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
</computeroutput>.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
Otherwise, the result type is <computeroutput>O</computeroutput>, and note that no
substitution took place.
</listitem>
</itemizedlist>
</para>
<para>
Note that <computeroutput><classname alt="proto::when">proto::when&lt;&gt;</classname></computeroutput> is implemented
in terms of <computeroutput><classname alt="proto::call">proto::call&lt;&gt;</classname></computeroutput>
and <computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>, so the
above procedure is evaluated recursively.
</para>
</description>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<description>
<para>
<computeroutput>
<classname>proto::make</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::operator()
</computeroutput>
behaves as follows:
</para>
<para>
<itemizedlist>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then:
</para>
<itemizedlist>
<listitem>
<para>
If <computeroutput>
<classname>proto::is_aggregate</classname>&lt;result_type&gt;::value
</computeroutput> is <computeroutput>true</computeroutput>, then construct
and return an object <computeroutput>that</computeroutput> as follows:
<programlisting>result_type that = {
<classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>0</subscript>&gt;()(expr, state, data),
<classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>n</subscript>&gt;()(expr, state, data)
};</programlisting>
</para>
</listitem>
<listitem>
<para>
Otherwise, construct
and return an object <computeroutput>that</computeroutput> as follows:
<programlisting>result_type that(
<classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>0</subscript>&gt;()(expr, state, data),
<classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>n</subscript>&gt;()(expr, state, data)
);</programlisting>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
If <computeroutput>T</computeroutput> is of the form
<computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
then let <computeroutput>T&apos;</computeroutput> be <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>. Then, return:
<programlisting>proto::make&lt;T&apos;&gt;()(expr, state, data)</programlisting>
</para>
</listitem>
<listitem>
<para>
Otherwise, construct and return an object <computeroutput>that</computeroutput>
as follows: <programlisting>result_type that = result_type();</programlisting>
</para>
</listitem>
</itemizedlist>
</para>
</description>
</method>
</method-group>
</struct>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,189 @@
<?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/pass_through.hpp">
<para>Definition of the
<computeroutput><classname alt="boost::proto::pass_through">proto::pass_through&lt;&gt;</classname></computeroutput>
transform, which is the default transform of all of the expression generator metafunctions such as
<computeroutput><classname alt="boost::proto::unary_plus">proto::unary_plus&lt;&gt;</classname></computeroutput>,
<computeroutput><classname alt="boost::proto::plus">proto::plus&lt;&gt;</classname></computeroutput> and
<computeroutput><classname alt="boost::proto::nary_expr">proto::nary_expr&lt;&gt;</classname></computeroutput>.</para>
<namespace name="boost">
<namespace name="proto">
<struct name="pass_through">
<template>
<template-type-parameter name="Grammar"/>
<template-type-parameter name="Domain">
<default><classname>proto::deduce_domain</classname></default>
</template-type-parameter>
</template>
<inherit><type><classname>proto::transform</classname>&lt; pass_through&lt;Grammar, Domain&gt; &gt;</type></inherit>
<purpose>A <conceptname>PrimitiveTransform</conceptname> that transforms the child expressions of an expression
node according to the corresponding children of a Grammar. The resulting expression is in the specified domain.</purpose>
<description>
<para>
Given a Grammar such as <computeroutput><classname>proto::plus</classname>&lt;T0, T1&gt;</computeroutput>,
an expression type that matches the grammar such as
<computeroutput><classname>proto::plus</classname>&lt;E0, E1&gt;::type</computeroutput>, a state
<computeroutput>S</computeroutput> and a data <computeroutput>D</computeroutput>, the result of applying
the <computeroutput>proto::pass_through&lt;<classname>proto::plus</classname>&lt;T0, T1&gt; &gt;</computeroutput>
transform is: <programlisting><classname>proto::plus</classname>&lt;
boost::result_of&lt;T0(E0, S, D)&gt;::type,
boost::result_of&lt;T1(E1, S, D)&gt;::type
&gt;::type</programlisting>
</para>
<para>
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.
</para>
<para>
The <code>Domain</code> template parameter determines which domain the resulting expression should
be in. If it is <code><classname>proto::deduce_domain</classname></code>, which is the default,
the resulting expression is in the same domain as the expression passed in. Otherwise, the resulting
expression is in the specified domain. Practically, that means the specified domain's generator is
used to post-process the resulting expression.
</para>
<para>
The explicit use of <computeroutput>proto::pass_through&lt;&gt;</computeroutput> is not usually
needed, since the expression generator metafunctions such as
<computeroutput><classname>proto::plus</classname>&lt;&gt;</computeroutput> have
<computeroutput>proto::pass_through&lt;&gt;</computeroutput> as their default transform. So,
for instance, these are equivalent:
<itemizedlist>
<listitem>
<computeroutput>
<classname>proto::when</classname>&lt; <classname>proto::plus</classname>&lt;X, Y&gt;, proto::pass_through&lt; <classname>proto::plus</classname>&lt;X, Y&gt; &gt; &gt;
</computeroutput>
</listitem>
<listitem>
<computeroutput>
<classname>proto::when</classname>&lt; <classname>proto::plus</classname>&lt;X, Y&gt;, <classname>proto::plus</classname>&lt;X, Y&gt; &gt;
</computeroutput>
</listitem>
<listitem>
<computeroutput>
<classname>proto::when</classname>&lt; <classname>proto::plus</classname>&lt;X, Y&gt; &gt; // because of proto::when&lt;class X, class Y=X&gt;
</computeroutput>
</listitem>
<listitem>
<computeroutput>
<classname>proto::plus</classname>&lt;X, Y&gt; // because plus&lt;&gt; is both a grammar and a transform
</computeroutput>
</listitem>
</itemizedlist>
</para>
<para>
For example, consider the following transform that promotes all
<computeroutput>float</computeroutput> terminals in an expression to
<computeroutput>double</computeroutput>.
<programlisting>// This transform finds all float terminals in an expression and promotes
// them to doubles.
struct Promote :
<classname>proto::or_</classname>&lt;
<classname>proto::when</classname>&lt;<classname>proto::terminal</classname>&lt;float&gt;, <classname>proto::terminal</classname>&lt;double&gt;::type(<classname>proto::_value</classname>) &gt;,
// terminal&lt;&gt;'s default transform is a no-op:
<classname>proto::terminal</classname>&lt;<classname>proto::_</classname>&gt;,
// nary_expr&lt;&gt; has a pass_through&lt;&gt; transform:
<classname>proto::nary_expr</classname>&lt;<classname>proto::_</classname>, <classname>proto::vararg</classname>&lt;Promote&gt; &gt;
&gt;
{};</programlisting>
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><type><classname>proto::transform_impl</classname>&lt;Expr, State, Data&gt;</type></inherit>
<typedef name="GN">
<purpose>For each N in [0,Expr arity), for exposition only</purpose>
<type>typename proto::result_of::child_c&lt;Grammar, N&gt;::type</type>
</typedef>
<typedef name="EN">
<purpose>For each N in [0,Expr arity), for exposition only</purpose>
<type>typename proto::result_of::child_c&lt;Expr, N&gt;::type</type>
</typedef>
<typedef name="RN">
<purpose>For each N in [0,Expr arity), for exposition only</purpose>
<type>typename boost::result_of&lt;GN(EN,State,Data)&gt;::type</type>
</typedef>
<typedef name="T">
<purpose>For exposition only</purpose>
<type>typename Expr::proto_tag</type>
</typedef>
<typedef name="Deduce">
<purpose>For exposition only</purpose>
<type>boost::is_same&lt;Domain, <classname>deduce_domain</classname>&gt;</type>
</typedef>
<typedef name="DD">
<purpose>For exposition only</purpose>
<type>typename Expr::proto_domain</type>
</typedef>
<typedef name="D">
<purpose>For exposition only</purpose>
<type>typename mpl::if_&lt;Deduce, DD, Domain&gt;::type</type>
</typedef>
<typedef name="G">
<purpose>For exposition only</purpose>
<type>typename D::proto_generator</type>
</typedef>
<typedef name="A">
<purpose>For exposition only</purpose>
<type><classname>proto::listN</classname>&lt;R0,...RN&gt;</type>
</typedef>
<typedef name="E">
<purpose>For exposition only</purpose>
<type><classname>proto::expr</classname>&lt;T, A&gt;</type>
</typedef>
<typedef name="BE">
<purpose>For exposition only</purpose>
<type><classname>proto::basic_expr</classname>&lt;T, A&gt;</type>
</typedef>
<typedef name="expr_type">
<purpose>For exposition only</purpose>
<type>typename mpl::if_&lt;<classname>proto::wants_basic_expr</classname>&lt;G&gt;, BE, E&gt;::type</type>
</typedef>
<typedef name="result_type">
<type>typename boost::result_of&lt;D(expr_type)&gt;::type</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
</parameter>
<requires>
<para>
<computeroutput>
<classname>proto::matches</classname>&lt;Expr, Grammar&gt;::value
</computeroutput> is <computeroutput>true</computeroutput>.
</para>
</requires>
<returns>
<para>
<programlisting>D()(expr_type::make(
G0()(<functionname>proto::child_c</functionname>&lt;0&gt;(expr), state, data),
...
GN()(<functionname>proto::child_c</functionname>&lt;N&gt;(expr), state, data)
))</programlisting>
</para>
</returns>
</method>
</method-group>
</struct>
</struct>
</namespace>
</namespace>
</header>

View File

@@ -0,0 +1,545 @@
<?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/when.hpp">
<para>
Definition of the
<computeroutput>
<classname alt="boost::proto::when">proto::when&lt;&gt;</classname>
</computeroutput> and
<computeroutput>
<classname alt="boost::proto::otherwise">proto::otherwise&lt;&gt;</classname>
</computeroutput> transforms.
</para>
<namespace name="boost">
<namespace name="proto">
<!-- struct transforms_type -->
<struct name="transforms_type">
<purpose>
The type used to define the global <code><globalname>proto::transforms</globalname></code>,
a key for use when creating and accessing a slot in a transform environment for
a set of external transforms.
</purpose>
<description>
<para>
The <code>proto::transforms_type</code> type, along with the <code><globalname>proto::transforms</globalname></code>
global, are declared using the <code><macroname>BOOST_PROTO_DEFINE_ENV_VAR</macroname>()</code> macro.
</para>
</description>
<method-group name="public member functions">
<overloaded-method name="operator=">
<signature cv="const">
<template>
<template-type-parameter name="Value"/>
</template>
<type><classname>env</classname>&lt;transforms_type, <replaceable>see-below</replaceable>&gt;</type>
<parameter name="value">
<paramtype>Value &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<template>
<template-type-parameter name="Value"/>
</template>
<type><classname>env</classname>&lt;transforms_type, <replaceable>see-below</replaceable>&gt;</type>
<parameter name="value">
<paramtype>Value const &amp;</paramtype>
</parameter>
</signature>
<description>
<para>
If <code>Value</code> is a specialization <code>boost::reference_wrapper&lt;T&gt;</code>,
this function returns <code><classname>env</classname>&lt;transforms_type, T &amp;&gt;(value.get())</code>.
</para>
<para>
Else, if the type <code>Value</code> is non-copyable (i.e., a function, an array, abstract, or an ostream),
this function returns <code><classname>env</classname>&lt;transforms_type, Value <replaceable>cv</replaceable> &amp;&gt;(value)</code>,
where <code><replaceable>cv</replaceable></code> is <code>const</code> for the second overload, and empty
for the first.
</para>
<para>
Otherwise, this function returns <code><classname>env</classname>&lt;transforms_type, Value&gt;(value)</code>.
</para>
</description>
</overloaded-method>
</method-group>
</struct>
<data-member name="transforms">
<description>
<para>
A key key for use when creating and accessing a slot in a transform environment for
a set of external transforms.
</para>
</description>
<type><classname>proto::transforms_type</classname> const</type>
</data-member>
<struct name="when">
<template>
<template-type-parameter name="Grammar"/>
<template-type-parameter name="PrimitiveTransform">
<default>Grammar</default>
</template-type-parameter>
</template>
<purpose>A grammar element and a <conceptname>PrimitiveTransform</conceptname> that associates
a transform with the grammar.</purpose>
<description>
<para>
Use <computeroutput>proto::when&lt;&gt;</computeroutput> 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.
<programlisting>// Count the terminals in an expression tree.
// Must be invoked with initial state == mpl::int_&lt;0&gt;().
struct CountLeaves :
<classname>proto::or_</classname>&lt;
proto::when&lt;<classname>proto::terminal</classname>&lt;<classname>proto::_</classname>&gt;, mpl::next&lt;<classname>proto::_state</classname>&gt;()&gt;,
proto::otherwise&lt;<classname>proto::fold</classname>&lt;<classname>proto::_</classname>, <classname>proto::_state</classname>, CountLeaves&gt; &gt;
&gt;
{};</programlisting>
</para>
<para>
In <computeroutput>proto::when&lt;G, T&gt;</computeroutput>, when <computeroutput>T</computeroutput>
is a class type it is a <conceptname>PrimitiveTransform</conceptname> and the following equivalencies hold:
</para>
<itemizedlist>
<listitem>
<para>
<computeroutput>boost::result_of&lt;proto::when&lt;G,T&gt;(E,S,V)&gt;::type</computeroutput> is the same as
<computeroutput>boost::result_of&lt;T(E,S,V)&gt;::type</computeroutput>.
</para>
</listitem>
<listitem>
<para>
<computeroutput>proto::when&lt;G,T&gt;()(e,s,d)</computeroutput> is the same as
<computeroutput>T()(e,s,d)</computeroutput>.
</para>
</listitem>
</itemizedlist>
</description>
<inherit><type>PrimitiveTransform</type></inherit>
<typedef name="proto_grammar">
<type>typename Grammar::proto_grammar</type>
</typedef>
</struct>
<struct-specialization name="when">
<template>
<template-type-parameter name="Grammar"/>
<template-type-parameter name="Fun"/>
</template>
<specialization>
<template-arg>Grammar</template-arg>
<template-arg>Fun *</template-arg>
</specialization>
<inherit><type><classname>proto::when</classname>&lt; Grammar, Fun &gt;</type></inherit>
<purpose>A specialization that treats function pointer <conceptname>Transform</conceptname>s as if they
were function type <conceptname>Transform</conceptname>s.</purpose>
<description>
<para>
This specialization requires that <computeroutput>Fun</computeroutput> is actually a function type.
</para>
<para>
This specialization is required for nested transforms such as
<computeroutput>proto::when&lt;G, T0(T1(_))&gt;</computeroutput>. In C++, functions that are used
as parameters to other functions automatically decay to funtion pointer types. In other words, the
type <computeroutput>T0(T1(_))</computeroutput> is indistinguishable from
<computeroutput>T0(T1(*)(_))</computeroutput>. This specialization is required to handle these
nested function pointer type transforms properly.
</para>
</description>
</struct-specialization>
<struct-specialization name="when">
<template>
<template-type-parameter name="Grammar"/>
<template-type-parameter name="R"/>
<template-type-parameter name="A" pack="1"/>
</template>
<specialization>
<template-arg>Grammar</template-arg>
<template-arg>R(A...)</template-arg>
</specialization>
<inherit><type><classname>proto::transform</classname>&lt; when&lt;Grammar, R(A...)&gt; &gt;</type></inherit>
<purpose>A grammar element and a <conceptname>Transform</conceptname> that associates a
transform with the grammar. </purpose>
<description>
<para>
Use <computeroutput>proto::when&lt;&gt;</computeroutput> to override a grammar's default
transform with a custom transform. It is for use when composing larger transforms by associating
smaller transforms with individual rules in your grammar.
</para>
<para>
The <computeroutput>when&lt;G, R(A...)&gt;</computeroutput> form accepts either a
<conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its
second parameter. <computeroutput>proto::when&lt;&gt;</computeroutput> uses
<computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::value</computeroutput> to
distinguish between the two, and uses
<computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> to evaluate
<conceptname>CallableTransform</conceptname>s and
<computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> to evaluate
<conceptname>ObjectTransform</conceptname>s.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><type><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</type></inherit>
<typedef name="call_">
<purpose>For exposition only</purpose>
<type><classname>proto::call</classname>&lt;R(A...)&gt;</type>
</typedef>
<typedef name="make_">
<purpose>For exposition only</purpose>
<type><classname>proto::make</classname>&lt;R(A...)&gt;</type>
</typedef>
<typedef name="which">
<purpose>For exposition only</purpose>
<type>typename mpl::if_&lt;<classname>proto::is_callable</classname>&lt;R&gt;,call_,make_&gt;::type</type>
</typedef>
<typedef name="result_type">
<type>typename boost::result_of&lt;which(Expr, State, Data)&gt;::type</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
<description>
<para>The current expression </para>
</description>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
<description>
<para>The current state </para>
</description>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
<description>
<para>An arbitrary data </para>
</description>
</parameter>
<description>
<para>
Evaluate <computeroutput>R(A...)</computeroutput> as a transform either with
<computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> or with
<computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> depending
on whether <computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::value</computeroutput>
is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.
</para>
</description>
<requires>
<para>
<computeroutput><classname>proto::matches</classname>&lt;Expr, Grammar&gt;::value</computeroutput>
is <computeroutput>true</computeroutput>.
</para>
</requires>
<returns>
<para>
<computeroutput>which()(expr, state, data)</computeroutput>
</para>
</returns>
</method>
</method-group>
</struct>
<typedef name="proto_grammar">
<type>typename Grammar::proto_grammar</type>
</typedef>
</struct-specialization>
<struct-specialization name="when">
<template>
<template-type-parameter name="Grammar"/>
<template-type-parameter name="R"/>
<template-type-parameter name="A" pack="1"/>
</template>
<specialization>
<template-arg>Grammar</template-arg>
<template-arg>R(A..., ...)</template-arg>
</specialization>
<inherit><type><classname>proto::transform</classname>&lt; when&lt;Grammar, R(A..., ...)&gt; &gt;</type></inherit>
<purpose>A grammar element and a <conceptname>Transform</conceptname> that associates a
transform with the grammar. </purpose>
<description>
<para>
Use <computeroutput>proto::when&lt;&gt;</computeroutput> to override a grammar's default
transform with a custom transform. It is for use when composing larger transforms by associating
smaller transforms with individual rules in your grammar.
</para>
<para>
The <computeroutput>when&lt;G, R(A..., ...)&gt;</computeroutput> form accepts either a
<conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its
second parameter. <computeroutput>proto::when&lt;&gt;</computeroutput> uses
<computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::value</computeroutput> to
distinguish between the two, and uses
<computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> to evaluate
<conceptname>CallableTransform</conceptname>s and
<computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> to evaluate
<conceptname>ObjectTransform</conceptname>s.
</para>
<para>
<emphasis role="bold">Note:</emphasis> In the specialization
<computeroutput>when&lt;G, R(A..., ...)&gt;</computeroutput>, the first ellipsis denotes a
C++11-style variadic template (which is emulated for C++98 compilers). The second ellipsis
is a C-style vararg.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><type><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</type></inherit>
<typedef name="call_">
<purpose>For exposition only</purpose>
<type><classname>proto::call</classname>&lt;R(A..., ...)&gt;</type>
</typedef>
<typedef name="make_">
<purpose>For exposition only</purpose>
<type><classname>proto::make</classname>&lt;R(A..., ...)&gt;</type>
</typedef>
<typedef name="which">
<purpose>For exposition only</purpose>
<type>typename mpl::if_&lt;<classname>proto::is_callable</classname>&lt;R&gt;,call_,make_&gt;::type</type>
</typedef>
<typedef name="result_type">
<type>typename boost::result_of&lt;which(Expr, State, Data)&gt;::type</type>
</typedef>
<method-group name="public member functions">
<method name="operator()" cv="const">
<type>result_type</type>
<parameter name="expr">
<paramtype>typename impl::expr_param</paramtype>
<description>
<para>The current expression </para>
</description>
</parameter>
<parameter name="state">
<paramtype>typename impl::state_param</paramtype>
<description>
<para>The current state </para>
</description>
</parameter>
<parameter name="data">
<paramtype>typename impl::data_param</paramtype>
<description>
<para>An arbitrary data </para>
</description>
</parameter>
<description>
<para>
Evaluate <computeroutput>R(A..., ...)</computeroutput> as a transform either with
<computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> or with
<computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> depending
on whether <computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::value</computeroutput>
is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.
</para>
</description>
<requires>
<para>
<computeroutput><classname>proto::matches</classname>&lt;Expr, Grammar&gt;::value</computeroutput>
is <computeroutput>true</computeroutput>.
</para>
</requires>
<returns>
<para>
<computeroutput>which()(expr, state, data)</computeroutput>
</para>
</returns>
</method>
</method-group>
</struct>
<typedef name="proto_grammar">
<type>typename Grammar::proto_grammar</type>
</typedef>
</struct-specialization>
<struct-specialization name="when">
<template>
<template-type-parameter name="Grammar"/>
</template>
<specialization>
<template-arg>Grammar</template-arg>
<template-arg><classname>proto::external_transform</classname></template-arg>
</specialization>
<inherit><type>
<classname>proto::transform</classname>&lt; when&lt;Grammar, <classname>proto::external_transform</classname>&gt; &gt;</type></inherit>
<purpose>A grammar element that associates an externally-specified transform with the grammar.
The transform is looked up in the Data parameter using the Grammar as a key.</purpose>
<description>
<para>
Use <computeroutput>proto::when&lt;&gt;</computeroutput> to override a grammar's default
transform with a custom transform. It is for use when composing larger transforms by associating
smaller transforms with individual rules in your grammar.
</para>
<para>
The <computeroutput>when&lt;G, <classname>proto::external_transform</classname>&gt;</computeroutput>
indicates that the associated transform is not yet known. It should be looked up when the transform
is about to be applied. It is found by looking it up in the passed-in Data parameter, which
behaves like a compile-time map from grammar types to transform types. The map is indexed using
<computeroutput>Grammar</computeroutput> as a key. The associated value type is used as the transform
to apply. In this way, the same grammar can be used to define multiple evaluating strategies that
can be added post-hoc.
</para>
<para>
See <computeroutput><classname>proto::external_transforms</classname></computeroutput> for an example.
</para>
</description>
<struct name="impl">
<template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="State"/>
<template-type-parameter name="Data"/>
</template>
<inherit><type>
boost::remove_reference&lt;
typename mpl::eval_if_c&lt;
<classname>proto::result_of::has_env_var</classname>&lt;Data, <classname>proto::transforms_type</classname>&gt;::value,
<classname>proto::result_of::env_var</classname>&lt;Data, <classname>proto::transforms_type</classname>&gt;,
<classname>proto::result_of::env_var</classname>&lt;Data, <classname>proto::data_type</classname>&gt;
&gt;::type
&gt;::type
::template when&lt; Grammar &gt;
::template impl&lt; Expr, State, Data &gt;</type></inherit>
<description>
<para>
The implementation of the <code>impl</code> struct depends on whether the <code>Data</code>
parameter is a transform environment that contains a value corresponding to the
<classname>proto::transforms_type</classname> key. If so, that value is treated as a
map from rules to transforms. Otherwise, the <code>Data</code> type itself is treated
as such a map.
</para>
</description>
</struct>
<typedef name="proto_grammar">
<type>typename Grammar::proto_grammar</type>
</typedef>
</struct-specialization>
<struct name="otherwise">
<template>
<template-type-parameter name="Fun"/>
</template>
<inherit><type><classname>proto::when</classname>&lt; <classname>proto::_</classname>, Fun &gt;</type></inherit>
<purpose>
Syntactic sugar for <computeroutput><classname>proto::when</classname>&lt; <classname>proto::_</classname>, Fun &gt;</computeroutput>,
for use in grammars to handle all the cases not yet handled.
</purpose>
<description>
<para>
Use <computeroutput>proto::otherwise&lt;T&gt;</computeroutput> in your grammars as a synonym for
<computeroutput><classname>proto::when</classname>&lt; <classname>proto::_</classname>, Fun &gt;</computeroutput>
as in the following transform which counts the number of terminals in an expression.
</para>
<para>
<programlisting>// Count the terminals in an expression tree.
// Must be invoked with initial state == mpl::int_&lt;0&gt;().
struct CountLeaves :
<classname>proto::or_</classname>&lt;
proto::when&lt;<classname>proto::terminal</classname>&lt;<classname>proto::_</classname>&gt;, mpl::next&lt;<classname>proto::_state</classname>&gt;()&gt;,
proto::otherwise&lt;<classname>proto::fold</classname>&lt;<classname>proto::_</classname>, <classname>proto::_state</classname>, CountLeaves&gt; &gt;
&gt;
{};</programlisting>
</para>
</description>
</struct>
<struct name="external_transform">
<purpose>A placeholder for use as the second parameter for <computeroutput><classname>proto::when</classname></computeroutput>
to indicate that the rule's transform is specified externally.</purpose>
<description>
<para>
See <computeroutput><classname>proto::external_transforms</classname></computeroutput> for an example.
</para>
</description>
</struct>
<struct name="external_transforms">
<template>
<template-type-parameter name="When" pack="1"/>
</template>
<purpose>A map from grammars to transforms, used as a way to externally associate transforms.</purpose>
<typedef name="map_type">
<purpose>For exposition only.</purpose>
<type>mpl::map&lt; typename to_mpl_pair&lt; When &gt;::type... &gt;</type>
</typedef>
<struct name="when">
<template>
<template-type-parameter name="Grammar"/>
</template>
<inherit><type><classname>proto::otherwise</classname>&lt; typename mpl::at&lt; map_type, Grammar &gt;::type &gt;</type></inherit>
</struct>
<description>
<para>
It is sometimes desirable to define a grammar that can be customized with different sets of transforms.
To do that, where you would normally specify a transform within a grammar, you can instead put
<computeroutput><classname>proto::external_transform</classname></computeroutput>; for example:
<computeroutput>proto::when&lt; some_grammar, proto::external_transform &gt;</computeroutput>. Then, when
invoking the grammar, you can pass an approriately-defined instance of <computeroutput>proto::external_transforms</computeroutput>
as the Data parameter. When an expression matches <computeroutput>some_grammar</computeroutput>, Proto
will look up the approprite transform in the Data parameter using <computeroutput>some_grammar</computeroutput>
as a key.
</para>
<para>
<programlisting>struct int_terminal
: <classname>proto::terminal</classname>&lt;int&gt;
{};
struct char_terminal
: <classname>proto::terminal</classname>&lt;char&gt;
{};
struct my_grammar
: <classname>proto::or_</classname>&lt;
// The next two grammar rules are customization points.
// The associated transforms are specified externally
// using external_transforms below.
<classname>proto::when</classname>&lt; int_terminal, <classname>proto::external_transform</classname> &gt;
, <classname>proto::when</classname>&lt; char_terminal, <classname>proto::external_transform</classname> &gt;
, <classname>proto::when</classname>&lt;
<classname>proto::plus</classname>&lt; my_grammar, my_grammar &gt;
, <classname>proto::fold</classname>&lt; <classname>proto::_</classname>, int(), my_grammar &gt;
&gt;
&gt;
{};
// Here is where the transforms are associated with the
// grammar rules above.
struct my_transforms
: proto::external_transforms&lt;
<classname>proto::when</classname>&lt;int_terminal, print(<classname>proto::_value</classname>)&gt;
, <classname>proto::when</classname>&lt;char_terminal, print(<classname>proto::_value</classname>)&gt;
&gt;
{};
// ...
<classname>proto::literal</classname>&lt;int&gt; i(1);
<classname>proto::literal</classname>&lt;char&gt; c('a');
my_transforms trx;
// Evaluate "i+c" using my_grammar with the specified transforms:
my_grammar()(i + c, 0, trx);
// If you would also like to pass arbitrary data along with the
// transforms, you can use a transform environment, as so:
my_grammar()(i + c, 0, (proto::data = 42, proto::transforms = trx));</programlisting>
</para>
</description>
</struct>
</namespace>
</namespace>
</header>