123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645 |
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
- <title>Macros with modifiers</title>
- <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
- <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
- <link rel="home" href="../index.html" title="Chapter 1. The Variadic Macro Data Library 1.9">
- <link rel="up" href="../index.html" title="Chapter 1. The Variadic Macro Data Library 1.9">
- <link rel="prev" href="vmd_generic/vmd_assert.html" title="Testing for equality and inequality">
- <link rel="next" href="vmd_modifiers/vmd_modifiers_filter.html" title="Filtering modifiers">
- </head>
- <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
- <table cellpadding="2" width="100%"><tr>
- <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
- <td align="center"><a href="../../../../../index.html">Home</a></td>
- <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
- <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
- <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
- <td align="center"><a href="../../../../../more/index.htm">More</a></td>
- </tr></table>
- <hr>
- <div class="spirit-nav">
- <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>
- </div>
- <div class="section">
- <div class="titlepage"><div><div><h2 class="title" style="clear: both">
- <a name="variadic_macro_data.vmd_modifiers"></a><a class="link" href="vmd_modifiers.html" title="Macros with modifiers">Macros with modifiers</a>
- </h2></div></div></div>
- <div class="toc"><dl class="toc">
- <dt><span class="section"><a href="vmd_modifiers.html#variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type">Return
- type modifiers</a></span></dt>
- <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_filter.html">Filtering
- modifiers</a></span></dt>
- <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_identifier.html">Identifier
- modifiers</a></span></dt>
- <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_splitting.html">Splitting
- modifiers</a></span></dt>
- <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_index.html">Index
- modifiers</a></span></dt>
- <dt><span class="section"><a href="vmd_modifiers/vmd_modifiers_single.html">Modifiers
- and the single-element sequence</a></span></dt>
- </dl></div>
- <p>
- The basic functionality for VMD macros parsing data types has been given using
- the required parameters of those macros. This basic functionality may be perfectly
- adequate for macro programmers to use VMD effectively in their programming
- efforts.
- </p>
- <p>
- A number of those macros take optional parameters, called in general "modifiers",
- which enhance or change the functionality of those macros in various ways.
- All modifiers are VMD identifiers.
- </p>
- <p>
- In all situations modifiers are optional parameters which are parsed by VMD
- to provide enhanced functionality for some of its macros. They are never required
- as part of the basic functionality of a macro.
- </p>
- <p>
- When modifiers are used as optional arguments to a macro they can be input
- after the required parameters in any order and VMD will still handle the optional
- parameters correctly.
- </p>
- <p>
- There are two general types of modifiers, 'specific modifiers' and 'user-defined
- modifiers'. Specific modifers start with BOOST_VMD_ and are both registered
- and pre-detected identifiers known to VMD. The specific modifiers change the
- expansion of particular macros in various ways which will be subsequently explained.
- User-defined modifiers are user-defined identifiers which the end-user of specific
- macros must register and pre-detect for himself. They also change the expansion
- of particular macros in various ways which will be subsequently explained.
- </p>
- <p>
- For any particular macro if a specific modifier is not appropriate it is just
- ignored. This means that VMD never generates a preprocessing error or gives
- an incorrect result just because a specific modifier does not apply for a particular
- macro. Any modifier which is not recognized as a specific modifier is treated
- as a user-defined modifier. In cases where a user-defined modifier is not appropriate
- it is also just ignored.
- </p>
- <p>
- The situations where modifiers can be used to enhance the basic functionality
- of VMD macros can be divided by particular types of specific modifiers. Each
- particular type of a specific modifier has a name given to it, functionality,
- and set of identifiers associated with that particular type. Each particular
- type of a specific modifier may be used as optional parameters in one or more
- designated macros depending on the specific modifier type.
- </p>
- <p>
- When more than one mutually exclusive specific modifier from a particular type
- of modifier is specified as an optional parameter the last specified takes
- effect. This allows the programmer to override a specific modifier by adding
- the overridden identifier as an optional argument to the end of the macro's
- invocation.
- </p>
- <p>
- Header files for specific modifiers are automatically included when the header
- files for macros taking those specific modifiers are included.
- </p>
- <p>
- Header files for user-defined modifiers, which register and pre-detect those
- user-defined modifiers, must be included as needed by the programmer using
- those modifiers.
- </p>
- <p>
- The following topics will explain each particular type of modifier and where
- it may be used.
- </p>
- <div class="section">
- <div class="titlepage"><div><div><h3 class="title">
- <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
- type modifiers</a>
- </h3></div></div></div>
- <p>
- A number of macros are capable of returning the type of data as a v-type
- rather than, or along with, the data itself. The most obvious of these is
- BOOST_VMD_GET_TYPE which generically returns the type of the input.
- </p>
- <p>
- Return type modifiers turn on, turn off, or change the type of the data returned
- in some way.
- </p>
- <p>
- These modifiers are:
- </p>
- <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
- <li class="listitem">
- BOOST_VMD_RETURN_NO_TYPE, do not return the type of data.
- </li>
- <li class="listitem">
- BOOST_VMD_RETURN_TYPE, return the type of data parsing any tuple-like
- syntactical construct as its most specific type. This means that any
- tuple-like construct is parsed first as a possible list, next as a possible
- array if it is not a list, and finally as a tuple if it is not a list
- or an array.
- </li>
- <li class="listitem">
- BOOST_VMD_RETURN_TYPE_LIST, parse any tuple-like syntactical construct
- first as a possible list and only then as a tuple if it is not a list.
- </li>
- <li class="listitem">
- BOOST_VMD_RETURN_TYPE_ARRAY, parse any tuple-like syntactical construct
- first as a possible array and only then as a tuple if it is not an array.
- </li>
- <li class="listitem">
- BOOST_VMD_RETURN_TYPE_TUPLE, parse any tuple-like syntactical construct
- only as a tuple.
- </li>
- </ul></div>
- <p>
- When VMD parses input generically it must determine the type of each data
- element of the input. For nearly all of the VMD data types this is never
- a problem. For the array or list data types this can be a problem, as explained
- when discussing parsing arrays and lists respectively using the specific
- macros BOOST_VMD_IS_ARRAY and BOOST_VMD_IS_LIST. The problem is that a valid
- tuple can be an invalid list or an invalid array, whose parsing as the more
- specific type will lead to UB. Because of this when VMD parses input generically,
- and only the data of an element is needed to continue parsing correctly,
- it parses all tuple-like data as a tuple and never as a list or an array.
- </p>
- <p>
- When VMD parses input generically, and the type of the data is required in
- some way as part of the return of a macro, VMD by default parses for the
- most specific type of each data element in order to return the most accurate
- type. In this situation by default the BOOST_VMD_RETURN_TYPE modifier is
- internally in effect without having to be specified.
- </p>
- <p>
- If more than one of the return type modifiers are specified as optional parameters
- the last one specified is in effect.
- </p>
- <h5>
- <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.h0"></a>
- <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
- with BOOST_VMD_GET_TYPE</a>
- </h5>
- <p>
- The only macro in which VMD without the use of modifiers is being asked to
- return the type of data is BOOST_VMD_GET_TYPE. For this macro the BOOST_VMD_RETURN_TYPE
- modifier is internally in effect so if no return type modifiers are input
- as optional parameters BOOST_VMD_GET_TYPE looks for the most specific type.
- </p>
- <p>
- For the BOOST_VMD_GET_TYPE macro the optional return type modifier BOOST_VMD_RETURN_NO_TYPE,
- if specified, is always ignored since the purpose of BOOST_VMD_GET_TYPE is
- solely to return the v-type.
- </p>
- <p>
- Let's look at how this works with BOOST_VMD_GET_TYPE by specifying VMD sequences
- that have tuples which may or may not be valid lists or arrays.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_EMPTY</span>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">SEQUENCE_EMPTY</span><span class="special">)</span>
- <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>
- <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI</span><span class="special">)</span>
- <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>
- </pre>
- <h5>
- <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.h1"></a>
- <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
- with sequence converting macros</a>
- </h5>
- <p>
- The sequence converting macros converts a sequence to a composite Boost PP
- data type or to variadic data, where each element's data in the sequence
- becomes an element in the destination composite type. The macros are:
- </p>
- <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
- <li class="listitem">
- BOOST_VMD_TO_ARRAY, converts the sequence to an array
- </li>
- <li class="listitem">
- BOOST_VMD_TO_LIST, converts the sequence to a list
- </li>
- <li class="listitem">
- BOOST_VMD_TO_SEQ, converts the sequence to a seq
- </li>
- <li class="listitem">
- BOOST_VMD_TO_TUPLE, converts the sequence to a tuple
- </li>
- <li class="listitem">
- BOOST_VMD_ENUM, converts the sequence to variadic data
- </li>
- </ul></div>
- <p>
- When it does the conversion, using just the required parameter of the sequence
- itself, it converts only the data value of each sequence element to the elements
- of a composite Boost PP data type or variadic data. Because it needs only
- the data value of each sequence element it determines the type of each sequence
- element as the most general type that it can be. This means that all tuple-like
- data are parsed as tuples rather than as possible lists or arrays.
- </p>
- <p>
- Using a return type modifier we can convert from a VMD sequence to a Boost
- PP composite data type or variadic data and retain the type of data of each
- element in the sequence as part of the conversion. When doing this each of
- the converted elements of the composite data type becomes a two-element tuple
- where the first element is the type of the data and the second element is
- the data itself.
- </p>
- <p>
- For the sequence conversion macros the default return type modifier internally
- set is BOOST_VMD_RETURN_NO_TYPE, which means that the type is not retained.
- By specifying another optional return type modifier we tell the conversion
- to preserve the type in the conversion output.
- </p>
- <p>
- If the sequence is empty, since there are no sequence elements, any return
- type modifier we use accomplishes nothing but is fine to use.
- </p>
- <p>
- First we show how sequence conversion macros work with the BOOST_VMD_RETURN_TYPE
- modifier, which always parses for the most specific type.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_EMPTY_1</span>
- <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE</span> <span class="number">35</span>
- <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_ID</span> <span class="identifier">ANID</span>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- Lets look at how we might use other return type modifiers when doing conversions
- to avoid UB if we want the type as part of the conversion but the type might
- be a valid tuple while being an invalid list or array.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- We present a number of uses of various sequence conversions with each of
- our four different sequences, and show their results.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- The SEQUENCE_MULTI_T1 is a valid array followed by a valid list. All return
- type modifiers produce their results without any UBs.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- The SEQUENCE_MULTI_T2 is an invalid array, but valid tuple, followed by a
- valid list.
- </p>
- <p>
- In sequence conversion we will get UB whenever we use a return type modifier
- that parses the data type of the invalid array as an array. But if we use
- the return type modifiers BOOST_VMD_RETURN_TYPE_LIST or BOOST_VMD_RETURN_TYPE_TUPLE
- we are never parsing the invalid array as an array but as a tuple instead
- and therefore we successfully return the type of the invalid array as a BOOST_VMD_TYPE_TUPLE.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- The SEQUENCE_MULTI_T3 is a valid array followed by an invalid list, but a
- valid tuple.
- </p>
- <p>
- In sequence conversion we will get UBs whenever we use a return type modifier
- that parses the data type of the invalid list as a list. But if we use the
- return type modifiers BOOST_VMD_RETURN_TYPE_ARRAY or BOOST_VMD_RETURN_TYPE_TUPLE
- we are never parsing the invalid list as a list but as a tuple instead and
- therefore we successfully return the type of the invalid list as a BOOST_VMD_TYPE_TUPLE.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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">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>
- <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">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>
- <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>
- </pre>
- <p>
- The SEQUENCE_MULTI_T4 is an invalid array, but valid tuple, followed by an
- invalid list, but valid tuple.
- </p>
- <p>
- In sequence conversion we will get UBs whenever we use a return type modifier
- that parses the sequence other than looking for only valid tuples. So here
- we must use the return type modifier BOOST_VMD_RETURN_TYPE_TUPLE for a sequence
- conversion without generating UBs.
- </p>
- <h5>
- <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.h2"></a>
- <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
- with BOOST_VMD_ELEM</a>
- </h5>
- <p>
- The default functionality of BOOST_VMD_ELEM when the required parameters
- are used is to return the particular element's data. When BOOST_VMD_ELEM
- does this it parses all elements of the sequence by determining the most
- general type of data for each element. The parsing algorithm stops when it
- reaches the element number whose data is returned. This means that all tuple-like
- data are parsed as tuples rather than as possible lists or arrays.
- </p>
- <p>
- Using return type modifiers as optional parameters we can tell BOOST_VMD_ELEM
- to return the type of the element found, as well as its data, in the form
- of a two element tuple. The first element of the tuple is the type of the
- data and the second element of the tuple is the data itself.
- </p>
- <p>
- When we use a return type modifier with BOOST_VMD_ELEM, which tells us to
- return the type of the data along with the data, the particular modifier
- only tells BOOST_VMD_ELEM how to parse the type of data for the element found.
- BOOST_VMD_ELEM will continue to parse elements in the sequence preceding
- the element found by determining the most general type of the data since
- this is the safest way of parsing the data itself.
- </p>
- <p>
- Using the return type modifier BOOST_VMD_RETURN_TYPE with BOOST_VMD_ELEM
- is perfectly safe as long as the particular element found is not an invalid
- list or array, but a valid tuple. It is when the element found may be an
- invalid list or invalid array that we must use other return type modifiers
- in order to parse the type of the element correctly.
- </p>
- <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>
- <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>
- <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_E</span> <span class="number">35</span>
- <span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_E2</span> <span class="identifier">ANID_E</span>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- When we use the other return type modifiers with BOOST_VMD_ELEM we do so
- because the element we want may be an invalid list or an invalid array but
- a valid tuple and yet we still want its type returned as part of the result.
- </p>
- <p>
- Let's look at how this works with BOOST_VMD_ELEM by specifying VMD sequences
- that have tuples which are in the form of arrays or lists which cannot be
- parsed as such by VMD without generating UBs.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- We present a number of uses of BOOST_VMD_ELEM with each of our four different
- sequences, and show their results.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- The SEQUENCE_MULTI_E1 is a valid array followed by a valid list. All return
- type modifiers produce their results without any UBs.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- The SEQUENCE_MULTI_E2 is an invalid array, but valid tuple, followed by a
- valid list.
- </p>
- <p>
- When we access element 0 of our sequence, and use a return type modifier
- that parses its data type as an array we will get UB. But if we use the return
- type modifiers BOOST_VMD_RETURN_TYPE_LIST or BOOST_VMD_RETURN_TYPE_TUPLE
- we are never parsing the invalid array as an array but as a tuple instead
- and therefore we successfully return the type of the invalid array as a BOOST_VMD_TYPE_TUPLE.
- </p>
- <p>
- When we access element 1 of our sequence, which is both a valid list and
- a valid tuple, we will never get UB. We will get the return type of the element
- based on which return type modifier we use.
- </p>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- The SEQUENCE_MULTI_E3 is a valid array followed by an invalid list, but valid
- tuple.
- </p>
- <p>
- When we access element 0 of our sequence, which is both a valid array and
- a valid tuple, we will never get UB. We will get the return type of the element
- based on which return type modifier we use.
- </p>
- <p>
- When we access element 1 of our sequence, and use a return type modifier
- that parses its data type as a list we will get UB. But if we use the return
- type modifiers BOOST_VMD_RETURN_TYPE_ARRAY or BOOST_VMD_RETURN_TYPE_TUPLE
- we are never parsing the invalid list as a list but as a tuple instead and
- therefore we successfully return the type of the invalid list as a BOOST_VMD_TYPE_TUPLE.
- </p>
- <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>
- <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>
- <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">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>
- <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">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>
- <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>
- <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>
- <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">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>
- <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>
- <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">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>
- </pre>
- <p>
- The SEQUENCE_MULTI_E4 is an invalid array, but valid tuple, followed by an
- invalid list, but valid tuple.
- </p>
- <p>
- When we access element 0 of our sequence, which is an invalid array but a
- valid tuple, we must use a return type modifier which does not parse element
- 0 as an array, else we will get UB. This means we must use the return type
- modifiers BOOST_VMD_RETURN_TYPE_LIST or BOOST_VMD_RETURN_TYPE_TUPLE so we
- are never parsing the invalid array as an array but as a tuple instead and
- therefore we successfully return the type of the invalid array as a BOOST_VMD_TYPE_TUPLE.
- </p>
- <p>
- When we access element 1 of our sequence, which is an invalid list but a
- valid tuple, we must use a return type modifier which does not parse element
- 1 as a list, else we will get UB. This means we must use the return type
- modifiers BOOST_VMD_RETURN_TYPE_ARRAY or BOOST_VMD_RETURN_TYPE_TUPLE so we
- are never parsing the invalid list as a list but as a tuple instead and therefore
- we successfully return the type of the invalid list as a BOOST_VMD_TYPE_TUPLE.
- </p>
- <h5>
- <a name="variadic_macro_data.vmd_modifiers.vmd_modifiers_return_type.h3"></a>
- <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
- with other modifiers of BOOST_VMD_ELEM</a>
- </h5>
- <p>
- We have not yet discussed the rest of the modifiers which may be used with
- BOOST_VMD_ELEM, but return type modifiers are completely independent of any
- of them. This means they can be combined with other modifiers and whenever
- the element of the sequence is returned the return type modifiers determine
- of what the value of that element consists; whether it be just the element
- data or the element as a type/data tuple with the type parsed according to
- our return type modifier. When we subsequently discuss the use of other modifiers
- with BOOST_VMD_ELEM and refer to the element being returned, we are referring
- to that element as it is determined by the return type modifiers, which by
- default only returns the element's data.
- </p>
- </div>
- </div>
- <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
- <td align="left"></td>
- <td align="right"><div class="copyright-footer">Copyright © 2010-2017 Tropic Software
- East Inc</div></td>
- </tr></table>
- <hr>
- <div class="spirit-nav">
- <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>
- </div>
- </body>
- </html>
|