Loading...
Searching...
No Matches
staticTokens.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the Apache License, Version 2.0 (the "Apache License")
5// with the following modification; you may not use this file except in
6// compliance with the Apache License and the following modification to it:
7// Section 6. Trademarks. is deleted and replaced with:
8//
9// 6. Trademarks. This License does not grant permission to use the trade
10// names, trademarks, service marks, or product names of the Licensor
11// and its affiliates, except as required to comply with Section 4(c) of
12// the License and to reproduce the content of the NOTICE file.
13//
14// You may obtain a copy of the Apache License at
15//
16// http://www.apache.org/licenses/LICENSE-2.0
17//
18// Unless required by applicable law or agreed to in writing, software
19// distributed under the Apache License with the above modification is
20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21// KIND, either express or implied. See the Apache License for the specific
22// language governing permissions and limitations under the Apache License.
23//
24//todo: cleanup: TF_DEFINE_PRIVATE_TOKENS, should use the public versions
25//todo: cleanup: document each macro extensivly
26//todo: cleanup: order macros, so that it is easier to see the structure
27//todo: simply syntax, we should get rid of braces for each array element and
28// each element
29
30#ifndef PXR_BASE_TF_STATIC_TOKENS_H
31#define PXR_BASE_TF_STATIC_TOKENS_H
32
77
78#include "pxr/pxr.h"
80#include "pxr/base/tf/preprocessorUtilsLite.h"
82#include "pxr/base/tf/token.h"
83
84#include <vector>
85
86#include <boost/preprocessor/cat.hpp>
87#include <boost/preprocessor/control/iif.hpp>
88#include <boost/preprocessor/control/expr_iif.hpp>
89#include <boost/preprocessor/logical/and.hpp>
90#include <boost/preprocessor/logical/not.hpp>
91#include <boost/preprocessor/punctuation/comma_if.hpp>
92#include <boost/preprocessor/seq/filter.hpp>
93#include <boost/preprocessor/seq/for_each.hpp>
94#include <boost/preprocessor/seq/for_each_i.hpp>
95#include <boost/preprocessor/seq/size.hpp>
96#include <boost/preprocessor/tuple/elem.hpp>
97
98PXR_NAMESPACE_OPEN_SCOPE
99
100// TF_DECLARE_PUBLIC_TOKENS use these macros to handle two or three arguments.
101// The three argument version takes an export/import macro (e.g. TF_API)
102// while the two argument version does not export the tokens.
103
104#define _TF_DECLARE_PUBLIC_TOKENS3(key, eiapi, seq) \
105 _TF_DECLARE_TOKENS3(key, seq, eiapi) \
106 extern eiapi TfStaticData<_TF_TOKENS_STRUCT_NAME(key)> key
107#define _TF_DECLARE_PUBLIC_TOKENS2(key, seq) \
108 _TF_DECLARE_TOKENS2(key, seq) \
109 extern TfStaticData<_TF_TOKENS_STRUCT_NAME(key)> key
110#define _TF_DECLARE_PUBLIC_TOKENS(N) _TF_DECLARE_PUBLIC_TOKENS##N
111#define _TF_DECLARE_PUBLIC_TOKENS_EVAL(N) _TF_DECLARE_PUBLIC_TOKENS(N)
112#define _TF_DECLARE_PUBLIC_TOKENS_EXPAND(x) x
113
117#define TF_DECLARE_PUBLIC_TOKENS(...) _TF_DECLARE_PUBLIC_TOKENS_EXPAND( _TF_DECLARE_PUBLIC_TOKENS_EVAL(_TF_DECLARE_PUBLIC_TOKENS_EXPAND( TF_NUM_ARGS(__VA_ARGS__) ))(__VA_ARGS__) )
118
122#define TF_DEFINE_PUBLIC_TOKENS(key, seq) \
123 _TF_DEFINE_TOKENS(key, seq) \
124 TfStaticData<_TF_TOKENS_STRUCT_NAME(key)> key
125
128#define TF_DEFINE_PRIVATE_TOKENS(key, seq) \
129 namespace { \
130 struct _TF_TOKENS_STRUCT_NAME_PRIVATE(key) { \
131 _TF_TOKENS_STRUCT_NAME_PRIVATE(key)() : \
132 _TF_TOKENS_INITIALIZE_SEQ( \
133 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_NOT_ARRAY, ~, seq) \
134 _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
135 { \
136 _TF_TOKENS_ASSIGN_ARRAY_SEQ( \
137 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_ARRAY, ~, seq)) \
138 _TF_TOKENS_BUILD_ALLTOKENS_VECTOR( \
139 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_NOT_ARRAY, ~, seq) \
140 _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
141 } \
142 _TF_TOKENS_DECLARE_MEMBERS(seq) \
143 }; \
144 } \
145 static TfStaticData<_TF_TOKENS_STRUCT_NAME_PRIVATE(key)> key
146
148// Private Macros
149
150// Private macro to generate struct name from key.
151//
152// Note that this needs to be a unique struct name for each translation unit.
153//
154#define _TF_TOKENS_STRUCT_NAME_PRIVATE(key) \
155 BOOST_PP_CAT(key, _PrivateStaticTokenType)
156
157// Private macro to generate struct name from key. This version is used
158// by the public token declarations, and so key must be unique for the entire
159// namespace.
160//
161#define _TF_TOKENS_STRUCT_NAME(key) \
162 BOOST_PP_CAT(key, _StaticTokenType)
163
165// Declaration Macros
166
167// Private macro used to generate TfToken member variables. elem can either
168// be a tuple on the form (name, value) or just a name.
169//
170#define _TF_TOKENS_DECLARE_MEMBER(r, data, elem) \
171 TfToken BOOST_PP_IIF(TF_PP_IS_TUPLE(elem), \
172 BOOST_PP_TUPLE_ELEM(2, 0, elem), elem) \
173 BOOST_PP_EXPR_IIF(TF_PP_IS_TUPLE(BOOST_PP_TUPLE_ELEM(2, 1, elem)), \
174 [BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(1, 0, \
175 BOOST_PP_TUPLE_ELEM(2, 1, elem)))]);
176
177// Private macro used to declare the list of members as TfTokens
178//
179#define _TF_TOKENS_DECLARE_MEMBERS(seq) \
180 BOOST_PP_SEQ_FOR_EACH(_TF_TOKENS_DECLARE_MEMBER, ~, \
181 seq _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
182 std::vector<TfToken> allTokens;
183
184// Private macro that expands all array elements to make them members
185// of the sequence.
186//
187#define _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq) \
188 BOOST_PP_SEQ_FOR_EACH(_TF_TOKENS_APPEND_ARRAY_ELEMENTS, \
189 ~, \
190 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_ARRAY, ~, seq)) \
191
192// Private macro used to generate a struct of TfTokens.
193//
194#define _TF_DECLARE_TOKENS3(key, seq, eiapi) \
195 struct _TF_TOKENS_STRUCT_NAME(key) { \
196 eiapi _TF_TOKENS_STRUCT_NAME(key)(); \
197 eiapi ~_TF_TOKENS_STRUCT_NAME(key)(); \
198 _TF_TOKENS_DECLARE_MEMBERS(seq) \
199 };
200
201#define _TF_DECLARE_TOKENS2(key, seq) \
202 struct _TF_TOKENS_STRUCT_NAME(key) { \
203 _TF_TOKENS_STRUCT_NAME(key)(); \
204 ~_TF_TOKENS_STRUCT_NAME(key)(); \
205 _TF_TOKENS_DECLARE_MEMBERS(seq) \
206 };
207
209// Definition Macros
210
211// Private macros to define members in the tokens struct.
212//
213#define _TF_TOKENS_DEFINE_MEMBER(r, data, i, elem) \
214 BOOST_PP_COMMA_IF(i) \
215 BOOST_PP_TUPLE_ELEM(1, 0, BOOST_PP_IIF(TF_PP_IS_TUPLE(elem), \
216 (_TF_TOKENS_INITIALIZE_MEMBER_TUPLE(elem)), \
217 (_TF_TOKENS_INITIALIZE_MEMBER(elem))))
218
219#define _TF_TOKENS_INITIALIZE_MEMBER_TUPLE(elem) \
220 BOOST_PP_TUPLE_ELEM(2, 0, elem)(BOOST_PP_TUPLE_ELEM(2, 1, elem), \
221 TfToken::Immortal) \
222
223#define _TF_TOKENS_INITIALIZE_MEMBER(elem) \
224 elem(TF_PP_STRINGIZE(elem), TfToken::Immortal)
225
226#define _TF_TOKENS_DEFINE_ARRAY_MEMBER(r, data, i, elem) \
227 data[i] = BOOST_PP_IIF(TF_PP_IS_TUPLE(elem), \
228 BOOST_PP_TUPLE_ELEM(2, 0, elem), elem);
229
230// Private macros to append tokens to the allTokens vector.
231//
232#define _TF_TOKENS_APPEND_MEMBER(r, data, i, elem) \
233 BOOST_PP_IIF(TF_PP_IS_TUPLE(elem), \
234 _TF_TOKENS_APPEND_MEMBER_BODY(~, ~, \
235 BOOST_PP_TUPLE_ELEM(2, 0, elem)), \
236 _TF_TOKENS_APPEND_MEMBER_BODY(~, ~, elem))
237
238#define _TF_TOKENS_APPEND_MEMBER_BODY(r, data, elem) \
239 allTokens.push_back(elem);
240
241#define _TF_TOKENS_BUILD_ALLTOKENS_VECTOR(seq) \
242 BOOST_PP_SEQ_FOR_EACH_I(_TF_TOKENS_APPEND_MEMBER, ~, seq)
243
244// Private macros to generate the list of initialized members.
245//
246#define _TF_TOKENS_INITIALIZE_SEQ(seq) \
247 BOOST_PP_SEQ_FOR_EACH_I(_TF_TOKENS_DEFINE_MEMBER, ~, seq)
248
249#define _TF_TOKENS_ASSIGN_ARRAY_SEQ(seq) \
250 BOOST_PP_SEQ_FOR_EACH(_TF_TOKENS_DEFINE_ARRAY_MEMBERS, ~, seq)
251
252#define _TF_TOKENS_DEFINE_ARRAY_MEMBERS(r, data, elem) \
253 BOOST_PP_SEQ_FOR_EACH_I(_TF_TOKENS_DEFINE_ARRAY_MEMBER, \
254 BOOST_PP_TUPLE_ELEM(2, 0, elem), \
255 BOOST_PP_TUPLE_ELEM(1, 0, BOOST_PP_TUPLE_ELEM(2, 1, elem)))
256
257// Private predicate macros to be used by SEQ_FILTER that determine if an
258// element of a sequence is an array of tokens or not.
259//
260#define _TF_TOKENS_IS_ARRAY(s, data, elem) \
261 BOOST_PP_AND(TF_PP_IS_TUPLE(elem), \
262 TF_PP_IS_TUPLE(BOOST_PP_TUPLE_ELEM(2, 1, elem)))
263
264#define _TF_TOKENS_IS_NOT_ARRAY(s, data, elem) \
265 BOOST_PP_NOT(_TF_TOKENS_IS_ARRAY(s, data, elem))
266
267// Private macro to append all array elements to a sequence.
268//
269#define _TF_TOKENS_APPEND_ARRAY_ELEMENTS(r, data, elem) \
270 BOOST_PP_TUPLE_ELEM(1, 0, BOOST_PP_TUPLE_ELEM(2, 1, elem))
271
272// Private macro to define the struct of tokens.
273//
274// This works by filtering the incoming seq in two ways. For the body of the
275// constructor, only array tokens are passed through (because they can't be
276// initialized via initializer lists). The initializer list's items are all
277// non-array seq elements _plus_ all array members themshelves. This way,
278// array tokens are also accessible without using [] which proved to be
279// a neat shortcut.
280//
281#define _TF_DEFINE_TOKENS(key, seq) \
282 _TF_TOKENS_STRUCT_NAME(key)::~_TF_TOKENS_STRUCT_NAME(key)() = default; \
283 _TF_TOKENS_STRUCT_NAME(key)::_TF_TOKENS_STRUCT_NAME(key)() : \
284 _TF_TOKENS_INITIALIZE_SEQ( \
285 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_NOT_ARRAY, ~, seq) \
286 _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
287 { \
288 _TF_TOKENS_ASSIGN_ARRAY_SEQ( \
289 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_ARRAY, ~, seq)) \
290 _TF_TOKENS_BUILD_ALLTOKENS_VECTOR( \
291 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_NOT_ARRAY, ~, seq) \
292 _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
293 }
294
295PXR_NAMESPACE_CLOSE_SCOPE
296
297#endif // PXR_BASE_TF_STATIC_TOKENS_H
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...