Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / vmd / doc / html / variadic_macro_data / vmd_modifiers.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Macros with modifiers</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="../index.html" title="Chapter&#160;1.&#160;The Variadic Macro Data Library 1.9">
9 <link rel="prev" href="vmd_generic/vmd_assert.html" title="Testing for equality and inequality">
10 <link rel="next" href="vmd_modifiers/vmd_modifiers_filter.html" title="Filtering modifiers">
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_generic/vmd_assert.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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_modifiers/vmd_modifiers_filter.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24 </div>
25 <div class="section">
26 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
27 <a name="variadic_macro_data.vmd_modifiers"></a><a class="link" href="vmd_modifiers.html" title="Macros with modifiers">Macros with modifiers</a>
28 </h2></div></div></div>
29 <div class="toc"><dl class="toc">
30 <dt><span class="section"><a href="vmd_modifiers.html#variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type">Return
31       type modifiers</a></span></dt>
32 <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_filter.html">Filtering
33       modifiers</a></span></dt>
34 <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_identifier.html">Identifier
35       modifiers</a></span></dt>
36 <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_splitting.html">Splitting
37       modifiers</a></span></dt>
38 <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_index.html">Index
39       modifiers</a></span></dt>
40 <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_single.html">Modifiers
41       and the single-element sequence</a></span></dt>
42 </dl></div>
43 <p>
44       The basic functionality for VMD macros parsing data types has been given using
45       the required parameters of those macros. This basic functionality may be perfectly
46       adequate for macro programmers to use VMD effectively in their programming
47       efforts.
48     </p>
49 <p>
50       A number of those macros take optional parameters, called in general "modifiers",
51       which enhance or change the functionality of those macros in various ways.
52       All modifiers are VMD identifiers.
53     </p>
54 <p>
55       In all situations modifiers are optional parameters which are parsed by VMD
56       to provide enhanced functionality for some of its macros. They are never required
57       as part of the basic functionality of a macro.
58     </p>
59 <p>
60       When modifiers are used as optional arguments to a macro they can be input
61       after the required parameters in any order and VMD will still handle the optional
62       parameters correctly.
63     </p>
64 <p>
65       There are two general types of modifiers, 'specific modifiers' and 'user-defined
66       modifiers'. Specific modifers start with BOOST_VMD_ and are both registered
67       and pre-detected identifiers known to VMD. The specific modifiers change the
68       expansion of particular macros in various ways which will be subsequently explained.
69       User-defined modifiers are user-defined identifiers which the end-user of specific
70       macros must register and pre-detect for himself. They also change the expansion
71       of particular macros in various ways which will be subsequently explained.
72     </p>
73 <p>
74       For any particular macro if a specific modifier is not appropriate it is just
75       ignored. This means that VMD never generates a preprocessing error or gives
76       an incorrect result just because a specific modifier does not apply for a particular
77       macro. Any modifier which is not recognized as a specific modifier is treated
78       as a user-defined modifier. In cases where a user-defined modifier is not appropriate
79       it is also just ignored.
80     </p>
81 <p>
82       The situations where modifiers can be used to enhance the basic functionality
83       of VMD macros can be divided by particular types of specific modifiers. Each
84       particular type of a specific modifier has a name given to it, functionality,
85       and set of identifiers associated with that particular type. Each particular
86       type of a specific modifier may be used as optional parameters in one or more
87       designated macros depending on the specific modifier type.
88     </p>
89 <p>
90       When more than one mutually exclusive specific modifier from a particular type
91       of modifier is specified as an optional parameter the last specified takes
92       effect. This allows the programmer to override a specific modifier by adding
93       the overridden identifier as an optional argument to the end of the macro's
94       invocation.
95     </p>
96 <p>
97       Header files for specific modifiers are automatically included when the header
98       files for macros taking those specific modifiers are included.
99     </p>
100 <p>
101       Header files for user-defined modifiers, which register and pre-detect those
102       user-defined modifiers, must be included as needed by the programmer using
103       those modifiers.
104     </p>
105 <p>
106       The following topics will explain each particular type of modifier and where
107       it may be used.
108     </p>
109 <div class="section">
110 <div class="titlepage"><div><div><h3 class="title">
111 <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type"></a><a class="link" href="vmd_modifiers.html#variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type" title="Return type modifiers">Return
112       type modifiers</a>
113 </h3></div></div></div>
114 <p>
115         A number of macros are capable of returning the type of data as a v-type
116         rather than, or along with, the data itself. The most obvious of these is
117         BOOST_VMD_GET_TYPE which generically returns the type of the input.
118       </p>
119 <p>
120         Return type modifiers turn on, turn off, or change the type of the data returned
121         in some way.
122       </p>
123 <p>
124         These modifiers are:
125       </p>
126 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
127 <li class="listitem">
128             BOOST_VMD_RETURN_NO_TYPE, do not return the type of data.
129           </li>
130 <li class="listitem">
131             BOOST_VMD_RETURN_TYPE, return the type of data parsing any tuple-like
132             syntactical construct as its most specific type. This means that any
133             tuple-like construct is parsed first as a possible list, next as a possible
134             array if it is not a list, and finally as a tuple if it is not a list
135             or an array.
136           </li>
137 <li class="listitem">
138             BOOST_VMD_RETURN_TYPE_LIST, parse any tuple-like syntactical construct
139             first as a possible list and only then as a tuple if it is not a list.
140           </li>
141 <li class="listitem">
142             BOOST_VMD_RETURN_TYPE_ARRAY, parse any tuple-like syntactical construct
143             first as a possible array and only then as a tuple if it is not an array.
144           </li>
145 <li class="listitem">
146             BOOST_VMD_RETURN_TYPE_TUPLE, parse any tuple-like syntactical construct
147             only as a tuple.
148           </li>
149 </ul></div>
150 <p>
151         When VMD parses input generically it must determine the type of each data
152         element of the input. For nearly all of the VMD data types this is never
153         a problem. For the array or list data types this can be a problem, as explained
154         when discussing parsing arrays and lists respectively using the specific
155         macros BOOST_VMD_IS_ARRAY and BOOST_VMD_IS_LIST. The problem is that a valid
156         tuple can be an invalid list or an invalid array, whose parsing as the more
157         specific type will lead to UB. Because of this when VMD parses input generically,
158         and only the data of an element is needed to continue parsing correctly,
159         it parses all tuple-like data as a tuple and never as a list or an array.
160       </p>
161 <p>
162         When VMD parses input generically, and the type of the data is required in
163         some way as part of the return of a macro, VMD by default parses for the
164         most specific type of each data element in order to return the most accurate
165         type. In this situation by default the BOOST_VMD_RETURN_TYPE modifier is
166         internally in effect without having to be specified.
167       </p>
168 <p>
169         If more than one of the return type modifiers are specified as optional parameters
170         the last one specified is in effect.
171       </p>
172 <h5>
173 <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.h0"></a>
174         <span class="phrase"><a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.usage_with_boost_vmd_get_type"></a></span><a class="link" href="vmd_modifiers.html#variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.usage_with_boost_vmd_get_type">Usage
175         with BOOST_VMD_GET_TYPE</a>
176       </h5>
177 <p>
178         The only macro in which VMD without the use of modifiers is being asked to
179         return the type of data is BOOST_VMD_GET_TYPE. For this macro the BOOST_VMD_RETURN_TYPE
180         modifier is internally in effect so if no return type modifiers are input
181         as optional parameters BOOST_VMD_GET_TYPE looks for the most specific type.
182       </p>
183 <p>
184         For the BOOST_VMD_GET_TYPE macro the optional return type modifier BOOST_VMD_RETURN_NO_TYPE,
185         if specified, is always ignored since the purpose of BOOST_VMD_GET_TYPE is
186         solely to return the v-type.
187       </p>
188 <p>
189         Let's look at how this works with BOOST_VMD_GET_TYPE by specifying VMD sequences
190         that have tuples which may or may not be valid lists or arrays.
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">get_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
193
194 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_IS_ARRAY</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>
195 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_IS_LIST</span> <span class="special">(</span><span class="identifier">anydata</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)</span>
196 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_IS_LIST_OR_ARRAY</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>
197 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_BUT_INVALID_ARRAY</span> <span class="special">(&amp;</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>
198 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_BUT_INVALID_LIST</span> <span class="special">(</span><span class="identifier">anydata</span><span class="special">,^</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)</span>
199 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_EMPTY</span>
200 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI</span> <span class="identifier">TUPLE_BUT_INVALID_ARRAY</span> <span class="identifier">TUPLE_BUT_INVALID_LIST</span>
201
202 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_ARRAY</span><span class="special">,</span> <span class="identifier">the</span> <span class="identifier">most</span> <span class="identifier">specific</span> <span class="identifier">type</span>
203 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
204 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_ARRAY</span>
205 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
206
207 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_LIST</span><span class="special">,</span> <span class="identifier">the</span> <span class="identifier">most</span> <span class="identifier">specific</span> <span class="identifier">type</span>
208 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_LIST</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
209 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_LIST</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
210 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_LIST</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_LIST</span>
211
212 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_LIST_OR_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_LIST</span><span class="special">,</span> <span class="identifier">the</span> <span class="identifier">most</span> <span class="identifier">specific</span> <span class="identifier">type</span>
213 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_LIST_OR_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
214 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_LIST_OR_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_ARRAY</span>
215 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_IS_LIST_OR_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_LIST</span>
216
217 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_BUT_INVALID_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="identifier">give</span> <span class="identifier">UB</span>
218 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_BUT_INVALID_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
219 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_BUT_INVALID_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="identifier">give</span> <span class="identifier">UB</span>
220 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_BUT_INVALID_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
221
222 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_BUT_INVALID_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="identifier">give</span> <span class="identifier">UB</span>
223 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_BUT_INVALID_LIST</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
224 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_BUT_INVALID_LIST</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_TUPLE</span>
225 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">TUPLE_BUT_INVALID_LIST</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="identifier">give</span> <span class="identifier">UB</span>
226
227 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">SEQUENCE_EMPTY</span><span class="special">)</span>
228    <span class="identifier">will</span> <span class="identifier">always</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_EMPTY</span> <span class="identifier">even</span> <span class="keyword">if</span> <span class="identifier">we</span> <span class="identifier">add</span> <span class="identifier">any</span> <span class="keyword">return</span> <span class="identifier">type</span> <span class="identifier">modifiers</span>
229 <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI</span><span class="special">)</span>
230    <span class="identifier">will</span> <span class="identifier">always</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_SEQUENCE</span> <span class="identifier">even</span> <span class="keyword">if</span> <span class="identifier">we</span> <span class="identifier">add</span> <span class="identifier">any</span> <span class="keyword">return</span> <span class="identifier">type</span> <span class="identifier">modifiers</span>
231 </pre>
232 <h5>
233 <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.h1"></a>
234         <span class="phrase"><a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.usage_with_sequence_converting_m"></a></span><a class="link" href="vmd_modifiers.html#variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.usage_with_sequence_converting_m">Usage
235         with sequence converting macros</a>
236       </h5>
237 <p>
238         The sequence converting macros converts a sequence to a composite Boost PP
239         data type or to variadic data, where each element's data in the sequence
240         becomes an element in the destination composite type. The macros are:
241       </p>
242 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
243 <li class="listitem">
244             BOOST_VMD_TO_ARRAY, converts the sequence to an array
245           </li>
246 <li class="listitem">
247             BOOST_VMD_TO_LIST, converts the sequence to a list
248           </li>
249 <li class="listitem">
250             BOOST_VMD_TO_SEQ, converts the sequence to a seq
251           </li>
252 <li class="listitem">
253             BOOST_VMD_TO_TUPLE, converts the sequence to a tuple
254           </li>
255 <li class="listitem">
256             BOOST_VMD_ENUM, converts the sequence to variadic data
257           </li>
258 </ul></div>
259 <p>
260         When it does the conversion, using just the required parameter of the sequence
261         itself, it converts only the data value of each sequence element to the elements
262         of a composite Boost PP data type or variadic data. Because it needs only
263         the data value of each sequence element it determines the type of each sequence
264         element as the most general type that it can be. This means that all tuple-like
265         data are parsed as tuples rather than as possible lists or arrays.
266       </p>
267 <p>
268         Using a return type modifier we can convert from a VMD sequence to a Boost
269         PP composite data type or variadic data and retain the type of data of each
270         element in the sequence as part of the conversion. When doing this each of
271         the converted elements of the composite data type becomes a two-element tuple
272         where the first element is the type of the data and the second element is
273         the data itself.
274       </p>
275 <p>
276         For the sequence conversion macros the default return type modifier internally
277         set is BOOST_VMD_RETURN_NO_TYPE, which means that the type is not retained.
278         By specifying another optional return type modifier we tell the conversion
279         to preserve the type in the conversion output.
280       </p>
281 <p>
282         If the sequence is empty, since there are no sequence elements, any return
283         type modifier we use accomplishes nothing but is fine to use.
284       </p>
285 <p>
286         First we show how sequence conversion macros work with the BOOST_VMD_RETURN_TYPE
287         modifier, which always parses for the most specific type.
288       </p>
289 <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="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
290 <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">to_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
291 <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">to_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
292 <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">to_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
293 <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">to_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
294
295 <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_ANID</span> <span class="special">(</span><span class="identifier">ANID</span><span class="special">)</span>
296 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_EMPTY_1</span>
297 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE</span> <span class="number">35</span>
298 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_ID</span> <span class="identifier">ANID</span>
299 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_ARRAY</span> <span class="special">(</span><span class="number">3</span><span class="special">,(</span><span class="number">0</span><span class="special">,</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">))</span>
300 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_LIST</span> <span class="special">(</span><span class="identifier">data</span><span class="special">,(</span><span class="identifier">more_data</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">))</span>
301 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_1</span> <span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="number">1</span><span class="special">)</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>
302 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_2</span> <span class="identifier">BOOST_VMD_TYPE_SEQ</span> <span class="special">(</span><span class="number">2</span><span class="special">,(</span><span class="number">5</span><span class="special">,</span><span class="number">6</span><span class="special">))</span>
303
304 <span class="identifier">BOOST_VMD_TO_ARRAY</span><span class="special">(</span><span class="identifier">SEQUENCE_EMPTY_1</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">an</span> <span class="identifier">empty</span> <span class="identifier">array</span> <span class="char">'(0,())'</span>
305 <span class="identifier">BOOST_VMD_TO_ARRAY</span><span class="special">(</span><span class="identifier">SEQUENCE_EMPTY_1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">an</span> <span class="identifier">empty</span> <span class="identifier">array</span> <span class="char">'(0,())'</span>
306
307 <span class="identifier">BOOST_VMD_TO_LIST</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">one</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">list</span> <span class="char">'(35,BOOST_PP_NIL)'</span>
308 <span class="identifier">BOOST_VMD_TO_LIST</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
309    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">one</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">list</span> <span class="char">'((BOOST_VMD_TYPE_NUMBER,35),BOOST_PP_NIL)'</span>
310
311 <span class="identifier">BOOST_VMD_TO_SEQ</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE_ID</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">one</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">seq</span> <span class="char">'(ANID)'</span>
312 <span class="identifier">BOOST_VMD_TO_SEQ</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE_ID</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
313    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">one</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">seq</span> <span class="char">'((BOOST_VMD_TYPE_IDENTIFIER,ANID))'</span>
314
315 <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">single</span> <span class="identifier">element</span> <span class="identifier">tuple</span> <span class="char">'((3,(0,1,2)))'</span>
316 <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
317    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">single</span> <span class="identifier">element</span> <span class="identifier">tuple</span> <span class="char">'((BOOST_VMD_TYPE_ARRAY,(3,(0,1,2))))'</span>
318
319 <span class="identifier">BOOST_VMD_ENUM</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">single</span><span class="special">-</span><span class="identifier">element</span> <span class="char">'(data,(more_data,BOOST_PP_NIL))'</span>
320 <span class="identifier">BOOST_VMD_ENUM</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE_LIST</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
321    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">single</span> <span class="identifier">element</span> <span class="char">'(BOOST_VMD_TYPE_LIST,(data,(more_data,BOOST_PP_NIL)))'</span>
322
323 <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_1</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">multi</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">tuple</span> <span class="char">'((0,1),(2)(3)(4))'</span>
324 <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
325    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">multi</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">tuple</span> <span class="char">'((BOOST_VMD_TYPE_TUPLE,(0,1)),(BOOST_VMD_TYPE_SEQ,(2)(3)(4)))'</span>
326
327 <span class="identifier">BOOST_VMD_ENUM</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_2</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">multi</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">variadic</span> <span class="identifier">data</span> <span class="char">'BOOST_VMD_TYPE_SEQ,(2,(5,6))'</span>
328 <span class="identifier">BOOST_VMD_ENUM</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
329    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">multi</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">variadic</span> <span class="identifier">data</span> <span class="char">'(BOOST_VMD_TYPE_TYPE,BOOST_VMD_TYPE_SEQ),(BOOST_VMD_TYPE_ARRAY,(2,(5,6)))'</span>
330 </pre>
331 <p>
332         Lets look at how we might use other return type modifiers when doing conversions
333         to avoid UB if we want the type as part of the conversion but the type might
334         be a valid tuple while being an invalid list or array.
335       </p>
336 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TUPLE_IS_VALID_ARRAY</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>
337 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_IS_VALID_LIST</span> <span class="special">(</span><span class="identifier">anydata</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)</span>
338 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_BUT_INVALID_ARRAY_2</span> <span class="special">(&amp;</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>
339 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_BUT_INVALID_LIST_2</span> <span class="special">(</span><span class="identifier">anydata</span><span class="special">,^</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)</span>
340
341 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_T1</span> <span class="identifier">TUPLE_IS_VALID_ARRAY</span> <span class="identifier">TUPLE_IS_VALID_LIST</span>
342 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_T2</span> <span class="identifier">TUPLE_BUT_INVALID_ARRAY_2</span> <span class="identifier">TUPLE_IS_VALID_LIST</span>
343 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_T3</span> <span class="identifier">TUPLE_IS_VALID_ARRAY</span> <span class="identifier">TUPLE_BUT_INVALID_LIST_2</span>
344 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_T4</span> <span class="identifier">TUPLE_BUT_INVALID_ARRAY_2</span> <span class="identifier">TUPLE_BUT_INVALID_LIST_2</span>
345 </pre>
346 <p>
347         We present a number of uses of various sequence conversions with each of
348         our four different sequences, and show their results.
349       </p>
350 <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">to_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
351
352 <span class="identifier">BOOST_VMD_TO_SEQ</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
353    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">seq</span> <span class="char">'((BOOST_VMD_TYPE_ARRAY,(2,(3,4)))) ((BOOST_VMD_TYPE_LIST,(anydata,BOOST_PP_NIL)))'</span>
354 <span class="identifier">BOOST_VMD_TO_SEQ</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span>
355    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">seq</span> <span class="char">'((BOOST_VMD_TYPE_ARRAY,(2,(3,4)))) ((BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL)))'</span>
356 <span class="identifier">BOOST_VMD_TO_SEQ</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span>
357    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">seq</span> <span class="char">'((BOOST_VMD_TYPE_TUPLE,(2,(3,4)))) ((BOOST_VMD_TYPE_LIST,(anydata,BOOST_PP_NIL)))'</span>
358 <span class="identifier">BOOST_VMD_TO_SEQ</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span>
359    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">seq</span> <span class="char">'((BOOST_VMD_TYPE_TUPLE,(2,(3,4)))) ((BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL)))'</span>
360 </pre>
361 <p>
362         The SEQUENCE_MULTI_T1 is a valid array followed by a valid list. All return
363         type modifiers produce their results without any UBs.
364       </p>
365 <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">to_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
366
367 <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
368    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">array</span> <span class="identifier">as</span> <span class="identifier">an</span> <span class="identifier">array</span>
369 <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span>
370    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">array</span> <span class="identifier">as</span> <span class="identifier">an</span> <span class="identifier">array</span>
371 <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span>
372    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">tuple</span> <span class="char">'((BOOST_VMD_TYPE_TUPLE,(&amp;2,(3,4))),(BOOST_VMD_TYPE_LIST,(anydata,BOOST_PP_NIL)))'</span>
373 <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span>
374    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">tuple</span> <span class="char">'((BOOST_VMD_TYPE_TUPLE,(&amp;2,(3,4))),(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL)))'</span>
375 </pre>
376 <p>
377         The SEQUENCE_MULTI_T2 is an invalid array, but valid tuple, followed by a
378         valid list.
379       </p>
380 <p>
381         In sequence conversion we will get UB whenever we use a return type modifier
382         that parses the data type of the invalid array as an array. But if we use
383         the return type modifiers BOOST_VMD_RETURN_TYPE_LIST or BOOST_VMD_RETURN_TYPE_TUPLE
384         we are never parsing the invalid array as an array but as a tuple instead
385         and therefore we successfully return the type of the invalid array as a BOOST_VMD_TYPE_TUPLE.
386       </p>
387 <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">to_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
388
389 <span class="identifier">BOOST_VMD_TO_ARRAY</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
390    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">list</span> <span class="identifier">as</span> <span class="identifier">a</span> <span class="identifier">list</span>
391 <span class="identifier">BOOST_VMD_TO_ARRAY</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span>
392    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">list</span> <span class="identifier">as</span> <span class="identifier">a</span> <span class="identifier">list</span>
393 <span class="identifier">BOOST_VMD_TO_ARRAY</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span>
394    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">array</span> <span class="char">'(2,((BOOST_VMD_TYPE_ARRAY,(2,(3,4))),(BOOST_VMD_TYPE_TUPLE,(anydata,^BOOST_PP_NIL))))'</span>
395 <span class="identifier">BOOST_VMD_TO_ARRAY</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span>
396    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">array</span> <span class="char">'(2,((BOOST_VMD_TYPE_TUPLE,(2,(3,4))),(BOOST_VMD_TYPE_TUPLE,(anydata,^BOOST_PP_NIL))))'</span>
397 </pre>
398 <p>
399         The SEQUENCE_MULTI_T3 is a valid array followed by an invalid list, but a
400         valid tuple.
401       </p>
402 <p>
403         In sequence conversion we will get UBs whenever we use a return type modifier
404         that parses the data type of the invalid list as a list. But if we use the
405         return type modifiers BOOST_VMD_RETURN_TYPE_ARRAY or BOOST_VMD_RETURN_TYPE_TUPLE
406         we are never parsing the invalid list as a list but as a tuple instead and
407         therefore we successfully return the type of the invalid list as a BOOST_VMD_TYPE_TUPLE.
408       </p>
409 <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">to_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
410
411 <span class="identifier">BOOST_VMD_TO_LIST</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
412    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">array</span> <span class="keyword">or</span> <span class="identifier">invalid</span> <span class="identifier">list</span>
413 <span class="identifier">BOOST_VMD_TO_LIST</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span>
414    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">array</span>
415 <span class="identifier">BOOST_VMD_TO_LIST</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span>
416    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">list</span>
417 <span class="identifier">BOOST_VMD_TO_LIST</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_T4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span>
418    <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">the</span> <span class="identifier">list</span> <span class="char">'((BOOST_VMD_TYPE_TUPLE,(&amp;2,(3,4))),((BOOST_VMD_TYPE_TUPLE,(anydata,^BOOST_PP_NIL)),BOOST_PP_NIL))'</span>
419 </pre>
420 <p>
421         The SEQUENCE_MULTI_T4 is an invalid array, but valid tuple, followed by an
422         invalid list, but valid tuple.
423       </p>
424 <p>
425         In sequence conversion we will get UBs whenever we use a return type modifier
426         that parses the sequence other than looking for only valid tuples. So here
427         we must use the return type modifier BOOST_VMD_RETURN_TYPE_TUPLE for a sequence
428         conversion without generating UBs.
429       </p>
430 <h5>
431 <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.h2"></a>
432         <span class="phrase"><a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.usage_with_boost_vmd_elem"></a></span><a class="link" href="vmd_modifiers.html#variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.usage_with_boost_vmd_elem">Usage
433         with BOOST_VMD_ELEM</a>
434       </h5>
435 <p>
436         The default functionality of BOOST_VMD_ELEM when the required parameters
437         are used is to return the particular element's data. When BOOST_VMD_ELEM
438         does this it parses all elements of the sequence by determining the most
439         general type of data for each element. The parsing algorithm stops when it
440         reaches the element number whose data is returned. This means that all tuple-like
441         data are parsed as tuples rather than as possible lists or arrays.
442       </p>
443 <p>
444         Using return type modifiers as optional parameters we can tell BOOST_VMD_ELEM
445         to return the type of the element found, as well as its data, in the form
446         of a two element tuple. The first element of the tuple is the type of the
447         data and the second element of the tuple is the data itself.
448       </p>
449 <p>
450         When we use a return type modifier with BOOST_VMD_ELEM, which tells us to
451         return the type of the data along with the data, the particular modifier
452         only tells BOOST_VMD_ELEM how to parse the type of data for the element found.
453         BOOST_VMD_ELEM will continue to parse elements in the sequence preceding
454         the element found by determining the most general type of the data since
455         this is the safest way of parsing the data itself.
456       </p>
457 <p>
458         Using the return type modifier BOOST_VMD_RETURN_TYPE with BOOST_VMD_ELEM
459         is perfectly safe as long as the particular element found is not an invalid
460         list or array, but a valid tuple. It is when the element found may be an
461         invalid list or invalid array that we must use other return type modifiers
462         in order to parse the type of the element correctly.
463       </p>
464 <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">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
465
466 <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_ANID_E</span> <span class="special">(</span><span class="identifier">ANID_E</span><span class="special">)</span>
467 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_E</span> <span class="number">35</span>
468 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_E2</span> <span class="identifier">ANID_E</span>
469 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_E</span> <span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="number">1</span><span class="special">)</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>
470 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_E_2</span> <span class="identifier">BOOST_VMD_TYPE_SEQ</span> <span class="special">(</span><span class="number">2</span><span class="special">,(</span><span class="number">5</span><span class="special">,</span><span class="number">6</span><span class="special">))</span>
471
472 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_SINGLE_E</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'35'</span>
473 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_SINGLE_E</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_NUMBER,35)'</span>
474
475 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_SINGLE_E2</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'ANID_E'</span>
476 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_SINGLE_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_IDENTIFIER,ANID_E)'</span>
477
478 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(2)(3)(4)'</span>
479 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_SEQ,(2)(3)(4))'</span>
480
481 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E_2</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'BOOST_VMD_TYPE_SEQ'</span>
482 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E_2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TYPE,BOOST_VMD_TYPE_SEQ)'</span>
483 </pre>
484 <p>
485         When we use the other return type modifiers with BOOST_VMD_ELEM we do so
486         because the element we want may be an invalid list or an invalid array but
487         a valid tuple and yet we still want its type returned as part of the result.
488       </p>
489 <p>
490         Let's look at how this works with BOOST_VMD_ELEM by specifying VMD sequences
491         that have tuples which are in the form of arrays or lists which cannot be
492         parsed as such by VMD without generating UBs.
493       </p>
494 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TUPLE_IS_VALID_ARRAY_E</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>
495 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_IS_VALID_LIST_E</span> <span class="special">(</span><span class="identifier">anydata</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)</span>
496 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_BUT_INVALID_ARRAY_E</span> <span class="special">(&amp;</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>
497 <span class="preprocessor">#define</span> <span class="identifier">TUPLE_BUT_INVALID_LIST_E</span> <span class="special">(</span><span class="identifier">anydata</span><span class="special">,^</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)</span>
498
499 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_E1</span> <span class="identifier">TUPLE_IS_VALID_ARRAY_E</span> <span class="identifier">TUPLE_IS_VALID_LIST_E</span>
500 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_E2</span> <span class="identifier">TUPLE_BUT_INVALID_ARRAY_E</span> <span class="identifier">TUPLE_IS_VALID_LIST_E</span>
501 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_E3</span> <span class="identifier">TUPLE_IS_VALID_ARRAY_E</span> <span class="identifier">TUPLE_BUT_INVALID_LIST_E</span>
502 <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_E4</span> <span class="identifier">TUPLE_BUT_INVALID_ARRAY_E</span> <span class="identifier">TUPLE_BUT_INVALID_LIST_E</span>
503 </pre>
504 <p>
505         We present a number of uses of BOOST_VMD_ELEM with each of our four different
506         sequences, and show their results.
507       </p>
508 <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">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
509
510 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_ARRAY,(2,(3,4)))'</span>
511 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_ARRAY,(2,(3,4)))'</span>
512 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(2,(3,4)))'</span>
513 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(2,(3,4)))'</span>
514 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_LIST,(anydata,BOOST_PP_NIL))'</span>
515 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL))'</span>
516 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_LIST,(anydata,BOOST_PP_NIL))'</span>
517 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E1</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL))'</span>
518 </pre>
519 <p>
520         The SEQUENCE_MULTI_E1 is a valid array followed by a valid list. All return
521         type modifiers produce their results without any UBs.
522       </p>
523 <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">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
524
525 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
526    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">array</span> <span class="identifier">as</span> <span class="identifier">an</span> <span class="identifier">array</span>
527 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span>
528    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">array</span> <span class="identifier">as</span> <span class="identifier">an</span> <span class="identifier">array</span>
529 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(&amp;2,(3,4)))'</span>
530 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(&amp;2,(3,4)))'</span>
531 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_LIST,(anydata,BOOST_PP_NIL))'</span>
532 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL))'</span>
533 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_LIST,(anydata,BOOST_PP_NIL))'</span>
534 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E2</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL))'</span>
535 </pre>
536 <p>
537         The SEQUENCE_MULTI_E2 is an invalid array, but valid tuple, followed by a
538         valid list.
539       </p>
540 <p>
541         When we access element 0 of our sequence, and use a return type modifier
542         that parses its data type as an array we will get UB. But if we use the return
543         type modifiers BOOST_VMD_RETURN_TYPE_LIST or BOOST_VMD_RETURN_TYPE_TUPLE
544         we are never parsing the invalid array as an array but as a tuple instead
545         and therefore we successfully return the type of the invalid array as a BOOST_VMD_TYPE_TUPLE.
546       </p>
547 <p>
548         When we access element 1 of our sequence, which is both a valid list and
549         a valid tuple, we will never get UB. We will get the return type of the element
550         based on which return type modifier we use.
551       </p>
552 <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">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
553
554 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_ARRAY,(2,(3,4)))'</span>
555 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_ARRAY,(2,(3,4)))'</span>
556 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(2,(3,4)))'</span>
557 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(2,(3,4)))'</span>
558 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
559    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">list</span> <span class="identifier">as</span> <span class="identifier">a</span> <span class="identifier">list</span>
560 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL))'</span>
561 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span>
562    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">list</span> <span class="identifier">as</span> <span class="identifier">a</span> <span class="identifier">list</span>
563 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E3</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL))'</span>
564 </pre>
565 <p>
566         The SEQUENCE_MULTI_E3 is a valid array followed by an invalid list, but valid
567         tuple.
568       </p>
569 <p>
570         When we access element 0 of our sequence, which is both a valid array and
571         a valid tuple, we will never get UB. We will get the return type of the element
572         based on which return type modifier we use.
573       </p>
574 <p>
575         When we access element 1 of our sequence, and use a return type modifier
576         that parses its data type as a list we will get UB. But if we use the return
577         type modifiers BOOST_VMD_RETURN_TYPE_ARRAY or BOOST_VMD_RETURN_TYPE_TUPLE
578         we are never parsing the invalid list as a list but as a tuple instead and
579         therefore we successfully return the type of the invalid list as a BOOST_VMD_TYPE_TUPLE.
580       </p>
581 <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">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
582
583 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
584    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">array</span>
585 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span>
586    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">array</span>
587 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(2,(3,4)))'</span>
588 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(2,(3,4)))'</span>
589 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span>
590    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">list</span>
591 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_ARRAY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL))'</span>
592 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_LIST</span><span class="special">)</span>
593    <span class="identifier">will</span> <span class="identifier">produce</span> <span class="identifier">UB</span> <span class="identifier">when</span> <span class="identifier">attempting</span> <span class="identifier">to</span> <span class="identifier">parse</span> <span class="identifier">the</span> <span class="identifier">invalid</span> <span class="identifier">list</span>
594 <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">SEQUENCE_MULTI_E4</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE_TUPLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(anydata,BOOST_PP_NIL))'</span>
595 </pre>
596 <p>
597         The SEQUENCE_MULTI_E4 is an invalid array, but valid tuple, followed by an
598         invalid list, but valid tuple.
599       </p>
600 <p>
601         When we access element 0 of our sequence, which is an invalid array but a
602         valid tuple, we must use a return type modifier which does not parse element
603         0 as an array, else we will get UB. This means we must use the return type
604         modifiers BOOST_VMD_RETURN_TYPE_LIST or BOOST_VMD_RETURN_TYPE_TUPLE so we
605         are never parsing the invalid array as an array but as a tuple instead and
606         therefore we successfully return the type of the invalid array as a BOOST_VMD_TYPE_TUPLE.
607       </p>
608 <p>
609         When we access element 1 of our sequence, which is an invalid list but a
610         valid tuple, we must use a return type modifier which does not parse element
611         1 as a list, else we will get UB. This means we must use the return type
612         modifiers BOOST_VMD_RETURN_TYPE_ARRAY or BOOST_VMD_RETURN_TYPE_TUPLE so we
613         are never parsing the invalid list as a list but as a tuple instead and therefore
614         we successfully return the type of the invalid list as a BOOST_VMD_TYPE_TUPLE.
615       </p>
616 <h5>
617 <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.h3"></a>
618         <span class="phrase"><a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.usage_with_other_modifiers_of_bo"></a></span><a class="link" href="vmd_modifiers.html#variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.usage_with_other_modifiers_of_bo">Usage
619         with other modifiers of BOOST_VMD_ELEM</a>
620       </h5>
621 <p>
622         We have not yet discussed the rest of the modifiers which may be used with
623         BOOST_VMD_ELEM, but return type modifiers are completely independent of any
624         of them. This means they can be combined with other modifiers and whenever
625         the element of the sequence is returned the return type modifiers determine
626         of what the value of that element consists; whether it be just the element
627         data or the element as a type/data tuple with the type parsed according to
628         our return type modifier. When we subsequently discuss the use of other modifiers
629         with BOOST_VMD_ELEM and refer to the element being returned, we are referring
630         to that element as it is determined by the return type modifiers, which by
631         default only returns the element's data.
632       </p>
633 </div>
634 </div>
635 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
636 <td align="left"></td>
637 <td align="right"><div class="copyright-footer">Copyright &#169; 2010-2017 Tropic Software
638       East Inc</div></td>
639 </tr></table>
640 <hr>
641 <div class="spirit-nav">
642 <a accesskey="p" href="vmd_generic/vmd_assert.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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_modifiers/vmd_modifiers_filter.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
643 </div>
644 </body>
645 </html>