1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 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 1. The Variadic Macro Data Library 1.9"> 8<link rel="up" href="../index.html" title="Chapter 1. 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"><</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">></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">(&</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"><</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">></span> 290<span class="preprocessor">#include</span> <span class="special"><</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">></span> 291<span class="preprocessor">#include</span> <span class="special"><</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">></span> 292<span class="preprocessor">#include</span> <span class="special"><</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">></span> 293<span class="preprocessor">#include</span> <span class="special"><</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">></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">(&</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"><</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">></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"><</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">></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,(&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,(&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"><</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">></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"><</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">></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,(&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"><</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">></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">(&</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"><</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">></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"><</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">></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,(&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,(&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"><</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">></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"><</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">></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 © 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> 646