]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/vmd/doc/vmd_equality.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / vmd / doc / vmd_equality.qbk
CommitLineData
7c673cae
FG
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_assert Testing for equality and inequality]
9
10VMD allows the programmer to test generically for the equality or inequality
11of any value which VMD can parse. This includes emptiness, identifiers, numbers,
12types, arrays, lists, seqs, tuples, and multi-element sequences.
13
14The macro to test for equality is called BOOST_VMD_EQUAL and it has two required
15parameters which are the two values against which to test. The values can be any
16VMD data type.
17
18For the composite data types of array, list, seq, and tuple, or any of those types
19in a multi-element sequence, the elements of those types must also be a data type
20which VMD can parse. BOOST_VMD_EQUAL recursively parses the elements in a composite data type
21for equality, up to a level of 16 inner types, to test that one composite type
22equals another composite type. The requirement, that composite elements must also
23be a data type which VMD can parse, is different from most other macros
24in the VMD library, where only the top-level composite type need be parsed enough to
25determine the type of the data. If BOOST_VMD_EQUAL encounters a data type which it
26cannot parse the result will be UB.
27
28VMD identifiers used in equality testing must be registered and pre-detected.
29All numbers and v-types are already registered/pre-detected for equality testing
30so it is only user-defined identifiers which must be registered and pre-detected.
31If an identifier has not been both registered and predetected it will never be
32equal to the same identifier value, so it will always fail equality testing,
33although it will not give a preprocessing error doing so.
34
35The BOOST_VMD_EQUAL macro returns 1 if both parameters are equal and 0 if the
36parameters are not equal.
37
38Conversely to test for inequality, of the same values as are required in testing
39for equality, the VMD library has the macro BOOST_VMD_NOT_EQUAL. This macro is simply
40a complement of the BOOST_VMD_EQUAL macro. If BOOST_VMD_EQUAL returns 1 then
41BOOST_VMD_NOT_EQUAL returns 0 and if BOOST_VMD_EQUAL returns 0 then
42BOOST_VMD_NOT_EQUAL returns 1.
43
44The BOOST_VMD_EQUAL and BOOST_VMD_NOT_EQUAL macros are called "equality macros".
45
46 #include <boost/vmd/equal.hpp>
47
48 #define BOOST_VMD_REGISTER_AN_ID1 (AN_ID1)
49 #define BOOST_VMD_REGISTER_AN_ID2 (AN_ID2)
50
51 #define BOOST_VMD_DETECT_AN_ID1_AN_ID1
52 #define BOOST_VMD_DETECT_AN_ID2_AN_ID2
53
54 #define AN_IDENTIFIER1 AN_ID1
55 #define AN_IDENTIFIER2 AN_ID2
56 #define AN_IDENTIFIER3 AN_ID1 // same as AN_IDENTIFIER1 = AN_ID1
57
58 #define A_NUMBER1 33
59 #define A_NUMBER2 145
60 #define A_NUMBER3 33 // same as A_NUMBER1 = 33
61
62 #define A_TUPLE1 (AN_IDENTIFIER1,A_NUMBER1)
63 #define A_TUPLE2 (AN_IDENTIFIER1,A_NUMBER2)
64 #define A_TUPLE3 (AN_IDENTIFIER3,A_NUMBER3) // same as A_TUPLE1 = (AN_ID1,33)
65
66 #define A_SEQ1 (A_NUMBER1)(A_TUPLE1)
67 #define A_SEQ2 (A_NUMBER2)(A_TUPLE2)
68 #define A_SEQ3 (A_NUMBER3)(A_TUPLE3) // same as A_SEQ1 = (33)((AN_ID1,33))
69
70 BOOST_VMD_EQUAL(AN_IDENTIFIER1,AN_IDENTIFIER2) will return 0
71 BOOST_VMD_EQUAL(AN_IDENTIFIER1,AN_IDENTIFIER3) will return 1
72
73 BOOST_VMD_EQUAL(A_NUMBER1,A_NUMBER2) will return 0
74 BOOST_VMD_EQUAL(A_NUMBER1,A_NUMBER3) will return 1
75
76 BOOST_VMD_EQUAL(A_TUPLE1,A_TUPLE2) will return 0
77 BOOST_VMD_EQUAL(A_TUPLE1,A_TUPLE3) will return 1
78
79 BOOST_VMD_EQUAL(A_SEQ1,A_SEQ2) will return 0
80 BOOST_VMD_EQUAL(A_SEQ1,A_SEQ3) will return 1
81
82When BOOST_VMD_EQUAL tests for equality it always parses data for their most
83specific types. The reason for this is that a valid tuple, which is also an invalid
84list or array, can never be compared completely because all elements of that tuple
85are not data types which VMD can parse. Therefore VMD always tests equality based
86on the most specific type for any value being tested, which speeds up testing for
87the more specific tuple data types such as lists and arrays.
88
89 #define TUPLE_IS_ARRAY1 (2,(3,4))
90 #define TUPLE_IS_ARRAY2 (2,(4,5))
91 #define TUPLE_IS_ARRAY3 (2,(3,4))
92
93 #define TUPLE_IS_LIST1 (55,BOOST_PP_NIL)
94 #define TUPLE_IS_LIST2 (135,BOOST_PP_NIL)
95 #define TUPLE_IS_LIST3 (55,BOOST_PP_NIL)
96
97 #define TUPLE_IS_LIST_OR_ARRAY1 (2,(3,BOOST_PP_NIL))
98 #define TUPLE_IS_LIST_OR_ARRAY2 (2,(4,BOOST_PP_NIL))
99 #define TUPLE_IS_LIST_OR_ARRAY3 (2,(3,BOOST_PP_NIL))
100
101 #define TUPLE_BUT_INVALID_ARRAY1 (&2,(3,4))
102 #define TUPLE_BUT_INVALID_ARRAY2 (&2,(4,4))
103 #define TUPLE_BUT_INVALID_ARRAY3 (&2,(3,4))
104
105 #define TUPLE_BUT_INVALID_LIST1 (55,^BOOST_PP_NIL)
106 #define TUPLE_BUT_INVALID_LIST2 (135,^BOOST_PP_NIL)
107 #define TUPLE_BUT_INVALID_LIST3 (55,^BOOST_PP_NIL)
108
109All of the constructs above are valid tuples.
110
111The first three are valid arrays, so they will be parsed and compared
112as arrays, so that they can be used as in:
113
114 #include <boost/vmd/equal.hpp>
115
116 BOOST_VMD_EQUAL(TUPLE_IS_ARRAY1,TUPLE_IS_ARRAY2) will return 0
117 BOOST_VMD_EQUAL(TUPLE_IS_ARRAY1,TUPLE_IS_ARRAY3) will return 1
118
119The next three are valid lists, so they will be parsed and compared
120as lists, so that they can be used as in:
121
122 #include <boost/vmd/equal.hpp>
123
124 BOOST_VMD_EQUAL(TUPLE_IS_LIST1,TUPLE_IS_LIST2) will return 0
125 BOOST_VMD_EQUAL(TUPLE_IS_LIST1,TUPLE_IS_LIST3) will return 1
126
127The next three are valid lists or arrays but will be parsed as lists
128because lists are more specific than arrays. They can be used as in:
129
130 #include <boost/vmd/equal.hpp>
131
132 BOOST_VMD_EQUAL(TUPLE_IS_LIST_OR_ARRAY1,TUPLE_IS_LIST_OR_ARRAY2) will return 0
133 BOOST_VMD_EQUAL(TUPLE_IS_LIST_OR_ARRAY1,TUPLE_IS_LIST_OR_ARRAY3) will return 1
134
135The next three are valid tuples but invalid arrays. The BOOST_VMD_EQUAL
136macro attempts to parse them as the most specific type they can be, which is an
137array. But the attempt to parse them as arrays will lead to UB
138because the number which signifies the size of the array is invalid as
139a number. Now let us suppose we should parse them as the less specific type
140of a tuple instead of as an array. This will still give UB
141if we will attempt to compare the first tuple element against a corresponding
142first tuple element of another tuple, and when we do will again encounter UB
143because it is not a data type VMD can parse.
144
145 #include <boost/vmd/equal.hpp>
146
147 BOOST_VMD_EQUAL(TUPLE_BUT_INVALID_ARRAY1,TUPLE_BUT_INVALID_ARRAY1) will generate UB
148 BOOST_VMD_EQUAL(TUPLE_BUT_INVALID_ARRAY1,TUPLE_BUT_INVALID_ARRAY1) will generate UB
149
150The next three are valid tuples but invalid lists. The BOOST_VMD_EQUAL
151macro attempts to parse them as the most specific type they can be, which is
152a list. But the attempt to parse them as lists will lead to UB
153because the identifier which signifies the end-of-list is invalid as
154an identifier. Now let us suppose we should parse them as the less specific type
155of a tuple instead of as a list. This will still give UB
156if we will attempt to compare the second tuple element against a corresponding
157second tuple element of another tuple, and when we do will again encounter UB
158because it is not a data type VMD can parse.
159
160 #include <boost/vmd/equal.hpp>
161
162 BOOST_VMD_EQUAL(TUPLE_BUT_INVALID_LIST1,TUPLE_BUT_INVALID_LIST2) will generate UB
163 BOOST_VMD_EQUAL(TUPLE_BUT_INVALID_LIST1,TUPLE_BUT_INVALID_LIST3) will generate UB
164
165It is possible that a composite data type which has an element which VMD cannot parse
166will not give UB when compared for equality, but rather just the test for equality
167will fail. This can occur if the algorithm which tests for equality tests false before parsing of
168the particular element. Such a situation might be:
169
170 #include <boost/vmd/equal.hpp>
171
172 #define A_TUPLE1 (3,4,"astring")
173 #define A_TUPLE2 (3,4)
174
175 BOOST_VMD_EQUAL(A_TUPLE1,A_TUPLE2) will return 0 rather than generate UB
176
177The reason the above correctly returns 0, rather than generate UB when
178VMD attempts to parse '"astring"', which is not a data type VMD can parse, is because the
179algorithm for testing equality tests whether or not the tuples have the same number of elements
180before it tests for the equality of each element. This is just one example where testing for
181equality may fail before UB is generated when BOOST_VMD_EQUAL attempts to
182parse a data type which it cannot handle. Nevertheless the general rule should still be considered
183that for BOOST_VMD_EQUAL/BOOT_VMD_NOT_EQUAL all data types, even an element of a composite data
184type, must be a VMD data type if the macro is to work properly, else UB could occur.
185
186[heading Usage]
187
188You can use the general header file:
189
190 #include <boost/vmd/vmd.hpp>
191
192or you can use the individual header files:
193
194 #include <boost/vmd/equal.hpp> for the BOOST_VMD_EQUAL macro
195 #include <boost/vmd/not_equal.hpp> for the BOOST_VMD_NOT_EQUAL macro
196
197[endsect]