• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
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">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
247</pre>
248<p>
249        or include the specific header:
250      </p>
251<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
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