impl.xml 14 KB

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