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 /// Array concept. By default, types are not arrays.
21 template <typename T>
22 struct VtIsArray : public std::false_type {};
23 
24 // We attempt to use local storage if a given type will fit and if it has a
25 // cheap copy operation. By default we only treat types with trivial
26 // assignments as "cheap to copy". Typically types that would fit in local
27 // space but do not have a trivial assignment are not cheap to copy. E.g. std::
28 // containers. Clients can specialize this template for their own types that
29 // aren't trivially assignable but are cheap to copy to enable local storage.
30 template <class T>
31 struct VtValueTypeHasCheapCopy : std::is_trivially_copy_assignable<T> {};
32 
33 #define VT_TYPE_IS_CHEAP_TO_COPY(T) \
34  template <> struct VtValueTypeHasCheapCopy<TF_PP_EAT_PARENS(T)> \
35  : std::true_type {}
36 
37 // VtValue supports two kinds of "value proxy":
38 //
39 // 1. Typed proxies, where given a proxy type P, we can determine the underlying
40 // proxied type at compile-time.
41 //
42 // 2. Erased proxies, where we cannot know the underlying proxied type at
43 // compile-time.
44 //
45 // Typed proxies are mostly useful from a performance standpoint, where you can
46 // produce a VtValue that holds an object that is not stored in its own storage
47 // area. That is, you can make a VtValue that points at an object you own
48 // rather than copying/swapping/moving it to the VtValue.
49 //
50 // To implement a Typed proxy, either have it derive VtTypedValueProxyBase or
51 // specialize the VtIsTypedValueProxy class template (possibly by way of the
52 // VT_TYPE_IS_TYPED_VALUE_PROXY macro). Then provide an implementation of
53 // VtGetProxiedObject that accepts `TypedProxy const &` and returns a const
54 // lvalue reference to the underlying proxied type. That reference must be
55 // valid so long as the YourProxyType argument reference is valid. Like:
56 //
57 // ProxiedType const &VtGetProxiedObject(TypedProxy const &);
58 //
59 // Erased proxies are mostly useful to enable producing VtValues holding
60 // "deferred" values; values whose types are not yet loaded in the process. For
61 // example, this can be used to produce VtValues holding objects whose types are
62 // provided in plugins that are not yet loaded. When a real object instance is
63 // required, VtValue will call `VtGetErasedProxiedVtValue(YourErasedProxy const
64 // &)` which must return a pointer to a VtValue holding the underlying proxied
65 // type. This can be manufactured "on-the-fly" (with affordances for
66 // thread-safety).
67 //
68 // To implement an Erased proxy, either have it derive VtErasedValueProxyBase or
69 // specialize the VtIsErasedValueProxy class template (possibly by way of the
70 // VT_TYPE_IS_ERASED_VALUE_PROXY macro). Then provide implementations of:
71 //
72 // bool VtErasedProxyHoldsType(ErasedProxy const &, std::type_info const &);
73 // TfType VtGetErasedProxiedTfType(ErasedProxy const &);
74 // VtValue const *VtGetErasedProxiedVtValue(ErasedProxy const &);
75 //
76 // The pointer returned by VtGetErasedProxiedVtValue must be valid as long as
77 // the ErasedProxy argument reference is valid.
78 //
79 // A note on Equality Comparisons. If a proxy type provides equality
80 // comparison, then two VtValues that hold the same proxy types will invoke that
81 // equality comparison when compared. Otherwise, the underlying proxied objects
82 // will be compared. This is beneficial when equality can be checked without
83 // having to actually instantiate the proxied object (for proxies that load &
84 // construct the proxied object lazily).
85 
86 // Clients may derive VtTypedValueProxyBase, specialize VtIsTypedValueProxy,
87 // or use the VT_TYPE_IS_TYPED_VALUE_PROXY macro to indicate their type is a
88 // VtValue proxy type.
90 template <class T>
91 struct VtIsTypedValueProxy : std::is_base_of<VtTypedValueProxyBase, T> {};
92 #define VT_TYPE_IS_TYPED_VALUE_PROXY(T) \
93  template <> struct VtIsTypedValueProxy<TF_PP_EAT_PARENS(T)> \
94  : std::true_type {}
95 
96 // Base implementation for VtGetProxiedObject (for non-proxy types).
97 template <class T,
98  typename std::enable_if<
100 T const &
101 VtGetProxiedObject(T const &nonProxy) {
102  return nonProxy;
103 }
104 
105 // Metafunction to determine the proxied type for a typed proxy.
106 template <class T>
108 {
109  using type = typename std::decay<
110  decltype(VtGetProxiedObject(std::declval<T>()))>::type;
111 };
112 
113 // Clients may derive VtErasedValueProxyBase, specialize VtIsErasedValueProxy,
114 // or use the VT_TYPE_IS_ERASED_VALUE_PROXY macro to indicate their type is a
115 // VtValue proxy type.
117 template <class T>
118 struct VtIsErasedValueProxy : std::is_base_of<VtErasedValueProxyBase, T> {};
119 #define VT_TYPE_IS_ERASED_VALUE_PROXY(T) \
120  template <> struct VtIsErasedValueProxy<TF_PP_EAT_PARENS(T)> \
121  : std::true_type {}
122 
123 // Metafunction to determine whether or not a given type T is a value proxy
124 // (either typed or type-erased).
125 template <class T>
127  std::integral_constant<
128  bool, VtIsTypedValueProxy<T>::value || VtIsErasedValueProxy<T>::value> {};
129 
131 
132 #endif // PXR_BASE_VT_TRAITS_H
T const & VtGetProxiedObject(T const &nonProxy)
Definition: traits.h:101
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
typename std::decay< decltype(VtGetProxiedObject(std::declval< T >()))>::type type
Definition: traits.h:110
Array concept. By default, types are not arrays.
Definition: traits.h:22
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74