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"
79#include "pxr/base/tf/preprocessorUtilsLite.h"
81#include "pxr/base/tf/token.h"
82
83#include <vector>
84
85#include <boost/preprocessor/control/iif.hpp>
86#include <boost/preprocessor/control/expr_iif.hpp>
87#include <boost/preprocessor/logical/and.hpp>
88#include <boost/preprocessor/logical/not.hpp>
89#include <boost/preprocessor/punctuation/comma_if.hpp>
90#include <boost/preprocessor/seq/filter.hpp>
91#include <boost/preprocessor/seq/for_each.hpp>
92#include <boost/preprocessor/seq/for_each_i.hpp>
93#include <boost/preprocessor/seq/size.hpp>
94#include <boost/preprocessor/tuple/elem.hpp>
95
96PXR_NAMESPACE_OPEN_SCOPE
97
98// TF_DECLARE_PUBLIC_TOKENS use these macros to handle two or three arguments.
99// The three argument version takes an export/import macro (e.g. TF_API)
100// while the two argument version does not export the tokens.
101
102#define _TF_DECLARE_PUBLIC_TOKENS3(key, eiapi, seq) \
103 _TF_DECLARE_TOKENS3(key, seq, eiapi) \
104 extern eiapi TfStaticData<_TF_TOKENS_STRUCT_NAME(key)> key
105#define _TF_DECLARE_PUBLIC_TOKENS2(key, seq) \
106 _TF_DECLARE_TOKENS2(key, seq) \
107 extern TfStaticData<_TF_TOKENS_STRUCT_NAME(key)> key
108#define _TF_DECLARE_PUBLIC_TOKENS(N) _TF_DECLARE_PUBLIC_TOKENS##N
109#define _TF_DECLARE_PUBLIC_TOKENS_EVAL(N) _TF_DECLARE_PUBLIC_TOKENS(N)
110#define _TF_DECLARE_PUBLIC_TOKENS_EXPAND(x) x
111
115#define TF_DECLARE_PUBLIC_TOKENS(...) _TF_DECLARE_PUBLIC_TOKENS_EXPAND( _TF_DECLARE_PUBLIC_TOKENS_EVAL(_TF_DECLARE_PUBLIC_TOKENS_EXPAND( TF_PP_VARIADIC_SIZE(__VA_ARGS__) ))(__VA_ARGS__) )
116
120#define TF_DEFINE_PUBLIC_TOKENS(key, seq) \
121 _TF_DEFINE_TOKENS(key, seq) \
122 TfStaticData<_TF_TOKENS_STRUCT_NAME(key)> key
123
126#define TF_DEFINE_PRIVATE_TOKENS(key, seq) \
127 namespace { \
128 struct _TF_TOKENS_STRUCT_NAME_PRIVATE(key) { \
129 _TF_TOKENS_STRUCT_NAME_PRIVATE(key)() : \
130 _TF_TOKENS_INITIALIZE_SEQ( \
131 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_NOT_ARRAY, ~, seq) \
132 _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
133 { \
134 _TF_TOKENS_ASSIGN_ARRAY_SEQ( \
135 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_ARRAY, ~, seq)) \
136 _TF_TOKENS_BUILD_ALLTOKENS_VECTOR( \
137 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_NOT_ARRAY, ~, seq) \
138 _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
139 } \
140 _TF_TOKENS_DECLARE_MEMBERS(seq) \
141 }; \
142 } \
143 static TfStaticData<_TF_TOKENS_STRUCT_NAME_PRIVATE(key)> key
144
146// Private Macros
147
148// Private macro to generate struct name from key.
149//
150// Note that this needs to be a unique struct name for each translation unit.
151//
152#define _TF_TOKENS_STRUCT_NAME_PRIVATE(key) \
153 BOOST_PP_CAT(key, _PrivateStaticTokenType)
154
155// Private macro to generate struct name from key. This version is used
156// by the public token declarations, and so key must be unique for the entire
157// namespace.
158//
159#define _TF_TOKENS_STRUCT_NAME(key) \
160 BOOST_PP_CAT(key, _StaticTokenType)
161
163// Declaration Macros
164
165// Private macro used to generate TfToken member variables. elem can either
166// be a tuple on the form (name, value) or just a name.
167//
168#define _TF_TOKENS_DECLARE_MEMBER(r, data, elem) \
169 TfToken BOOST_PP_IIF(TF_PP_IS_TUPLE(elem), \
170 BOOST_PP_TUPLE_ELEM(2, 0, elem), elem) \
171 BOOST_PP_EXPR_IIF(TF_PP_IS_TUPLE(BOOST_PP_TUPLE_ELEM(2, 1, elem)), \
172 [BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(1, 0, \
173 BOOST_PP_TUPLE_ELEM(2, 1, elem)))]);
174
175// Private macro used to declare the list of members as TfTokens
176//
177#define _TF_TOKENS_DECLARE_MEMBERS(seq) \
178 BOOST_PP_SEQ_FOR_EACH(_TF_TOKENS_DECLARE_MEMBER, ~, \
179 seq _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
180 std::vector<TfToken> allTokens;
181
182// Private macro that expands all array elements to make them members
183// of the sequence.
184//
185#define _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq) \
186 BOOST_PP_SEQ_FOR_EACH(_TF_TOKENS_APPEND_ARRAY_ELEMENTS, \
187 ~, \
188 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_ARRAY, ~, seq)) \
189
190// Private macro used to generate a struct of TfTokens.
191//
192#define _TF_DECLARE_TOKENS3(key, seq, eiapi) \
193 struct _TF_TOKENS_STRUCT_NAME(key) { \
194 eiapi _TF_TOKENS_STRUCT_NAME(key)(); \
195 eiapi ~_TF_TOKENS_STRUCT_NAME(key)(); \
196 _TF_TOKENS_DECLARE_MEMBERS(seq) \
197 };
198
199#define _TF_DECLARE_TOKENS2(key, seq) \
200 struct _TF_TOKENS_STRUCT_NAME(key) { \
201 _TF_TOKENS_STRUCT_NAME(key)(); \
202 ~_TF_TOKENS_STRUCT_NAME(key)(); \
203 _TF_TOKENS_DECLARE_MEMBERS(seq) \
204 };
205
207// Definition Macros
208
209// Private macros to define members in the tokens struct.
210//
211#define _TF_TOKENS_DEFINE_MEMBER(r, data, i, elem) \
212 BOOST_PP_COMMA_IF(i) \
213 BOOST_PP_TUPLE_ELEM(1, 0, BOOST_PP_IIF(TF_PP_IS_TUPLE(elem), \
214 (_TF_TOKENS_INITIALIZE_MEMBER_TUPLE(elem)), \
215 (_TF_TOKENS_INITIALIZE_MEMBER(elem))))
216
217#define _TF_TOKENS_INITIALIZE_MEMBER_TUPLE(elem) \
218 BOOST_PP_TUPLE_ELEM(2, 0, elem)(BOOST_PP_TUPLE_ELEM(2, 1, elem), \
219 TfToken::Immortal) \
220
221#define _TF_TOKENS_INITIALIZE_MEMBER(elem) \
222 elem(TF_PP_STRINGIZE(elem), TfToken::Immortal)
223
224#define _TF_TOKENS_DEFINE_ARRAY_MEMBER(r, data, i, elem) \
225 data[i] = BOOST_PP_IIF(TF_PP_IS_TUPLE(elem), \
226 BOOST_PP_TUPLE_ELEM(2, 0, elem), elem);
227
228// Private macros to append tokens to the allTokens vector.
229//
230#define _TF_TOKENS_APPEND_MEMBER(r, data, i, elem) \
231 BOOST_PP_IIF(TF_PP_IS_TUPLE(elem), \
232 _TF_TOKENS_APPEND_MEMBER_BODY(~, ~, \
233 BOOST_PP_TUPLE_ELEM(2, 0, elem)), \
234 _TF_TOKENS_APPEND_MEMBER_BODY(~, ~, elem))
235
236#define _TF_TOKENS_APPEND_MEMBER_BODY(r, data, elem) \
237 allTokens.push_back(elem);
238
239#define _TF_TOKENS_BUILD_ALLTOKENS_VECTOR(seq) \
240 BOOST_PP_SEQ_FOR_EACH_I(_TF_TOKENS_APPEND_MEMBER, ~, seq)
241
242// Private macros to generate the list of initialized members.
243//
244#define _TF_TOKENS_INITIALIZE_SEQ(seq) \
245 BOOST_PP_SEQ_FOR_EACH_I(_TF_TOKENS_DEFINE_MEMBER, ~, seq)
246
247#define _TF_TOKENS_ASSIGN_ARRAY_SEQ(seq) \
248 BOOST_PP_SEQ_FOR_EACH(_TF_TOKENS_DEFINE_ARRAY_MEMBERS, ~, seq)
249
250#define _TF_TOKENS_DEFINE_ARRAY_MEMBERS(r, data, elem) \
251 BOOST_PP_SEQ_FOR_EACH_I(_TF_TOKENS_DEFINE_ARRAY_MEMBER, \
252 BOOST_PP_TUPLE_ELEM(2, 0, elem), \
253 BOOST_PP_TUPLE_ELEM(1, 0, BOOST_PP_TUPLE_ELEM(2, 1, elem)))
254
255// Private predicate macros to be used by SEQ_FILTER that determine if an
256// element of a sequence is an array of tokens or not.
257//
258#define _TF_TOKENS_IS_ARRAY(s, data, elem) \
259 BOOST_PP_AND(TF_PP_IS_TUPLE(elem), \
260 TF_PP_IS_TUPLE(BOOST_PP_TUPLE_ELEM(2, 1, elem)))
261
262#define _TF_TOKENS_IS_NOT_ARRAY(s, data, elem) \
263 BOOST_PP_NOT(_TF_TOKENS_IS_ARRAY(s, data, elem))
264
265// Private macro to append all array elements to a sequence.
266//
267#define _TF_TOKENS_APPEND_ARRAY_ELEMENTS(r, data, elem) \
268 BOOST_PP_TUPLE_ELEM(1, 0, BOOST_PP_TUPLE_ELEM(2, 1, elem))
269
270// Private macro to define the struct of tokens.
271//
272// This works by filtering the incoming seq in two ways. For the body of the
273// constructor, only array tokens are passed through (because they can't be
274// initialized via initializer lists). The initializer list's items are all
275// non-array seq elements _plus_ all array members themshelves. This way,
276// array tokens are also accessible without using [] which proved to be
277// a neat shortcut.
278//
279#define _TF_DEFINE_TOKENS(key, seq) \
280 _TF_TOKENS_STRUCT_NAME(key)::~_TF_TOKENS_STRUCT_NAME(key)() = default; \
281 _TF_TOKENS_STRUCT_NAME(key)::_TF_TOKENS_STRUCT_NAME(key)() : \
282 _TF_TOKENS_INITIALIZE_SEQ( \
283 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_NOT_ARRAY, ~, seq) \
284 _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
285 { \
286 _TF_TOKENS_ASSIGN_ARRAY_SEQ( \
287 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_ARRAY, ~, seq)) \
288 _TF_TOKENS_BUILD_ALLTOKENS_VECTOR( \
289 BOOST_PP_SEQ_FILTER(_TF_TOKENS_IS_NOT_ARRAY, ~, seq) \
290 _TF_TOKENS_EXPAND_ARRAY_ELEMENTS(seq)) \
291 }
292
293PXR_NAMESPACE_CLOSE_SCOPE
294
295#endif // PXR_BASE_TF_STATIC_TOKENS_H
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...