Loading...
Searching...
No Matches
visitValue.h
1//
2// Copyright 2022 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_VT_VISIT_VALUE_H
8#define PXR_BASE_VT_VISIT_VALUE_H
9
10#include "pxr/pxr.h"
11
12#include "pxr/base/vt/value.h"
13
14PXR_NAMESPACE_OPEN_SCOPE
15
16namespace Vt_ValueVisitDetail {
17
18// These two overloads do SFINAE to detect whether the visitor can be invoked
19// with the given held type T. If the visitor cannot be invoked with T, it is
20// instead invoked with the VtValue itself. We use the int/long trick and pass
21// 0 in the caller to disambiguate in case both are viable.
22template <class T, class Visitor, class ...Args>
23auto
24Visit(VtValue const &val, Visitor &&visitor, int, Args &&...args) ->
25 decltype(std::forward<Visitor>(visitor)(
26 val.UncheckedGet<T>(), std::forward<Args>(args)...))
27{
28 return std::forward<Visitor>(visitor)(
29 val.UncheckedGet<T>(), std::forward<Args>(args)...);
30}
31
32template <class T, class Visitor, class ...Args>
33auto
34Visit(VtValue const &val, Visitor &&visitor, long, Args &&...args) {
35 return std::forward<Visitor>(visitor)(val, std::forward<Args>(args)...);
36}
37
38} // Vt_ValueVisitDetail
39
40
108template <class Visitor, class ...Args>
109auto VtVisitValue(VtValue const &value, Visitor &&visitor, Args&&...args)
110{
111 // This generally gets the compiler to emit a jump table to dispatch
112 // directly to the code for each known value type.
113 switch (value.GetKnownValueTypeIndex()) {
114
115// Cases for known types.
116#define VT_CASE_FOR_TYPE_INDEX(unused, elem) \
117 case VtGetKnownValueTypeIndex<VT_TYPE(elem)>(): \
118 return Vt_ValueVisitDetail::Visit<VT_TYPE(elem)>( \
119 value, std::forward<Visitor>(visitor), 0, \
120 std::forward<Args>(args)...); \
121 break;
122VT_FOR_EACH_VALUE_TYPE(VT_CASE_FOR_TYPE_INDEX)
123#undef VT_CASE_FOR_TYPE_INDEX
124
125 default:
126 // Invoke visitor with value itself.
127 return Vt_ValueVisitDetail::Visit<VtValue>(
128 value, std::forward<Visitor>(visitor), 0,
129 std::forward<Args>(args)...);
130 break;
131 };
132}
133
182template <
183 template <class T, class ...> class Visitor,
184 typename ...TypeArgs,
185 typename ...FnArgs
186 >
187auto VtVisitValueType(VtValue const &value, FnArgs&&...args)
188{
189 // This generally gets the compiler to emit a jump table to dispatch
190 // directly to the code for each known value type.
191 switch (value.GetKnownValueTypeIndex()) {
192
193// Cases for known types.
194#define VT_CASE_FOR_TYPE_INDEX(unused, elem) \
195 case VtGetKnownValueTypeIndex<VT_TYPE(elem)>(): \
196 return Visitor<VT_TYPE(elem), TypeArgs...>::Visit( \
197 std::forward<FnArgs>(args)...); \
198 break;
199VT_FOR_EACH_VALUE_TYPE(VT_CASE_FOR_TYPE_INDEX)
200#undef VT_CASE_FOR_TYPE_INDEX
201
202 default:
203 // Invoke visitor with VtValue itself.
204 return Visitor<VtValue, TypeArgs...>::Visit(
205 std::forward<FnArgs>(args)...);
206 };
207}
208
237template <
238 template <class T, template <class...> class, class ...> class Visitor,
239 template <class...> class Tmpl,
240 typename ...TypeArgs,
241 typename ...FnArgs
242 >
243auto VtVisitValueType(VtValue const &value, FnArgs&&...args)
244{
245 // This generally gets the compiler to emit a jump table to dispatch
246 // directly to the code for each known value type.
247 switch (value.GetKnownValueTypeIndex()) {
248
249// Cases for known types.
250#define VT_CASE_FOR_TYPE_INDEX(unused, elem) \
251 case VtGetKnownValueTypeIndex<VT_TYPE(elem)>(): \
252 return Visitor<VT_TYPE(elem), Tmpl, TypeArgs...>::Visit( \
253 std::forward<FnArgs>(args)...); \
254 break;
255VT_FOR_EACH_VALUE_TYPE(VT_CASE_FOR_TYPE_INDEX)
256#undef VT_CASE_FOR_TYPE_INDEX
257
258 default:
259 // Invoke visitor with VtValue itself.
260 return Visitor<VtValue, Tmpl, TypeArgs...>::Visit(
261 std::forward<FnArgs>(args)...);
262 };
263}
264
265PXR_NAMESPACE_CLOSE_SCOPE
266
267#endif // PXR_BASE_VT_VISIT_VALUE_H
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:90
int GetKnownValueTypeIndex() const
Return VtKnownValueTypeIndex<T> for the held type T.
Definition: value.h:1034