1<?xml version="1.0" encoding="utf-8"?> 2<!-- 3 Copyright 2012 Eric Niebler 4 5 Distributed under the Boost 6 Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 --> 9<header name="boost/proto/transform/impl.hpp"> 10 <para>Contains definition of transform<> and transform_impl<> helpers. </para> 11 <namespace name="boost"> 12 <namespace name="proto"> 13 14 <!-- proto::transform --> 15 <struct name="transform"> 16 <template> 17 <template-type-parameter name="PrimitiveTransform"/> 18 </template> 19 <purpose>Inherit from this to make your type a <conceptname>PrimitiveTransform</conceptname>.</purpose> 20 <struct-specialization name="result"> 21 <template> 22 <template-type-parameter name="This"/> 23 <template-type-parameter name="Expr"/> 24 </template> 25 <specialization> 26 <template-arg>This(Expr)</template-arg> 27 </specialization> 28 <typedef name="type"> 29 <type>typename PrimitiveTransform::template impl< Expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable> >::result_type</type> 30 </typedef> 31 </struct-specialization> 32 <struct-specialization name="result"> 33 <template> 34 <template-type-parameter name="This"/> 35 <template-type-parameter name="Expr"/> 36 <template-type-parameter name="State"/> 37 </template> 38 <specialization> 39 <template-arg>This(Expr, State)</template-arg> 40 </specialization> 41 <typedef name="type"> 42 <type>typename PrimitiveTransform::template impl< Expr, State, <replaceable>unspecified</replaceable> >::result_type</type> 43 </typedef> 44 </struct-specialization> 45 <struct-specialization name="result"> 46 <template> 47 <template-type-parameter name="This"/> 48 <template-type-parameter name="Expr"/> 49 <template-type-parameter name="State"/> 50 <template-type-parameter name="Data"/> 51 </template> 52 <specialization> 53 <template-arg>This(Expr, State, Data)</template-arg> 54 </specialization> 55 <typedef name="type"> 56 <type>typename PrimitiveTransform::template impl< Expr, State, Data >::result_type</type> 57 </typedef> 58 </struct-specialization> 59 <typedef name="transform_type"> 60 <type>PrimitiveTransform</type> 61 </typedef> 62 <method-group name="public member functions"> 63 <method name="operator()" cv="const"> 64 <type>typename PrimitiveTransform::template impl<Expr &, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>>::result_type</type> 65 <template> 66 <template-type-parameter name="Expr"/> 67 </template> 68 <parameter name="expr"> 69 <paramtype>Expr &</paramtype> 70 </parameter> 71 <returns> 72 <computeroutput> 73 typename PrimitiveTransform::template impl<Expr &, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>>()(expr, <replaceable>unspecified</replaceable>, <replaceable>unspecified</replaceable>) 74 </computeroutput> 75 </returns> 76 </method> 77 <method name="operator()" cv="const"> 78 <type>typename PrimitiveTransform::template impl<Expr &, State &, <replaceable>unspecified</replaceable>>::result_type</type> 79 <template> 80 <template-type-parameter name="Expr"/> 81 <template-type-parameter name="State"/> 82 </template> 83 <parameter name="expr"> 84 <paramtype>Expr &</paramtype> 85 </parameter> 86 <parameter name="state"> 87 <paramtype>State &</paramtype> 88 </parameter> 89 <returns> 90 <computeroutput> 91 typename PrimitiveTransform::template impl<Expr &, State &, <replaceable>unspecified</replaceable>>()(expr, state, <replaceable>unspecified</replaceable>) 92 </computeroutput> 93 </returns> 94 </method> 95 <method name="operator()" cv="const"> 96 <type>typename PrimitiveTransform::template impl<Expr &, State const &, <replaceable>unspecified</replaceable>>::result_type</type> 97 <template> 98 <template-type-parameter name="Expr"/> 99 <template-type-parameter name="State"/> 100 </template> 101 <parameter name="expr"> 102 <paramtype>Expr &</paramtype> 103 </parameter> 104 <parameter name="state"> 105 <paramtype>State const &</paramtype> 106 </parameter> 107 <returns> 108 <computeroutput> 109 typename PrimitiveTransform::template impl<Expr &, State const &, <replaceable>unspecified</replaceable>>()(expr, state, <replaceable>unspecified</replaceable>) 110 </computeroutput> 111 </returns> 112 </method> 113 <method name="operator()" cv="const"> 114 <type>typename PrimitiveTransform::template impl<Expr &, State &, Data &>::result_type</type> 115 <template> 116 <template-type-parameter name="Expr"/> 117 <template-type-parameter name="State"/> 118 <template-type-parameter name="Data"/> 119 </template> 120 <parameter name="expr"> 121 <paramtype>Expr &</paramtype> 122 </parameter> 123 <parameter name="state"> 124 <paramtype>State &</paramtype> 125 </parameter> 126 <parameter name="data"> 127 <paramtype>Data &</paramtype> 128 </parameter> 129 <returns> 130 <computeroutput> 131 typename PrimitiveTransform::template impl<Expr &, State &, Data &>()(expr, state, data) 132 </computeroutput> 133 </returns> 134 </method> 135 <method name="operator()" cv="const"> 136 <type>typename PrimitiveTransform::template impl<Expr &, State const &, Data &>::result_type</type> 137 <template> 138 <template-type-parameter name="Expr"/> 139 <template-type-parameter name="State"/> 140 <template-type-parameter name="Data"/> 141 </template> 142 <parameter name="expr"> 143 <paramtype>Expr &</paramtype> 144 </parameter> 145 <parameter name="state"> 146 <paramtype>State const &</paramtype> 147 </parameter> 148 <parameter name="data"> 149 <paramtype>Data &</paramtype> 150 </parameter> 151 <returns> 152 <computeroutput> 153 typename PrimitiveTransform::template impl<Expr &, State const &, Data &>()(expr, state, data) 154 </computeroutput> 155 </returns> 156 </method> 157 </method-group> 158 </struct> 159 160 <!-- proto::transform_impl --> 161 <struct name="transform_impl"> 162 <template> 163 <template-type-parameter name="Expr"/> 164 <template-type-parameter name="State"/> 165 <template-type-parameter name="Data"/> 166 </template> 167 <typedef name="expr"> 168 <type>typename boost::remove_reference<Expr const>::type</type> 169 </typedef> 170 <typedef name="expr_param"> 171 <type>typename boost::add_reference<Expr const>::type</type> 172 </typedef> 173 <typedef name="state"> 174 <type>typename boost::remove_reference<State const>::type</type> 175 </typedef> 176 <typedef name="state_param"> 177 <type>typename boost::add_reference<State const>::type</type> 178 </typedef> 179 <typedef name="data"> 180 <type>typename boost::remove_reference<Data const>::type</type> 181 </typedef> 182 <typedef name="data_param"> 183 <type>typename boost::add_reference<Data const>::type</type> 184 </typedef> 185 </struct> 186 187 <!-- proto::pack --> 188 <struct name="pack"> 189 <purpose>To turn an expression into a pseudo-parameter pack containing the 190 expression's children, for the purpose of expanding the pack expression within 191 a <conceptname>CallableTransform</conceptname> or 192 <conceptname>ObjectTransform</conceptname>.</purpose> 193 <description> 194 <para> 195 <computeroutput>proto::pack</computeroutput> is useful within 196 <conceptname>CallableTransform</conceptname>s and 197 <conceptname>ObjectTransform</conceptname>s when one wishes to unpack an expression 198 into a function call or an object constructor. <computeroutput>proto::pack</computeroutput> 199 turns a Proto expression into a pseudo-parameter pack, which may appear in an unpacking 200 pattern to be expanded with the "<computeroutput>...</computeroutput>" syntax. 201 </para> 202 203 <para> 204 <emphasis role="bold">Example:</emphasis> 205 </para> 206 207 <para> 208 <programlisting>// The following demonstrates how to use a pseudo-pack expansion 209// to unpack an expression into a function call. 210 211struct do_sum : <classname alt="boost::proto::callable">proto::callable</classname> 212{ 213 typedef int result_type; 214 215 int operator()(int i) const { return i; } 216 int operator()(int i, int j) const { return i + j; } 217 int operator()(int i, int j, int k) const { return i + j + k; } 218}; 219 220// Take any n-ary expression where the children are all int terminals and sum all the ints 221struct sum 222 : <classname alt="boost::proto::when">proto::when</classname>< 223 224 // Match any nary expression where the children are all int terminals 225 <classname alt="boost::proto::nary_expr">proto::nary_expr</classname><<classname alt="boost::proto::_">_</classname>, <classname alt="boost::proto::vararg">proto::vararg</classname><<classname alt="boost::proto::terminal">proto::terminal</classname><int> > > 226 227 // Turn the current expression into a pseudo-parameter pack, then expand it, 228 // extracting the value from each child in turn. 229 , do_sum(<classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>))...) 230 > 231{}; 232 233int main() 234{ 235 <classname alt="boost::proto::terminal">proto::terminal</classname><int>::type i = {42}; 236 int result = sum()( i(3,5) ); // Creates a ternary functional-call expression 237 std::cout << "Sum of 42, 3, and 5 : " << result << std::endl; 238}</programlisting> 239 </para> 240 241 <para> 242 The above program displays: 243 </para> 244 245 <para> 246 <computeroutput>Sum of 42, 3, and 5 : 50</computeroutput> 247 </para> 248 249 <para> 250 In the above example, the type 251 <computeroutput> 252 <classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>)) 253 </computeroutput> 254 is a so-called <emphasis>unpacking pattern</emphasis>, described below. 255 </para> 256 257 <para> 258 <emphasis role="bold">Unpacking Patterns:</emphasis> 259 </para> 260 261 <para> 262 Composite transforms (either <conceptname>CallableTransform</conceptname>s or 263 <conceptname>ObjectTransform</conceptname>s) usually have the form 264 <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>. 265 However, when the argument list in a composite transform is terminated with a C-style 266 vararg ellipsis as in <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, 267 the final argument <computeroutput>A<subscript>n</subscript></computeroutput> is treated 268 as an <emphasis>unpacking pattern</emphasis>. 269 </para> 270 271 <para> 272 An unpacking pattern must itself be a composite transform; that is, it must be a 273 function type representing either a <conceptname>CallableTransform</conceptname> or 274 an <conceptname>ObjectTransform</conceptname>. The type <computeroutput>proto::pack(_)</computeroutput> 275 must appear exactly once in the unpacking pattern. This type will receive a substitution 276 when the unpacking pattern is expanded. 277 </para> 278 279 <para> 280 A composite transform like <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, 281 when evaluated against a given expression <replaceable>E</replaceable>, state and data, is evaluated as if it were 282 <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n-1</subscript>,<replaceable>S</replaceable>)</computeroutput> 283 where <replaceable>S</replaceable> is a type sequence computed as follows: 284 </para> 285 <para> 286 Let <computeroutput><replaceable>SUB</replaceable>(A,B)</computeroutput> be a type function that replaces every occurence of 287 <computeroutput>proto::pack(_)</computeroutput> within <computeroutput>A</computeroutput> with <computeroutput>B</computeroutput>. 288 <itemizedlist> 289 <listitem> 290 If the expression <replaceable>E</replaceable> is a terminal (i.e. it has arity 0), <replaceable>S</replaceable> 291 is the one-element sequence containing <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_value">proto::_value</classname>)</computeroutput>. 292 </listitem> 293 <listitem> 294 If the expression <replaceable>E</replaceable> is a non-terminal, <replaceable>S</replaceable> is the sequence 295 <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname><0>),… 296 <replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname><<replaceable>M</replaceable>-1>)</computeroutput>, where 297 <replaceable>M</replaceable> is the arity of the expression <replaceable>E</replaceable>. 298 </listitem> 299 </itemizedlist> 300 </para> 301 </description> 302 </struct> 303 304 </namespace> 305 </namespace> 306</header> 307