]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/vmd/doc/vmd_identifier.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / vmd / doc / vmd_identifier.qbk
1 [/
2 (C) Copyright Edward Diener 2011-2015
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt).
6 ]
7
8 [section:vmd_identifier Identifiers]
9
10 An identifier in VMD is either of two lower-level preprocessor possibilities:
11
12 * a preprocessing token 'identifier', which is essentially a sequence
13 of alphanumeric characters and the underscore
14 character with the first character not being a numeric character.
15 * a preprocessing token 'pp-number' that is an integral literal token.
16
17 Here are some examples:
18
19 SOME_NAME
20 _SOME_NAME
21 SOME_123_NAME
22 some_123_name
23 sOMe_123_NAmE
24 2367
25 43e11
26 0
27 22
28 654792
29 0x1256
30
31 [heading Problem testing any identifier]
32
33 One of the difficulties with identifiers in preprocessor metaprogramming
34 is safely testing for a particular one. VMD has a means of doing this within
35 a particular constraint for the characters that serve as the input.
36
37 The constraint is that the beginning input character, ignoring any whitespace, passed
38 as the input to test must be either:
39
40 * an identifier character, ie. an alphanumeric or an underscore
41 * the left parenthesis of a tuple
42
43 and if the first character is not the left parenthesis of a tuple
44 the remaining characters must be alphanumeric or an underscore until a space character
45 or end of input occurs.
46
47 If this is not the case the behavior is undefined, and most likely
48 a preprocessing error will occur.
49
50 Given the input:
51
52 's_anything' : can be tested
53 'S_anything' : can be tested
54 's_anYthiNg' : can be tested
55 '_anything' : can be tested
56 '_Anything' : can be tested
57 '_anytHIng' : can be tested
58 '24' : can be tested
59 '245e2' : can be tested
60 '(anything)' : can be tested, tuple
61 '(anything) anything' : can be tested, tuple and further input
62 'anything anything' : can be tested, identifier followed by space character
63
64 '%_anything' : undefined behavior and most likely a preprocessing error due to the constraint
65 '(_anything' : undefined behavior and most likely a preprocessing error due to the constraint, since a single '(' does not form a tuple
66 '44.3' : undefined behavior and most likely a preprocessing error due to the constraint since '.' is not alphanumeric
67
68 [heading Identifying an identifier]
69
70 In VMD the only way an identifier can be identified in preprocessor input is by a process called
71 registration. In order to 'register' an identifier to be recognized by VMD the end-user must create,
72 for every identifier to be recognized, an object-like macro whose form is:
73
74 #define BOOST_VMD_REGISTER_identifier (identifier)
75
76 where 'identifier' is a particular identifier we wish to identify. This is called in
77 VMD a registration macro.
78
79 It is recommended that such registration macros be created in a header file which
80 can be included before the end-user uses the identifier macros of VMD.
81
82 If a particular registration macro occurs more than once it is
83 not a preprocessing error, so duplicating a registration macro will not lead to any problems
84 since each registration macro of the same name will have the exact same object-like macro
85 expansion.
86
87 Within a given translation unit it could potentially happen
88 that registration macros have been included by header files which a particular end-user
89 of VMD has not created. This should also not lead to particular problems since registration
90 is a process for adding identifiers for any particular translation unit. As we shall see
91 VMD has macros for not only finding any identifier in preprocessor input but for also finding
92 any particular identifier in preprocessor input.
93
94 [heading Testing for an identifier macro]
95
96 The specific macro used to test for an identifier in VMD is called BOOST_VMD_IS_IDENTIFIER.
97 The macro takes one required parameter which is the input against which to test.
98
99 When we invoke BOOST_VMD_IS_IDENTIFIER it returns 1 if the input represents any
100 registered identifier, otherwise it returns 0.
101
102 As an example:
103
104 #include <boost/vmd/is_identifier.hpp>
105
106 #define BOOST_VMD_REGISTER_yellow (yellow)
107 #define BOOST_VMD_REGISTER_green (green)
108 #define BOOST_VMD_REGISTER_blue (blue)
109
110 BOOST_VMD_IS_IDENTIFIER(some_input) // returns 1 if 'some_input' is 'yellow','green', or 'blue'
111 BOOST_VMD_IS_IDENTIFIER(some_input) // returns 0 if 'some_input' is 'purple'
112
113 Essentially only registered identifiers can be found in VMD as identifiers.
114
115 [heading Detecting a particular identifier]
116
117 Although registering an identifier allows VMD to recognize the string of characters
118 as a VMD identifier, the ability to detect a particular identifier needs the end-user
119 to define another macro:
120
121 #define BOOST_VMD_DETECT_identifier_identifier
122
123 where 'identifier' is a particular identifier we wish to detect. This object-like
124 macro expands to no output.
125
126 Like the registration macro multiple detection macros of the same identifier
127 in a translation unit does not cause a compiler problem since the exact same
128 object-like macro occurs.
129
130 The term for creating this macro is that we have potentially 'pre-detected'
131 the identifier and I will use the term pre-detected as the process of creating
132 the BOOST_VMD_DETECT macro.
133
134 The ability to detect that a VMD identifier is a particular identifier is used
135 in VMD macros when data is compared for equality/inequality as well as when we
136 want to match an identifier against a set of other identifiers. These situations
137 will be explained later in the documentation when the particular macro functionality
138 is discussed. If the programmer never uses the functionality which these situations
139 encompass there is no need to use pre-detection for a registered identifier.
140
141 [heading Parsing identifiers and undefined behavior]
142
143 The technique for parsing identifiers, once it is determined that the input
144 being parsed does not begin with a set of parentheses, uses preprocessor
145 concatenation in its parsing. This technique involves the preprocessor '##'
146 operator to concatenate input, and examine the results of that concatenation.
147
148 When preprocessor concatenation is used the result of the concatenation must
149 be a valid preprocessing token, else the behavior of the preprocessor is undefined.
150 In C++ 'undefined behavior' in general means that anything can happen. In practical
151 use when preprocessor concatenation does not produce a valid preprocessing token,
152 a compiler is most likely to generate a preprocessing error. If the compiler chooses
153 not to issue a preprocessing error the outcome will always mean that parsing an
154 identifier will fail. But because the outcome is undefined behavior there is no
155 absolute way that the programmer can determine what the outcome will be when
156 preprocessor concatenation is used and the input being parsed contains
157 preprocessor input which does not meet the constraints for parsing an identifier
158 mentioned at the beginning of this topic.
159
160 In this documentation I will be using the abbreviation 'UB' as the shortened form
161 of 'undefined behavior' to denote the particular occurrence where VMD attempts to
162 parse preprocessor input using preprocessor concatenation and undefined behavior
163 will occur.
164
165 [heading Usage]
166
167 To use the BOOST_VMD_IS_IDENTIFIER macro either include the general header:
168
169 #include <boost/vmd/vmd.hpp>
170
171 or include the specific header:
172
173 #include <boost/vmd/is_identifier.hpp>
174
175 [endsect]