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