vmd_pp_data_types.html 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>VMD and Boost PP data types</title>
  5. <link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;The Variadic Macro Data Library 1.9">
  8. <link rel="up" href="../vmd_specific.html" title="Specific macros for working with data types">
  9. <link rel="prev" href="vmd_type.html" title="Types">
  10. <link rel="next" href="vmd_identifying.html" title="Identifying data types">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="vmd_type.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../vmd_specific.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_identifying.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h3 class="title">
  27. <a name="variadic_macro_data.vmd_specific.vmd_pp_data_types"></a><a class="link" href="vmd_pp_data_types.html" title="VMD and Boost PP data types">VMD
  28. and Boost PP data types</a>
  29. </h3></div></div></div>
  30. <p>
  31. VMD is able to determine whether or not preprocessing input is a given Boost
  32. PP data type. The VMD macros to do this are:
  33. </p>
  34. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  35. <li class="listitem">
  36. BOOST_VMD_IS_ARRAY for an array
  37. </li>
  38. <li class="listitem">
  39. BOOST_VMD_IS_LIST for a list
  40. </li>
  41. <li class="listitem">
  42. BOOST_VMD_IS_SEQ for a seq
  43. </li>
  44. <li class="listitem">
  45. BOOST_VMD_IS_TUPLE for a tuple
  46. </li>
  47. </ul></div>
  48. <p>
  49. Each of these macros take a single parameter as input and return 1 if the
  50. parameter is the appropriate data type and 0 if it is not.
  51. </p>
  52. <h5>
  53. <a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.h0"></a>
  54. <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.syntax_anomalies"></a></span><a class="link" href="vmd_pp_data_types.html#variadic_macro_data.vmd_specific.vmd_pp_data_types.syntax_anomalies">Syntax
  55. anomalies</a>
  56. </h5>
  57. <p>
  58. Both an array and a non-empty list are also a tuple. So if one has:
  59. </p>
  60. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ANARRAY</span> <span class="special">(</span><span class="number">3</span><span class="special">,(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">))</span>
  61. <span class="preprocessor">#define</span> <span class="identifier">ALIST</span> <span class="special">(</span><span class="identifier">a</span><span class="special">,(</span><span class="identifier">b</span><span class="special">,(</span><span class="identifier">c</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)))</span>
  62. <span class="preprocessor">#define</span> <span class="identifier">ATUPLE</span> <span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">)</span>
  63. <span class="preprocessor">#define</span> <span class="identifier">ASEQ</span> <span class="special">(</span><span class="identifier">a</span><span class="special">)(</span><span class="identifier">b</span><span class="special">)(</span><span class="identifier">c</span><span class="special">)</span>
  64. </pre>
  65. <p>
  66. then
  67. </p>
  68. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  69. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">ANARRAY</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  70. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">ALIST</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  71. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">ATUPLE</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  72. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">ASEQ</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">0</span>
  73. </pre>
  74. <p>
  75. A list whose first element is the number 2 and whose second element is not
  76. the end-of-list marker BOOST_PP_NIL is also an array. So if one has:
  77. </p>
  78. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ALIST</span> <span class="special">(</span><span class="number">2</span><span class="special">,(</span><span class="number">3</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">))</span>
  79. <span class="preprocessor">#define</span> <span class="identifier">ALIST2</span> <span class="special">(</span><span class="number">2</span><span class="special">,(</span><span class="number">3</span><span class="special">,(</span><span class="number">4</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)))</span>
  80. <span class="preprocessor">#define</span> <span class="identifier">ALIST3</span> <span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)</span>
  81. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  82. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  83. <span class="identifier">BOOST_VMD_IS_LIST</span><span class="special">(</span><span class="identifier">ALIST</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  84. <span class="identifier">BOOST_VMD_IS_LIST</span><span class="special">(</span><span class="identifier">ALIST2</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  85. <span class="identifier">BOOST_VMD_IS_LIST</span><span class="special">(</span><span class="identifier">ALIST3</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  86. <span class="identifier">BOOST_VMD_IS_ARRAY</span><span class="special">(</span><span class="identifier">ALIST</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  87. <span class="identifier">BOOST_VMD_IS_ARRAY</span><span class="special">(</span><span class="identifier">ALIST2</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  88. <span class="identifier">BOOST_VMD_IS_ARRAY</span><span class="special">(</span><span class="identifier">ALIST3</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">0</span>
  89. </pre>
  90. <p>
  91. A single element tuple is also a one element seq. So if one has:
  92. </p>
  93. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ASE_TUPLE</span> <span class="special">(</span><span class="identifier">a</span><span class="special">)</span>
  94. </pre>
  95. <p>
  96. then
  97. </p>
  98. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  99. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  100. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">ASE_TUPLE</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  101. <span class="identifier">BOOST_VMD_IS_SEQ</span><span class="special">(</span><span class="identifier">ASE_TUPLE</span><span class="special">)</span> <span class="identifier">returns</span> <span class="number">1</span>
  102. </pre>
  103. <h5>
  104. <a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.h1"></a>
  105. <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.problem_when_testing_an_array"></a></span><a class="link" href="vmd_pp_data_types.html#variadic_macro_data.vmd_specific.vmd_pp_data_types.problem_when_testing_an_array">Problem
  106. when testing an array</a>
  107. </h5>
  108. <p>
  109. The form of an array is a two element tuple, where the first element is a
  110. number and the second element is a tuple. The number specifies the size of
  111. the tuple. Since when using variadic macros it is never necessary to specify
  112. the size of a tuple, an array is largely obsolete. However VMD still supports
  113. it.
  114. </p>
  115. <p>
  116. The problem when testing for an array is that if the first element does not
  117. obey the constraint on testing for a number, you will get UB.
  118. </p>
  119. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  120. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  121. <span class="preprocessor">#define</span> <span class="identifier">A_TUPLE</span> <span class="special">(&amp;</span><span class="identifier">anything</span><span class="special">,(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">))</span>
  122. <span class="identifier">BOOST_VMD_IS_ARRAY</span><span class="special">(</span><span class="identifier">A_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="identifier">give</span> <span class="identifier">UB</span> <span class="identifier">due</span> <span class="identifier">to</span> <span class="identifier">the</span> <span class="identifier">constraint</span>
  123. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">A_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  124. </pre>
  125. <p>
  126. When VMD attempts to parse for an array, as it does when the BOOST_VMD_IS_ARRAY
  127. is used, if first looks to see if the syntax represents a tuple with two
  128. elements. Next it looks to see if the second element itself is a tuple. Finally
  129. if it is satisfied that the previous checks are valid it tests whether the
  130. first element is a number or not. It is in this final test, that the first
  131. element is a valid number, where the UB could occur as explained in the topic
  132. 'Numbers'.
  133. </p>
  134. <h5>
  135. <a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.h2"></a>
  136. <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.problem_when_testing_a_list"></a></span><a class="link" href="vmd_pp_data_types.html#variadic_macro_data.vmd_specific.vmd_pp_data_types.problem_when_testing_a_list">Problem
  137. when testing a list</a>
  138. </h5>
  139. <p>
  140. The form of a non-empty list is a two element tuple, where the first element
  141. is the head of the list and can be anything and the second element is itself
  142. a list or the end-of-list identifier BOOST_PP_NIL.
  143. </p>
  144. <p>
  145. The problem when testing for a list is that if the second element does not
  146. obey the constraint on testing for an identifier, since BOOST_PP_NIL is an
  147. identifier and is tested as such, you will get UB.
  148. </p>
  149. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  150. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  151. <span class="preprocessor">#define</span> <span class="identifier">A_TUPLE</span> <span class="special">(</span><span class="identifier">element</span><span class="special">,&amp;</span><span class="identifier">anything</span><span class="special">)</span>
  152. <span class="identifier">BOOST_VMD_IS_LIST</span><span class="special">(</span><span class="identifier">A_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="identifier">give</span> <span class="identifier">UB</span> <span class="identifier">due</span> <span class="identifier">to</span> <span class="identifier">the</span> <span class="identifier">constraint</span>
  153. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">A_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  154. </pre>
  155. <p>
  156. The form of an empty list is the identifier BOOST_PP_NIL. Therefore:
  157. </p>
  158. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  159. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  160. <span class="preprocessor">#define</span> <span class="identifier">A_BAD_EMPTY_LIST</span> <span class="special">&amp;</span><span class="identifier">BOOST_PP_NIL</span>
  161. <span class="identifier">BOOST_VMD_IS_LIST</span><span class="special">(</span><span class="identifier">A_BAD_EMPTY_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="identifier">give</span> <span class="identifier">UB</span> <span class="identifier">due</span> <span class="identifier">to</span> <span class="identifier">the</span> <span class="identifier">constraint</span>
  162. <span class="identifier">BOOST_VMD_IS_IDENTIFIER</span><span class="special">(</span><span class="identifier">A_BAD_EMPTY_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="identifier">give</span> <span class="identifier">UB</span> <span class="identifier">due</span> <span class="identifier">to</span> <span class="identifier">the</span> <span class="identifier">constraint</span>
  163. </pre>
  164. <p>
  165. When VMD attempts to parse for a list, as it does when the BOOST_VMD_IS_LIST
  166. is used, if first looks to see if the syntax represents a tuple with two
  167. elements. If it is not a tuple with two elements it will check for the end-of-list.
  168. If it is a tuple with two elements it looks to see if the second element
  169. is a list. In both these paths it must always eventually check for the end-of-list
  170. notation BOOST_PP_NIL, which is an identifier in VMD. It is in this final
  171. test, that the end-of-list notation exists as a VMD identifier, where the
  172. UB could occur as explained in the topic 'Identifiers'.
  173. </p>
  174. <h5>
  175. <a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.h3"></a>
  176. <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.distinguishing_a_seq_and_a_tuple"></a></span><a class="link" href="vmd_pp_data_types.html#variadic_macro_data.vmd_specific.vmd_pp_data_types.distinguishing_a_seq_and_a_tuple">Distinguishing
  177. a seq and a tuple</a>
  178. </h5>
  179. <p>
  180. As has previously been mentioned a single element tuple is also a one element
  181. seq.
  182. </p>
  183. <p>
  184. However, as will be discussed later in the documentation, when VMD has to
  185. determine the type of such data, it always returns it as a tuple ( BOOST_VMD_TYPE_TUPLE
  186. ).
  187. </p>
  188. <p>
  189. If our data consists of more than one consecutive tuple of a single element
  190. the data is a seq:
  191. </p>
  192. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  193. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  194. <span class="preprocessor">#define</span> <span class="identifier">ST_DATA</span> <span class="special">(</span><span class="identifier">somedata</span><span class="special">)(</span><span class="identifier">some_other_data</span><span class="special">)</span>
  195. <span class="identifier">BOOST_VMD_IS_SEQ</span><span class="special">(</span><span class="identifier">ST_DATA</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  196. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">ST_DATA</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span>
  197. </pre>
  198. <p>
  199. However if the data consists of a mixture we need to distinguish how VMD
  200. parses the data. The rule is that VMD always parses a single element tuple
  201. as a tuple unless it is followed by one or more single element tuples, in
  202. which case it is a seq.
  203. </p>
  204. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ST_DATA</span> <span class="special">(</span><span class="identifier">somedata</span><span class="special">)(</span><span class="identifier">element1</span><span class="special">,</span><span class="identifier">element2</span><span class="special">)</span>
  205. </pre>
  206. <p>
  207. VMD parses the above data as 2 consecutive tuples. The first tuple is the
  208. single element tuple '(somedata)' and the second tuple is the multi element
  209. tuple '(element1,element2)'.
  210. </p>
  211. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ST_DATA</span> <span class="special">(</span><span class="identifier">element1</span><span class="special">,</span><span class="identifier">element2</span><span class="special">)(</span><span class="identifier">somedata</span><span class="special">)</span>
  212. </pre>
  213. <p>
  214. VMD parses the above data as 2 consecutive tuples. The first tuple is the
  215. multi element tuple '(element1,element2)' and the second tuple is the single
  216. element tuple '(somedata)'.
  217. </p>
  218. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ST_DATA</span> <span class="special">(</span><span class="identifier">somedata</span><span class="special">)(</span><span class="identifier">some_other_data</span><span class="special">)(</span><span class="identifier">element1</span><span class="special">,</span><span class="identifier">element2</span><span class="special">)</span>
  219. </pre>
  220. <p>
  221. VMD parses the above data as a seq followed by a tuple. The seq is '(somedata)(some_other_data)'
  222. and the tuple is '(element1,element2)'.
  223. </p>
  224. <h5>
  225. <a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.h4"></a>
  226. <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.empty_boost_pp_data_types"></a></span><a class="link" href="vmd_pp_data_types.html#variadic_macro_data.vmd_specific.vmd_pp_data_types.empty_boost_pp_data_types">Empty
  227. Boost PP data types</a>
  228. </h5>
  229. <p>
  230. An array and a list can be empty.
  231. </p>
  232. <p>
  233. An empty array has the form '(0,())', and is a perfectly valid array.
  234. </p>
  235. <p>
  236. You can test for an empty array using the macro BOOST_VMD_IS_EMPTY_ARRAY.
  237. </p>
  238. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  239. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_empty_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  240. <span class="preprocessor">#define</span> <span class="identifier">AN_ARRAY</span> <span class="special">(</span><span class="number">1</span><span class="special">,(</span><span class="number">1</span><span class="special">))</span>
  241. <span class="preprocessor">#define</span> <span class="identifier">AN_EMPTY_ARRAY</span> <span class="special">(</span><span class="number">0</span><span class="special">,())</span>
  242. <span class="identifier">BOOST_VMD_IS_ARRAY</span><span class="special">(</span><span class="identifier">AN_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  243. <span class="identifier">BOOST_VMD_IS_ARRAY</span><span class="special">(</span><span class="identifier">AN_EMPTY_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  244. <span class="identifier">BOOST_VMD_IS_EMPTY_ARRAY</span><span class="special">(</span><span class="identifier">AN_EMPTY_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  245. <span class="identifier">BOOST_VMD_IS_EMPTY_ARRAY</span><span class="special">()</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span>
  246. <span class="identifier">BOOST_VMD_IS_EMPTY_ARRAY</span><span class="special">(</span><span class="identifier">AN_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span>
  247. </pre>
  248. <p>
  249. An empty list has the form 'BOOST_PP_NIL', and is a perfectly valid list.
  250. </p>
  251. <p>
  252. You can test for an empty list using the macro BOOST_VMD_IS_EMPTY_LIST.
  253. </p>
  254. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_empty_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  255. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  256. <span class="preprocessor">#define</span> <span class="identifier">A_LIST</span> <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)</span>
  257. <span class="preprocessor">#define</span> <span class="identifier">AN_EMPTY_LIST</span> <span class="identifier">BOOST_PP_NIL</span>
  258. <span class="identifier">BOOST_VMD_IS_LIST</span><span class="special">(</span><span class="identifier">A_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  259. <span class="identifier">BOOST_VMD_IS_LIST</span><span class="special">(</span><span class="identifier">AN_EMPTY_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  260. <span class="identifier">BOOST_VMD_IS_EMPTY_LIST</span><span class="special">(</span><span class="identifier">AN_EMPTY_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  261. <span class="identifier">BOOST_VMD_IS_EMPTY_LIST</span><span class="special">()</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span>
  262. <span class="identifier">BOOST_VMD_IS_EMPTY_LIST</span><span class="special">(</span><span class="identifier">A_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span>
  263. </pre>
  264. <p>
  265. Neither seqs or tuples can be empty when using Boost PP. Because of this
  266. if you convert from an empty array or list to a seq or tuple using Boost
  267. PP macros to do so you will get undefined behavior.
  268. </p>
  269. <p>
  270. The syntax '()', which is called an empty parenthesis, is neither a zero-element
  271. seq or a tuple consisting of no elements. Rather it is either a one-element
  272. seq whose content is emptiness or a single-element tuple whose content is
  273. emptiness.
  274. </p>
  275. <p>
  276. VMD supports the syntax of an empty parenthesis. You can test for it using
  277. the macro BOOST_VMD_IS_PARENS_EMPTY.
  278. </p>
  279. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_parens_empty</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  280. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  281. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  282. <span class="preprocessor">#define</span> <span class="identifier">EMPTY_PARENS</span> <span class="special">()</span>
  283. <span class="preprocessor">#define</span> <span class="identifier">TUPLE</span> <span class="special">(</span><span class="number">0</span><span class="special">)</span>
  284. <span class="preprocessor">#define</span> <span class="identifier">SEQ</span> <span class="special">(</span><span class="number">0</span><span class="special">)(</span><span class="number">1</span><span class="special">)</span>
  285. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">EMPTY_PARENS</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  286. <span class="identifier">BOOST_VMD_IS_SEQ</span><span class="special">(</span><span class="identifier">EMPTY_PARENS</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  287. <span class="identifier">BOOST_VMD_IS_PARENS_EMPTY</span><span class="special">(</span><span class="identifier">EMPTY_PARENS</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span>
  288. <span class="identifier">BOOST_VMD_IS_PARENS_EMPTY</span><span class="special">()</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span>
  289. <span class="identifier">BOOST_VMD_IS_PARENS_EMPTY</span><span class="special">(</span><span class="identifier">TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span>
  290. <span class="identifier">BOOST_VMD_IS_PARENS_EMPTY</span><span class="special">(</span><span class="identifier">SEQ</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span>
  291. </pre>
  292. <p>
  293. The VC++8 compiler ( Visual Studio 2005 ), which is the oldest VC++ version
  294. which VMD supports, has trouble working with the empty parenthesis syntax.
  295. Therefore if you have to use VC++8 avoid its use, otherwise you should be
  296. fine using it if you desire.
  297. </p>
  298. <h5>
  299. <a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.h5"></a>
  300. <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.using_a_tuple_instead_of_an_arra"></a></span><a class="link" href="vmd_pp_data_types.html#variadic_macro_data.vmd_specific.vmd_pp_data_types.using_a_tuple_instead_of_an_arra">Using
  301. a tuple instead of an array</a>
  302. </h5>
  303. <p>
  304. When using variadic macros, the fact that an array can be empty is its only
  305. advantage over a tuple. Otherwise using a tuple is always easier since the
  306. syntax is simpler; you never have to notate the tuple's size.
  307. </p>
  308. <p>
  309. Since VMD fully supports passing and returning emptiness you could use a
  310. tuple instead of an array in all situations and simply pass or return emptiness
  311. to represent an "empty" tuple, and as an equivalent to an empty
  312. array.
  313. </p>
  314. <p>
  315. This notion of using emptiness to represent an "empty" tuple can
  316. also be extended to using emptiness to represent an "empty" seq.
  317. However functionality in Boost PP will not recognize emptiness as an empty
  318. tuple or seq, nor can you work with emptiness to represent an empty tuple
  319. or empty seq using the Boost PP functionality for a tuple or a seq. For a
  320. solution to using emptiness to represent an "empty" tuple or an
  321. "empty" seq VMD has functionality which will be explained when
  322. we look at our last area of functionality in VMD, useful variadic macros
  323. not in Boost PP.
  324. </p>
  325. <h5>
  326. <a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.h6"></a>
  327. <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_pp_data_types.usage"></a></span><a class="link" href="vmd_pp_data_types.html#variadic_macro_data.vmd_specific.vmd_pp_data_types.usage">Usage</a>
  328. </h5>
  329. <p>
  330. You can use the general header file:
  331. </p>
  332. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  333. </pre>
  334. <p>
  335. or you can use individual header files for each of these macros. The individual
  336. header files are:
  337. </p>
  338. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// for the BOOST_VMD_IS_ARRAY macro</span>
  339. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// for the BOOST_VMD_IS_LIST macro</span>
  340. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// for the BOOST_VMD_IS_SEQ macro</span>
  341. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// for the BOOST_VMD_IS_TUPLE macro.</span>
  342. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_empty_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// for the BOOST_VMD_IS_EMPTY_ARRAY macro.</span>
  343. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_empty_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// for the BOOST_VMD_IS_EMPTY_LIST macro.</span>
  344. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_parens_empty</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// for the BOOST_VMD_IS_PARENS_EMPTY macro.</span>
  345. </pre>
  346. </div>
  347. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  348. <td align="left"></td>
  349. <td align="right"><div class="copyright-footer">Copyright &#169; 2010-2017 Tropic Software
  350. East Inc</div></td>
  351. </tr></table>
  352. <hr>
  353. <div class="spirit-nav">
  354. <a accesskey="p" href="vmd_type.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../vmd_specific.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_identifying.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
  355. </div>
  356. </body>
  357. </html>