Loading...
Searching...
No Matches
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
28
29#include "pxr/pxr.h"
30#include "pxr/base/vt/api.h"
31#include "pxr/base/tf/preprocessorUtilsLite.h"
32
33#include <type_traits>
34
35PXR_NAMESPACE_OPEN_SCOPE
36
38template <typename T>
39struct 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.
47template <class T>
48struct 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.
106struct VtTypedValueProxyBase {};
107template <class T>
108struct 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).
114template <class T,
115 typename std::enable_if<
116 !VtIsTypedValueProxy<T>::value, int>::type = 0>
117T const &
118VtGetProxiedObject(T const &nonProxy) {
119 return nonProxy;
120}
121
122// Metafunction to determine the proxied type for a typed proxy.
123template <class T>
124struct VtGetProxiedType
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.
133struct VtErasedValueProxyBase {};
134template <class T>
135struct 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).
142template <class T>
143struct VtIsValueProxy :
144 std::integral_constant<
145 bool, VtIsTypedValueProxy<T>::value || VtIsErasedValueProxy<T>::value> {};
146
147PXR_NAMESPACE_CLOSE_SCOPE
148
149#endif // PXR_BASE_VT_TRAITS_H
Array concept. By default, types are not arrays.
Definition: traits.h:39