make.xml 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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/make.hpp">
  9. <para>
  10. Contains definition of the
  11. <computeroutput>
  12. <classname alt="boost::proto::make">proto::make&lt;&gt;</classname>
  13. </computeroutput>
  14. and
  15. <computeroutput>
  16. <classname alt="boost::proto::protect">proto::protect&lt;&gt;</classname>
  17. </computeroutput>
  18. transforms.
  19. </para>
  20. <namespace name="boost">
  21. <namespace name="proto">
  22. <struct name="noinvoke">
  23. <template>
  24. <template-type-parameter name="T"/>
  25. </template>
  26. <purpose>A type annotation in an <conceptname>ObjectTransform</conceptname> which instructs
  27. Proto not to look for a nested <computeroutput>::type</computeroutput> within
  28. <computeroutput>T</computeroutput> after type substitution.</purpose>
  29. <description>
  30. <para>
  31. <conceptname>ObjectTransform</conceptname>s are evaluated by
  32. <computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>,
  33. which finds all nested transforms and replaces them with the result of their applications.
  34. If any substitutions are performed, the result is first assumed to be a metafunction to be applied;
  35. that is, Proto checks to see if the result has a nested <computeroutput>::type</computeroutput>
  36. typedef. If it does, that becomes the result. The purpose of <computeroutput>proto::noinvoke&lt;&gt;</computeroutput>
  37. is to prevent Proto from looking for a nested <computeroutput>::type</computeroutput> typedef
  38. in these situations.
  39. </para>
  40. <para>
  41. Example:
  42. <programlisting>struct Test
  43. : <classname>proto::when</classname>&lt;
  44. <classname>_</classname>
  45. , proto::noinvoke&lt;
  46. // This remove_pointer invocation is bloked by noinvoke
  47. boost::remove_pointer&lt;
  48. // This add_pointer invocation is *not* blocked by noinvoke
  49. boost::add_pointer&lt;<classname>_</classname>&gt;
  50. &gt;
  51. &gt;()
  52. &gt;
  53. {};
  54. void test_noinvoke()
  55. {
  56. typedef <classname>proto::terminal</classname>&lt;int&gt;::type Int;
  57. BOOST_MPL_ASSERT((
  58. boost::is_same&lt;
  59. boost::result_of&lt;Test(Int)&gt;::type
  60. , boost::remove_pointer&lt;Int *&gt;
  61. &gt;
  62. ));
  63. Int i = {42};
  64. boost::remove_pointer&lt;Int *&gt; t = Test()(i);
  65. }</programlisting>
  66. </para>
  67. </description>
  68. </struct>
  69. <struct name="protect">
  70. <template>
  71. <template-type-parameter name="PrimitiveTransform"/>
  72. </template>
  73. <inherit><classname>proto::transform</classname>&lt; protect&lt;PrimitiveTransform&gt; &gt;</inherit>
  74. <purpose>A <conceptname>PrimitiveTransform</conceptname> which prevents another
  75. <conceptname>PrimitiveTransform</conceptname> from being applied in an
  76. <conceptname>ObjectTransform</conceptname>.</purpose>
  77. <description>
  78. <para>
  79. When building higher order transforms with
  80. <computeroutput>
  81. <classname alt="proto::make">proto::make&lt;&gt;</classname>
  82. </computeroutput> or
  83. <computeroutput>
  84. <classname alt="proto::lazy">proto::lazy&lt;&gt;</classname>
  85. </computeroutput>,
  86. you sometimes would like to build types that are parameterized with Proto transforms. In such
  87. lambda-style transforms, Proto will unhelpfully find all nested transforms and apply them, even
  88. if you don't want them to be applied. Consider the following transform, which will replace the
  89. <computeroutput>proto::_</computeroutput> in
  90. <computeroutput>Bar&lt;proto::_&gt;()</computeroutput>
  91. with <computeroutput>proto::terminal&lt;int&gt;::type</computeroutput>:
  92. </para>
  93. <para>
  94. <programlisting>template&lt;typename T&gt;
  95. struct Bar
  96. {};
  97. struct Foo :
  98. <classname>proto::when</classname>&lt;<classname>proto::_</classname>, Bar&lt;<classname>proto::_</classname>&gt;() &gt;
  99. {};
  100. <classname>proto::terminal</classname>&lt;int&gt;::type i = {0};
  101. int main() {
  102. Foo()(i);
  103. std::cout &lt;&lt; typeid(Foo()(i)).name() &lt;&lt; std::endl;
  104. }</programlisting>
  105. </para>
  106. <para>
  107. If you actually wanted to default-construct an object of type
  108. <computeroutput>Bar&lt;proto::_&gt;</computeroutput>, you would have to protect the
  109. <computeroutput>_</computeroutput> to prevent it from being applied. You can
  110. use <computeroutput>proto::protect&lt;&gt;</computeroutput> as follows:
  111. </para>
  112. <para>
  113. <programlisting>// OK: replace anything with Bar&lt;_&gt;()
  114. struct Foo :
  115. <classname>proto::when</classname>&lt;<classname>proto::_</classname>, Bar&lt;<classname>proto::protect</classname>&lt;<classname>proto::_</classname>&gt; &gt;() &gt;
  116. {};</programlisting>
  117. </para>
  118. </description>
  119. <struct name="impl">
  120. <template>
  121. <template-type-parameter name=""/>
  122. <template-type-parameter name=""/>
  123. <template-type-parameter name=""/>
  124. </template>
  125. <typedef name="result_type">
  126. <type>PrimitiveTransform</type>
  127. </typedef>
  128. </struct>
  129. </struct>
  130. <struct name="make">
  131. <template>
  132. <template-type-parameter name="T"/>
  133. </template>
  134. <inherit><classname>proto::transform</classname>&lt; make&lt;T&gt; &gt;</inherit>
  135. <purpose>A <conceptname>PrimitiveTransform</conceptname> that computes a type by evaluating
  136. any nested transforms and then constructs an object of that type. </purpose>
  137. <description>
  138. <para>
  139. The purpose of <computeroutput>proto::make&lt;&gt;</computeroutput> is to annotate a transform as
  140. an <conceptname>ObjectTransform</conceptname> so that
  141. <computeroutput><classname alt="proto::when">proto::when&lt;&gt;</classname></computeroutput> knows
  142. how to apply it.
  143. </para>
  144. <para>
  145. For the full description of the behavior of the
  146. <computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>
  147. transform, see the documentation for the nested
  148. <computeroutput><classname alt="proto::make::impl">proto::make::impl&lt;&gt;</classname></computeroutput>
  149. class template.
  150. </para>
  151. </description>
  152. <struct name="impl">
  153. <template>
  154. <template-type-parameter name="Expr"/>
  155. <template-type-parameter name="State"/>
  156. <template-type-parameter name="Data"/>
  157. </template>
  158. <inherit><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</inherit>
  159. <typedef name="result_type">
  160. <type><emphasis>see-below</emphasis></type>
  161. <description>
  162. <para>
  163. <computeroutput><classname>proto::make</classname>&lt;T&gt;::impl&lt;Expr, State, Data&gt;::result_type</computeroutput> is
  164. computed as follows:
  165. </para>
  166. <para>
  167. If <computeroutput>T</computeroutput> is an <conceptname>ObjectTransform</conceptname> of the form
  168. <computeroutput>Object(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput> or
  169. <computeroutput>Object(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
  170. then let <computeroutput>O</computeroutput> be the return type
  171. <computeroutput>Object</computeroutput>. Otherwise, let <computeroutput>O</computeroutput>
  172. be <computeroutput>T</computeroutput>. The <computeroutput>result_type</computeroutput> typedef is
  173. then computed as follows:
  174. </para>
  175. <para>
  176. <itemizedlist>
  177. <listitem>
  178. <para>
  179. If <computeroutput><classname>proto::is_transform</classname>&lt;O&gt;::value</computeroutput> is
  180. <computeroutput>true</computeroutput>, then let the result type be
  181. <computeroutput>
  182. boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>_</classname>, O&gt;(Expr, State, Data)&gt;::type
  183. </computeroutput>.
  184. Note that a substitution took place.
  185. </para>
  186. </listitem>
  187. <listitem>
  188. If <computeroutput>O</computeroutput> is a template like
  189. <computeroutput><classname>proto::noinvoke</classname>&lt;S&lt;X<subscript>0</subscript>,…X<subscript>n</subscript>&gt; &gt;</computeroutput>,
  190. then the result type is calculated as follows:
  191. <itemizedlist>
  192. <listitem>
  193. <para>
  194. For each <computeroutput>i</computeroutput> in
  195. <computeroutput>[0,n]</computeroutput>, let <computeroutput>
  196. X<subscript>i</subscript>'
  197. </computeroutput> be
  198. <computeroutput>
  199. boost::result_of&lt;<classname>proto::make</classname>&lt;X<subscript>i</subscript>&gt;(Expr, State, Data)&gt;::type
  200. </computeroutput>
  201. (which evaluates this procedure recursively). Note that a substitution took place. (In this case,
  202. Proto merely assumes that a substitution took place for the sake of compile-time efficiency. There
  203. would be no reason to use <computeroutput><classname>proto::noinvoke&lt;&gt;</classname></computeroutput>
  204. otherwise.)
  205. </para>
  206. </listitem>
  207. <listitem>
  208. <para>
  209. The result type is
  210. <computeroutput>
  211. S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
  212. </computeroutput>.
  213. </para>
  214. </listitem>
  215. </itemizedlist>
  216. </listitem>
  217. <listitem>
  218. If <computeroutput>O</computeroutput> is a template like
  219. <computeroutput>S&lt;X<subscript>0</subscript>,…X<subscript>n</subscript>&gt;</computeroutput>,
  220. then the result type is calculated as follows:
  221. <itemizedlist>
  222. <listitem>
  223. <para>
  224. For each <computeroutput>i</computeroutput> in
  225. <computeroutput>[0,n]</computeroutput>, let <computeroutput>
  226. X<subscript>i</subscript>'
  227. </computeroutput> be
  228. <computeroutput>
  229. boost::result_of&lt;<classname>proto::make</classname>&lt;X<subscript>i</subscript>&gt;(Expr, State, Data)&gt;::type
  230. </computeroutput>
  231. (which evaluates this procedure recursively). Note whether any substitutions took place during
  232. this operation.
  233. </para>
  234. </listitem>
  235. <listitem>
  236. <para>
  237. If any substitutions took place in the above step and
  238. <computeroutput>
  239. S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
  240. </computeroutput> has a nested
  241. <computeroutput>type</computeroutput> typedef, the result type is
  242. <computeroutput>
  243. S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;::type
  244. </computeroutput>.
  245. </para>
  246. </listitem>
  247. <listitem>
  248. <para>
  249. Otherwise, the result type is
  250. <computeroutput>
  251. S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
  252. </computeroutput>.
  253. </para>
  254. </listitem>
  255. </itemizedlist>
  256. </listitem>
  257. <listitem>
  258. Otherwise, the result type is <computeroutput>O</computeroutput>, and note that no
  259. substitution took place.
  260. </listitem>
  261. </itemizedlist>
  262. </para>
  263. <para>
  264. Note that <computeroutput><classname alt="proto::when">proto::when&lt;&gt;</classname></computeroutput> is implemented
  265. in terms of <computeroutput><classname alt="proto::call">proto::call&lt;&gt;</classname></computeroutput>
  266. and <computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>, so the
  267. above procedure is evaluated recursively.
  268. </para>
  269. </description>
  270. </typedef>
  271. <method-group name="public member functions">
  272. <method name="operator()" cv="const">
  273. <type>result_type</type>
  274. <parameter name="expr">
  275. <paramtype>typename impl::expr_param</paramtype>
  276. </parameter>
  277. <parameter name="state">
  278. <paramtype>typename impl::state_param</paramtype>
  279. </parameter>
  280. <parameter name="data">
  281. <paramtype>typename impl::data_param</paramtype>
  282. </parameter>
  283. <description>
  284. <para>
  285. <computeroutput>
  286. <classname>proto::make</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::operator()
  287. </computeroutput>
  288. behaves as follows:
  289. </para>
  290. <para>
  291. <itemizedlist>
  292. <listitem>
  293. <para>
  294. If <computeroutput>T</computeroutput> is of the form
  295. <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then:
  296. </para>
  297. <itemizedlist>
  298. <listitem>
  299. <para>
  300. If <computeroutput>
  301. <classname>proto::is_aggregate</classname>&lt;result_type&gt;::value
  302. </computeroutput> is <computeroutput>true</computeroutput>, then construct
  303. and return an object <computeroutput>that</computeroutput> as follows:
  304. <programlisting>result_type that = {
  305. <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>0</subscript>&gt;()(expr, state, data),
  306. <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>n</subscript>&gt;()(expr, state, data)
  307. };</programlisting>
  308. </para>
  309. </listitem>
  310. <listitem>
  311. <para>
  312. Otherwise, construct
  313. and return an object <computeroutput>that</computeroutput> as follows:
  314. <programlisting>result_type that(
  315. <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>0</subscript>&gt;()(expr, state, data),
  316. <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>n</subscript>&gt;()(expr, state, data)
  317. );</programlisting>
  318. </para>
  319. </listitem>
  320. </itemizedlist>
  321. </listitem>
  322. <listitem>
  323. <para>
  324. If <computeroutput>T</computeroutput> is of the form
  325. <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
  326. then let <computeroutput>T&apos;</computeroutput> be <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
  327. where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
  328. as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>. Then, return:
  329. <programlisting>proto::make&lt;T&apos;&gt;()(expr, state, data)</programlisting>
  330. </para>
  331. </listitem>
  332. <listitem>
  333. <para>
  334. Otherwise, construct and return an object <computeroutput>that</computeroutput>
  335. as follows: <programlisting>result_type that = result_type();</programlisting>
  336. </para>
  337. </listitem>
  338. </itemizedlist>
  339. </para>
  340. </description>
  341. </method>
  342. </method-group>
  343. </struct>
  344. </struct>
  345. </namespace>
  346. </namespace>
  347. </header>