1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Identifiers</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="../vmd_specific.html" title="Specific macros for working with data types"> 9<link rel="prev" href="vmd_constraints.html" title="Macro constraints"> 10<link rel="next" href="vmd_number.html" title="Numbers"> 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_constraints.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../vmd_specific.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_number.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<a name="variadic_macro_data.vmd_specific.vmd_identifier"></a><a class="link" href="vmd_identifier.html" title="Identifiers">Identifiers</a> 28</h3></div></div></div> 29<p> 30 An identifier in VMD is either of two lower-level preprocessor possibilities: 31 </p> 32<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 33<li class="listitem"> 34 a preprocessing token 'identifier', which is essentially a sequence of 35 alphanumeric characters and the underscore character with the first character 36 not being a numeric character. 37 </li> 38<li class="listitem"> 39 a preprocessing token 'pp-number' that is an integral literal token. 40 </li> 41</ul></div> 42<p> 43 Here are some examples: 44 </p> 45<pre class="programlisting"><span class="identifier">SOME_NAME</span> 46<span class="identifier">_SOME_NAME</span> 47<span class="identifier">SOME_123_NAME</span> 48<span class="identifier">some_123_name</span> 49<span class="identifier">sOMe_123_NAmE</span> 50<span class="number">2367</span> 51<span class="number">43e11</span> 52<span class="number">0</span> 53<span class="number">22</span> 54<span class="number">654792</span> 55<span class="number">0x1256</span> 56</pre> 57<h5> 58<a name="variadic_macro_data.vmd_specific.vmd_identifier.h0"></a> 59 <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_identifier.problem_testing_any_identifier"></a></span><a class="link" href="vmd_identifier.html#variadic_macro_data.vmd_specific.vmd_identifier.problem_testing_any_identifier">Problem 60 testing any identifier</a> 61 </h5> 62<p> 63 One of the difficulties with identifiers in preprocessor metaprogramming 64 is safely testing for a particular one. VMD has a means of doing this within 65 a particular constraint for the characters that serve as the input. 66 </p> 67<p> 68 The constraint is that the beginning input character, ignoring any whitespace, 69 passed as the input to test must be either: 70 </p> 71<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 72<li class="listitem"> 73 an identifier character, ie. an alphanumeric or an underscore 74 </li> 75<li class="listitem"> 76 the left parenthesis of a tuple 77 </li> 78</ul></div> 79<p> 80 and if the first character is not the left parenthesis of a tuple the remaining 81 characters must be alphanumeric or an underscore until a space character 82 or end of input occurs. 83 </p> 84<p> 85 If this is not the case the behavior is undefined, and most likely a preprocessing 86 error will occur. 87 </p> 88<p> 89 Given the input: 90 </p> 91<pre class="programlisting"><span class="char">'s_anything'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span> 92<span class="char">'S_anything'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span> 93<span class="char">'s_anYthiNg'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span> 94<span class="char">'_anything'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span> 95<span class="char">'_Anything'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span> 96<span class="char">'_anytHIng'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span> 97<span class="char">'24'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span> 98<span class="char">'245e2'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span> 99<span class="char">'(anything)'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span><span class="special">,</span> <span class="identifier">tuple</span> 100<span class="char">'(anything) anything'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span><span class="special">,</span> <span class="identifier">tuple</span> <span class="keyword">and</span> <span class="identifier">further</span> <span class="identifier">input</span> 101<span class="char">'anything anything'</span> <span class="special">:</span> <span class="identifier">can</span> <span class="identifier">be</span> <span class="identifier">tested</span><span class="special">,</span> <span class="identifier">identifier</span> <span class="identifier">followed</span> <span class="identifier">by</span> <span class="identifier">space</span> <span class="identifier">character</span> 102 103<span class="char">'%_anything'</span> <span class="special">:</span> <span class="identifier">undefined</span> <span class="identifier">behavior</span> <span class="keyword">and</span> <span class="identifier">most</span> <span class="identifier">likely</span> <span class="identifier">a</span> <span class="identifier">preprocessing</span> <span class="identifier">error</span> <span class="identifier">due</span> <span class="identifier">to</span> <span class="identifier">the</span> <span class="identifier">constraint</span> 104<span class="char">'(_anything'</span> <span class="special">:</span> <span class="identifier">undefined</span> <span class="identifier">behavior</span> <span class="keyword">and</span> <span class="identifier">most</span> <span class="identifier">likely</span> <span class="identifier">a</span> <span class="identifier">preprocessing</span> <span class="identifier">error</span> <span class="identifier">due</span> <span class="identifier">to</span> <span class="identifier">the</span> <span class="identifier">constraint</span><span class="special">,</span> <span class="identifier">since</span> <span class="identifier">a</span> <span class="identifier">single</span> <span class="char">'('</span> <span class="identifier">does</span> <span class="keyword">not</span> <span class="identifier">form</span> <span class="identifier">a</span> <span class="identifier">tuple</span> 105<span class="char">'44.3'</span> <span class="special">:</span> <span class="identifier">undefined</span> <span class="identifier">behavior</span> <span class="keyword">and</span> <span class="identifier">most</span> <span class="identifier">likely</span> <span class="identifier">a</span> <span class="identifier">preprocessing</span> <span class="identifier">error</span> <span class="identifier">due</span> <span class="identifier">to</span> <span class="identifier">the</span> <span class="identifier">constraint</span> <span class="identifier">since</span> <span class="char">'.'</span> <span class="identifier">is</span> <span class="keyword">not</span> <span class="identifier">alphanumeric</span> 106</pre> 107<h5> 108<a name="variadic_macro_data.vmd_specific.vmd_identifier.h1"></a> 109 <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_identifier.identifying_an_identifier"></a></span><a class="link" href="vmd_identifier.html#variadic_macro_data.vmd_specific.vmd_identifier.identifying_an_identifier">Identifying 110 an identifier</a> 111 </h5> 112<p> 113 In VMD the only way an identifier can be identified in preprocessor input 114 is by a process called registration. In order to 'register' an identifier 115 to be recognized by VMD the end-user must create, for every identifier to 116 be recognized, an object-like macro whose form is: 117 </p> 118<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_identifier</span> <span class="special">(</span><span class="identifier">identifier</span><span class="special">)</span> 119</pre> 120<p> 121 where 'identifier' is a particular identifier we wish to identify. This is 122 called in VMD a registration macro. 123 </p> 124<p> 125 It is recommended that such registration macros be created in a header file 126 which can be included before the end-user uses the identifier macros of VMD. 127 </p> 128<p> 129 If a particular registration macro occurs more than once it is not a preprocessing 130 error, so duplicating a registration macro will not lead to any problems 131 since each registration macro of the same name will have the exact same object-like 132 macro expansion. 133 </p> 134<p> 135 Within a given translation unit it could potentially happen that registration 136 macros have been included by header files which a particular end-user of 137 VMD has not created. This should also not lead to particular problems since 138 registration is a process for adding identifiers for any particular translation 139 unit. As we shall see VMD has macros for not only finding any identifier 140 in preprocessor input but for also finding any particular identifier in preprocessor 141 input. 142 </p> 143<h5> 144<a name="variadic_macro_data.vmd_specific.vmd_identifier.h2"></a> 145 <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_identifier.testing_for_an_identifier_macro"></a></span><a class="link" href="vmd_identifier.html#variadic_macro_data.vmd_specific.vmd_identifier.testing_for_an_identifier_macro">Testing 146 for an identifier macro</a> 147 </h5> 148<p> 149 The specific macro used to test for an identifier in VMD is called BOOST_VMD_IS_IDENTIFIER. 150 The macro takes a required parameter of variadic data which is the input 151 against which to test. 152 </p> 153<p> 154 When we invoke BOOST_VMD_IS_IDENTIFIER it returns 1 if the input represents 155 any registered identifier, otherwise it returns 0. 156 </p> 157<p> 158 As an example: 159 </p> 160<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">is_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 161 162<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_yellow</span> <span class="special">(</span><span class="identifier">yellow</span><span class="special">)</span> 163<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_green</span> <span class="special">(</span><span class="identifier">green</span><span class="special">)</span> 164<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_blue</span> <span class="special">(</span><span class="identifier">blue</span><span class="special">)</span> 165 166<span class="identifier">BOOST_VMD_IS_IDENTIFIER</span><span class="special">(</span><span class="identifier">some_input</span><span class="special">)</span> <span class="comment">// returns 1 if 'some_input' is 'yellow','green', or 'blue'</span> 167<span class="identifier">BOOST_VMD_IS_IDENTIFIER</span><span class="special">(</span><span class="identifier">some_input</span><span class="special">)</span> <span class="comment">// returns 0 if 'some_input' is 'purple'</span> 168</pre> 169<p> 170 Only registered identifiers can be found in VMD as identifiers. 171 </p> 172<h5> 173<a name="variadic_macro_data.vmd_specific.vmd_identifier.h3"></a> 174 <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_identifier.detecting_a_particular_identifie"></a></span><a class="link" href="vmd_identifier.html#variadic_macro_data.vmd_specific.vmd_identifier.detecting_a_particular_identifie">Detecting 175 a particular identifier</a> 176 </h5> 177<p> 178 Although registering an identifier allows VMD to recognize the string of 179 characters as a VMD identifier, the ability to detect a particular identifier 180 needs the end-user to define another macro: 181 </p> 182<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_identifier_identifier</span> 183</pre> 184<p> 185 where 'identifier' is a particular identifier we wish to detect. This object-like 186 macro expands to no output. 187 </p> 188<p> 189 Like the registration macro multiple detection macros of the same identifier 190 in a translation unit does not cause a compiler problem since the exact same 191 object-like macro occurs. 192 </p> 193<p> 194 The term for creating this macro is that we have potentially 'pre-detected' 195 the identifier and I will use the term pre-detected as the process of creating 196 the BOOST_VMD_DETECT macro. 197 </p> 198<p> 199 The ability to detect that a VMD identifier is a particular identifier is 200 used in VMD macros when data is compared for equality/inequality as well 201 as when we want to match an identifier against a set of other identifiers. 202 These situations will be explained later in the documentation when the particular 203 macro functionality is discussed. If the programmer never uses the functionality 204 which these situations encompass there is no need to use pre-detection for 205 a registered identifier. 206 </p> 207<h5> 208<a name="variadic_macro_data.vmd_specific.vmd_identifier.h4"></a> 209 <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_identifier.parsing_identifier_constraints_a"></a></span><a class="link" href="vmd_identifier.html#variadic_macro_data.vmd_specific.vmd_identifier.parsing_identifier_constraints_a">Parsing 210 identifier constraints and undefined behavior</a> 211 </h5> 212<p> 213 The reason that the identifier constraints mentioned above exist is that 214 the technique for parsing identifiers, once it is determined that the input 215 being parsed does not begin with a set of parentheses, uses preprocessor 216 concatenation in its parsing. This technique involves the preprocessor '##' 217 operator to concatenate input, and examine the results of that concatenation. 218 </p> 219<p> 220 When preprocessor concatenation is used the result of the concatenation must 221 be a valid preprocessing token, else the behavior of the preprocessor is 222 undefined. In C++ 'undefined behavior' in general means that anything can 223 happen. In practical use when preprocessor concatenation does not produce 224 a valid preprocessing token, a compiler is most likely to generate a preprocessing 225 error. If the compiler chooses not to issue a preprocessing error the outcome 226 will always be correct and mean that parsing an identifier will fail. But 227 because the outcome is undefined behavior there is no absolute way that the 228 programmer can determine what the outcome will be when preprocessor concatenation 229 is used and the input being parsed contains preprocessor input which does 230 not meet the constraints for parsing an identifier mentioned at the beginning 231 of this topic. 232 </p> 233<p> 234 In this documentation I will be using the abbreviation 'UB' as the shortened 235 form of 'undefined behavior' to denote the particular occurrence where VMD 236 attempts to parse preprocessor input using preprocessor concatenation and 237 undefined behavior will occur. 238 </p> 239<h5> 240<a name="variadic_macro_data.vmd_specific.vmd_identifier.h5"></a> 241 <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_identifier.usage"></a></span><a class="link" href="vmd_identifier.html#variadic_macro_data.vmd_specific.vmd_identifier.usage">Usage</a> 242 </h5> 243<p> 244 To use the BOOST_VMD_IS_IDENTIFIER macro either include the general header: 245 </p> 246<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">vmd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 247</pre> 248<p> 249 or include the specific header: 250 </p> 251<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">is_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 252</pre> 253</div> 254<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 255<td align="left"></td> 256<td align="right"><div class="copyright-footer">Copyright © 2010-2017 Tropic Software 257 East Inc</div></td> 258</tr></table> 259<hr> 260<div class="spirit-nav"> 261<a accesskey="p" href="vmd_constraints.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../vmd_specific.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_number.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 262</div> 263</body> 264</html> 265