HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
traits.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 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_TRAITS_H
8 #define PXR_BASE_VT_TRAITS_H
9 
10 /// \file vt/traits.h
11 
12 #include "pxr/pxr.h"
13 #include "pxr/base/vt/api.h"
15 
16 #include <type_traits>
17 
19 
20 /// A trait to detect instantiations of VtArray, specialized in array.h.
21 template <typename T>
22 struct VtIsArray : public std::false_type {};
23 
24 /// A trait to detect instantiations of VtArrayEdit, specialized in arrayEdit.h
25 template <typename T>
26 struct VtIsArrayEdit : public std::false_type {};
27 
28 // We attempt to use local storage if a given type will fit and if it has a
29 // cheap copy operation. By default we only treat types with trivial
30 // assignments as "cheap to copy". Typically types that would fit in local
31 // space but do not have a trivial assignment are not cheap to copy. E.g. std::
32 // containers. Clients can specialize this template for their own types that
33 // aren't trivially assignable but are cheap to copy to enable local storage.
34 template <class T>
35 struct VtValueTypeHasCheapCopy : std::is_trivially_copy_assignable<T> {};
36 
37 #define VT_TYPE_IS_CHEAP_TO_COPY(T) \
38  template <> struct VtValueTypeHasCheapCopy<TF_PP_EAT_PARENS(T)> \
39  : std::true_type {}
40 
41 // VtValue supports two kinds of "value proxy":
42 //
43 // 1. Typed proxies, where given a proxy type P, we can determine the underlying
44 // proxied type at compile-time.
45 //
46 // 2. Erased proxies, where we cannot know the underlying proxied type at
47 // compile-time.
48 //
49 // Typed proxies are mostly useful from a performance standpoint, where you can
50 // produce a VtValue that holds an object that is not stored in its own storage
51 // area. That is, you can make a VtValue that points at an object you own
52 // rather than copying/swapping/moving it to the VtValue.
53 //
54 // To implement a Typed proxy, either have it derive VtTypedValueProxyBase or
55 // specialize the VtIsTypedValueProxy class template (possibly by way of the
56 // VT_TYPE_IS_TYPED_VALUE_PROXY macro). Then provide an implementation of
57 // VtGetProxiedObject that accepts `TypedProxy const &` and returns a const
58 // lvalue reference to the underlying proxied type. That reference must be
59 // valid so long as the YourProxyType argument reference is valid. Like:
60 //
61 // ProxiedType const &VtGetProxiedObject(TypedProxy const &);
62 //
63 // Erased proxies are mostly useful to enable producing VtValues holding
64 // "deferred" values; values whose types are not yet loaded in the process. For
65 // example, this can be used to produce VtValues holding objects whose types are
66 // provided in plugins that are not yet loaded. When a real object instance is
67 // required, VtValue will call `VtGetErasedProxiedVtValue(YourErasedProxy const
68 // &)` which must return a pointer to a VtValue holding the underlying proxied
69 // type. This can be manufactured "on-the-fly" (with affordances for
70 // thread-safety).
71 //
72 // To implement an Erased proxy, either have it derive VtErasedValueProxyBase or
73 // specialize the VtIsErasedValueProxy class template (possibly by way of the
74 // VT_TYPE_IS_ERASED_VALUE_PROXY macro). Then provide implementations of:
75 //
76 // bool VtErasedProxyHoldsType(ErasedProxy const &, std::type_info const &);
77 // TfType VtGetErasedProxiedTfType(ErasedProxy const &);
78 // VtValue const *VtGetErasedProxiedVtValue(ErasedProxy const &);
79 //
80 // The pointer returned by VtGetErasedProxiedVtValue must be valid as long as
81 // the ErasedProxy argument reference is valid.
82 //
83 // A note on Equality Comparisons. If a proxy type provides equality
84 // comparison, then two VtValues that hold the same proxy types will invoke that
85 // equality comparison when compared. Otherwise, the underlying proxied objects
86 // will be compared. This is beneficial when equality can be checked without
87 // having to actually instantiate the proxied object (for proxies that load &
88 // construct the proxied object lazily).
89 
90 // Clients may derive VtTypedValueProxyBase, specialize VtIsTypedValueProxy,
91 // or use the VT_TYPE_IS_TYPED_VALUE_PROXY macro to indicate their type is a
92 // VtValue proxy type.
94 template <class T>
95 struct VtIsTypedValueProxy : std::is_base_of<VtTypedValueProxyBase, T> {};
96 #define VT_TYPE_IS_TYPED_VALUE_PROXY(T) \
97  template <> struct VtIsTypedValueProxy<TF_PP_EAT_PARENS(T)> \
98  : std::true_type {}
99 
100 // Base implementation for VtGetProxiedObject (for non-proxy types).
101 template <class T,
102  typename std::enable_if<
104 T const &
105 VtGetProxiedObject(T const &nonProxy) {
106  return nonProxy;
107 }
108 
109 // Metafunction to determine the proxied type for a typed proxy.
110 template <class T>
112 {
113  using type = typename std::decay<
114  decltype(VtGetProxiedObject(std::declval<T>()))>::type;
115 };
116 
117 // Clients may derive VtErasedValueProxyBase, specialize VtIsErasedValueProxy,
118 // or use the VT_TYPE_IS_ERASED_VALUE_PROXY macro to indicate their type is a
119 // VtValue proxy type.
121 template <class T>
122 struct VtIsErasedValueProxy : std::is_base_of<VtErasedValueProxyBase, T> {};
123 #define VT_TYPE_IS_ERASED_VALUE_PROXY(T) \
124  template <> struct VtIsErasedValueProxy<TF_PP_EAT_PARENS(T)> \
125  : std::true_type {}
126 
127 // Metafunction to determine whether or not a given type T is a value proxy
128 // (either typed or type-erased).
129 template <class T>
131  std::integral_constant<
132  bool, VtIsTypedValueProxy<T>::value || VtIsErasedValueProxy<T>::value> {};
133 
134 /// A trait indicating whether VtValue compose-over functionality can be
135 /// registered for a type.
136 template <class T>
137 struct VtValueTypeCanCompose : std::false_type {};
138 
139 /// A helper for specializing the above trait.
140 #define VT_VALUE_TYPE_CAN_COMPOSE(T) \
141  template <> struct VtValueTypeCanCompose<TF_PP_EAT_PARENS(T)> \
142  : std::true_type {};
143 
144 /// A trait indicating whether VtValue transform functionality can be registered
145 /// for a type.
146 template <class T>
147 struct VtValueTypeCanTransform : std::false_type {};
148 
149 /// A helper for specializing the above trait.
150 #define VT_VALUE_TYPE_CAN_TRANSFORM(T) \
151  template <> struct VtValueTypeCanTransform<TF_PP_EAT_PARENS(T)> \
152  : std::true_type {};
153 
155 
156 #endif // PXR_BASE_VT_TRAITS_H
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
T const & VtGetProxiedObject(T const &nonProxy)
Definition: traits.h:105
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
typename std::decay< decltype(VtGetProxiedObject(std::declval< T >()))>::type type
Definition: traits.h:114
A trait to detect instantiations of VtArray, specialized in array.h.
Definition: traits.h:22
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
A trait to detect instantiations of VtArrayEdit, specialized in arrayEdit.h.
Definition: traits.h:26