1 2 // (C) Copyright Edward Diener 2011-2015 3 // Use, modification and distribution are subject to the Boost Software License, 4 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt). 6 7 #if !defined(BOOST_VMD_ELEM_HPP) 8 #define BOOST_VMD_ELEM_HPP 9 10 #include <boost/vmd/detail/setup.hpp> 11 12 #if BOOST_PP_VARIADICS 13 14 #include <boost/vmd/detail/modifiers.hpp> 15 #include <boost/vmd/detail/sequence_elem.hpp> 16 17 /* 18 19 The succeeding comments in this file are in doxygen format. 20 21 */ 22 23 /** \file 24 */ 25 26 /** \def BOOST_VMD_ELEM(elem,...) 27 28 \brief Accesses an element of a sequence. 29 30 elem = A sequence element number. From 0 to sequence size - 1. <br/> 31 ... = Variadic parameters. 32 33 The first variadic parameter is required and is the sequence to access. 34 Further variadic parameters are all optional. 35 36 With no further variadic parameters the macro returns the particular element 37 in the sequence. If the element number is outside the bounds of the sequence 38 macro access fails and the macro turns emptiness. 39 40 Optional parameters determine what it means that an element is successfully 41 accessed as well as what data is returned by the macro. 42 43 Filters: specifying a VMD type tells the macro to return the element only 44 if it is of the VMD type specified, else macro access fails. If more than 45 one VMD type is specified as an optional parameter the last one 46 specified is the filter. 47 48 Matching Identifiers: If the filter is specified as the identifier type, BOOST_VMD_TYPE_IDENTIFIER, 49 optional parameters which are identifiers specify that the element accessed 50 must match one of the identifiers else access fails. The identifiers may be specified multiple 51 times as single optional parameters or once as a tuple of identifier 52 parameters. If the identifiers are specified as single optional parameters 53 they cannot be any of the specific BOOST_VMD_ optional parameters in order to be 54 recognized as matching identifiers. Normally this should never be the case. 55 The only situation where this could occur is if the VMD types, which are filters, 56 are used as matching identifiers; in this case the matching identifiers need 57 to be passed as a tuple of identifier parameters so they are not treated 58 as filters. 59 60 Filters and matching identifiers change what it means that an element is successfully 61 accessed. They do not change what data is returned by the macro. The remaining optional 62 parameters do not change what it means that an element is successfully accessed but they 63 do change what data is returned by the macro. 64 65 @code 66 67 Splitting: Splitting allows the macro to return the rest of the sequence 68 after the element accessed. 69 70 If BOOST_VMD_RETURN_AFTER is specified the return is a tuple 71 with the element accessed as the first tuple parameter and the rest of 72 the sequence as the second tuple parameter. If element access fails 73 both tuple parameters are empty. 74 75 If BOOST_VMD_RETURN_ONLY_AFTER 76 is specified the return is the rest of the sequence after the element accessed 77 found. If the element access fails the return is emptiness. 78 79 If BOOST_VMD_RETURN_NO_AFTER, the default, is specified no splitting 80 occurs. 81 82 If more than one of the splitting identifiers are specified 83 the last one specified determines the splitting. 84 85 Return Type: The element accessed can be changed to return both the type 86 of the element as well as the element data with optional return type 87 parameters. When a type is returned, the element accessed which is returned becomes a 88 two-element tuple where the type of the element accessed is the first tuple element and the element 89 data itself is the second tuple element. If the macro fails to access the 90 element the element access returned is emptiness and not a tuple. 91 92 If BOOST_VMD_RETURN_NO_TYPE, the default, is specified no type is returned 93 as part of the element accessed. 94 95 If BOOST_VMD_RETURN_TYPE is specified the specific type of the element 96 is returned in the tuple. 97 98 If BOOST_VMD_RETURN_TYPE_ARRAY is specified 99 an array type is returned if the element is an array, else a tuple 100 type is returned if the element is a tuple, else the actual type 101 is returned for non-tuple data. 102 103 If BOOST_VMD_RETURN_TYPE_LIST is specified 104 a list type is returned if the element is a list, else a tuple 105 type is returned if the element is a tuple, else the actual type 106 is returned for non-tuple data. 107 108 If BOOST_VMD_RETURN_TYPE_TUPLE is specified 109 a tuple type is returned for all tuple-like data, else the actual type 110 is returned for non-tuple data. 111 112 If more than one return type optional 113 parameter is specified the last one specified determines the return type. 114 115 If a filter is specified optional return type parameters are ignored and 116 the default BOOST_VMD_RETURN_NO_TYPE is in effect. 117 118 Index: If the filter is specified as the identifier type, BOOST_VMD_TYPE_IDENTIFIER, 119 and matching identifiers are specified, an index parameter specifies that the 120 numeric index, starting with 0, of the matching identifier found, be returned 121 as part of the result. 122 123 If BOOST_VMD_RETURN_INDEX is specified an index is returned 124 as part of the result. 125 126 If BOOST_VMD_RETURN_NO_INDEX, the default, is specified 127 no index is returned as part of the result. 128 129 If both are specified the last one specified determines the index parameter. 130 131 When an index is returned as part of the result, the result is a tuple where the 132 element accessed is the first tuple parameter and the index is the last tuple parameter. 133 If element access fails the index is empty. If there is no BOOST_VMD_TYPE_IDENTIFIER 134 filter or if there are no matching identifiers the BOOST_VMD_RETURN_INDEX is ignored 135 and no index is returned as part of the result. 136 137 @endcode 138 139 returns = With no optional parameters the element accessed is returned, or emptiness if 140 element is outside the bounds of the sequence. Filters and matching identifiers 141 can change the meaning of whether the element accessed is returned or failure 142 occurs, but whenever failure occurs emptiness is returned as the element access part 143 of that failure, else the element accessed is returned. Return type optional parameters, 144 when filters are not used, return the element accessed as a two-element tuple 145 where the first tuple element is the type and the second tuple element is the 146 data; if the element is not accessed then emptiness is returned as the element access 147 and not a tuple. Splitting with BOOST_VMD_RETURN_AFTER returns a tuple where the element accessed 148 is the first tuple element and the rest of the sequence is the second tuple element. 149 Splitting with BOOST_VMD_RETURN_ONLY_AFTER returns the rest of the sequence after 150 the element accessed or emptiness if the element can not be accessed. Indexing 151 returns the index as part of the output only if filtering with 152 BOOST_VMD_TYPE_IDENTIFIER is specified and matching identifiers are specified. 153 When the index is returned with BOOST_VMD_RETURN_AFTER it is the third element 154 of the tuple returned, else it is the second element of a tuple where the element 155 accessed is the first element of the tuple. 156 157 */ 158 159 #define BOOST_VMD_ELEM(elem,...) \ 160 BOOST_VMD_DETAIL_SEQUENCE_ELEM(BOOST_VMD_ALLOW_ALL,elem,__VA_ARGS__) \ 161 /**/ 162 163 /** \def BOOST_VMD_ELEM_D(d,elem,...) 164 165 \brief Accesses an element of a sequence. Re-entrant version. 166 167 d = The next available BOOST_PP_WHILE iteration. <br/> 168 elem = A sequence element number. From 0 to sequence size - 1. <br/> 169 ... = Variadic parameters. 170 171 The first variadic parameter is required and is the sequence to access. 172 Further variadic parameters are all optional. 173 174 With no further variadic parameters the macro returns the particular element 175 in the sequence. If the element number is outside the bounds of the sequence 176 macro access fails and the macro turns emptiness. 177 178 Optional parameters determine what it means that an element is successfully 179 accessed as well as what data is returned by the macro. 180 181 Filters: specifying a VMD type tells the macro to return the element only 182 if it is of the VMD type specified, else macro access fails. If more than 183 one VMD type is specified as an optional parameter the last one 184 specified is the filter. 185 186 Matching Identifiers: If the filter is specified as the identifier type, BOOST_VMD_TYPE_IDENTIFIER, 187 optional parameters which are identifiers specify that the element accessed 188 must match one of the identifiers else access fails. The identifiers may be specified multiple 189 times as single optional parameters or once as a tuple of identifier 190 parameters. If the identifiers are specified as single optional parameters 191 they cannot be any of the specific BOOST_VMD_ optional parameters in order to be 192 recognized as matching identifiers. Normally this should never be the case. 193 The only situation where this could occur is if the VMD types, which are filters, 194 are used as matching identifiers; in this case the matching identifiers need 195 to be passed as a tuple of identifier parameters so they are not treated 196 as filters. 197 198 Filters and matching identifiers change what it means that an element is successfully 199 accessed. They do not change what data is returned by the macro. The remaining optional 200 parameters do not change what it means that an element is successfully accessed but they 201 do change what data is returned by the macro. 202 203 @code 204 205 Splitting: Splitting allows the macro to return the rest of the sequence 206 after the element accessed. 207 208 If BOOST_VMD_RETURN_AFTER is specified the return is a tuple 209 with the element accessed as the first tuple parameter and the rest of 210 the sequence as the second tuple parameter. If element access fails 211 both tuple parameters are empty. 212 213 If BOOST_VMD_RETURN_ONLY_AFTER 214 is specified the return is the rest of the sequence after the element accessed 215 found. If the element access fails the return is emptiness. 216 217 If BOOST_VMD_RETURN_NO_AFTER, the default, is specified no splitting 218 occurs. 219 220 If more than one of the splitting identifiers are specified 221 the last one specified determines the splitting. 222 223 Return Type: The element accessed can be changed to return both the type 224 of the element as well as the element data with optional return type 225 parameters. When a type is returned, the element accessed which is returned becomes a 226 two-element tuple where the type of the element accessed is the first tuple element and the element 227 data itself is the second tuple element. If the macro fails to access the 228 element the element access returned is emptiness and not a tuple. 229 230 If BOOST_VMD_RETURN_NO_TYPE, the default, is specified no type is returned 231 as part of the element accessed. 232 233 If BOOST_VMD_RETURN_TYPE is specified the specific type of the element 234 is returned in the tuple. 235 236 If BOOST_VMD_RETURN_TYPE_ARRAY is specified 237 an array type is returned if the element is an array, else a tuple 238 type is returned if the element is a tuple, else the actual type 239 is returned for non-tuple data. 240 241 If BOOST_VMD_RETURN_TYPE_LIST is specified 242 a list type is returned if the element is a list, else a tuple 243 type is returned if the element is a tuple, else the actual type 244 is returned for non-tuple data. 245 246 If BOOST_VMD_RETURN_TYPE_TUPLE is specified 247 a tuple type is returned for all tuple-like data, else the actual type 248 is returned for non-tuple data. If more than one return type optional 249 parameter is specified the last one specified determines the return type. 250 251 If a filter is specified optional return type parameters are ignored and 252 the default BOOST_VMD_RETURN_NO_TYPE is in effect. 253 254 Index: If the filter is specified as the identifier type, BOOST_VMD_TYPE_IDENTIFIER, 255 and matching identifiers are specified, an index parameter specifies that the 256 numeric index, starting with 0, of the matching identifier found, be returned 257 as part of the result. 258 259 If BOOST_VMD_RETURN_INDEX is specified an index is returned 260 as part of the result. 261 262 If BOOST_VMD_RETURN_NO_INDEX, the default, is specified 263 no index is returned as part of the result. 264 265 If both are specified the last one specified determines the index parameter. 266 267 When an index is returned as part of the result, the result is a tuple where the 268 element accessed is the first tuple parameter and the index is the last tuple parameter. 269 If element access fails the index is empty. If there is no BOOST_VMD_TYPE_IDENTIFIER 270 filter or if there are no matching identifiers the BOOST_VMD_RETURN_INDEX is ignored 271 and no index is returned as part of the result. 272 273 @endcode 274 275 returns = With no optional parameters the element accessed is returned, or emptiness if 276 element is outside the bounds of the sequence. Filters and matching identifiers 277 can change the meaning of whether the element accessed is returned or failure 278 occurs, but whenever failure occurs emptiness is returned as the element access part 279 of that failure, else the element accessed is returned. Return type optional parameters, 280 when filters are not used, return the element accessed as a two-element tuple 281 where the first tuple element is the type and the second tuple element is the 282 data; if the element is not accessed then emptiness is returned as the element access 283 and not a tuple. Splitting with BOOST_VMD_RETURN_AFTER returns a tuple where the element accessed 284 is the first tuple element and the rest of the sequence is the second tuple element. 285 Splitting with BOOST_VMD_RETURN_ONLY_AFTER returns the rest of the sequence after 286 the element accessed or emptiness if the element can not be accessed. Indexing 287 returns the index as part of the output only if filtering with 288 BOOST_VMD_TYPE_IDENTIFIER is specified and matching identifiers are specified. 289 When the index is returned with BOOST_VMD_RETURN_AFTER it is the third element 290 of the tuple returned, else it is the second element of a tuple where the element 291 accessed is the first element of the tuple. 292 293 */ 294 295 #define BOOST_VMD_ELEM_D(d,elem,...) \ 296 BOOST_VMD_DETAIL_SEQUENCE_ELEM_D(d,BOOST_VMD_ALLOW_ALL,elem,__VA_ARGS__) \ 297 /**/ 298 299 #endif /* BOOST_PP_VARIADICS */ 300 #endif /* BOOST_VMD_ELEM_HPP */ 301