Loading...
Searching...
No Matches
fixedSizeHolder.h
1//
2// Copyright 2025 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_EXEC_VDF_FIXED_SIZE_HOLDER_H
8#define PXR_EXEC_VDF_FIXED_SIZE_HOLDER_H
9
10#include "pxr/pxr.h"
11
14
15#include <memory>
16#include <type_traits>
17#include <utility>
18
19PXR_NAMESPACE_OPEN_SCOPE
20
21// Storage class used when T is too big to fit in Vdf_FixedSizeHolder's Size.
22// It is mutable and therefore it makes deep copies.
23template <typename T>
24class Vdf_FixedSizeHolderRemoteStorage
25{
26public:
27 Vdf_FixedSizeHolderRemoteStorage() {
28 TfAutoMallocTag tag("Vdf", "Vdf_FixedSizeHolder::ctor",
29 __ARCH_PRETTY_FUNCTION__);
30 _pointer.reset(new T);
31 }
32
33 template <typename U>
34 explicit Vdf_FixedSizeHolderRemoteStorage(U &&value) {
35 TfAutoMallocTag tag("Vdf", "Vdf_FixedSizeHolder::ctor",
36 __ARCH_PRETTY_FUNCTION__);
37 _pointer.reset(new T(std::forward<U>(value)));
38 }
39
40 Vdf_FixedSizeHolderRemoteStorage(
41 Vdf_FixedSizeHolderRemoteStorage const &other) {
42 TfAutoMallocTag tag("Vdf", "Vdf_FixedSizeHolder::copy ctor",
43 __ARCH_PRETTY_FUNCTION__);
44 _pointer.reset(new T(other.Get()));
45 }
46 Vdf_FixedSizeHolderRemoteStorage &operator=(
47 Vdf_FixedSizeHolderRemoteStorage const &other) {
48 if (this != &other) {
49 TfAutoMallocTag tag("Vdf", "Vdf_FixedSizeHolder::assignment",
50 __ARCH_PRETTY_FUNCTION__);
51 _pointer.reset(new T(other.Get()));
52 }
53 return *this;
54 }
55
56 Vdf_FixedSizeHolderRemoteStorage(
57 Vdf_FixedSizeHolderRemoteStorage &&) = default;
58 Vdf_FixedSizeHolderRemoteStorage &operator=(
59 Vdf_FixedSizeHolderRemoteStorage &&) = default;
60
61 inline T const &Get() const {
62 return *_pointer;
63 }
64 inline T &GetMutable() {
65 return *_pointer;
66 }
67private:
68 std::unique_ptr<T> _pointer;
69};
70
71// Local storage class used when T is small enough to fit in
72// Vdf_FixedSizeHolder's Size.
73template <typename T>
74class Vdf_FixedSizeHolderLocalStorage
75{
76public:
77 Vdf_FixedSizeHolderLocalStorage() = default;
78
79 template <typename U>
80 explicit Vdf_FixedSizeHolderLocalStorage(U &&value)
81 : _value(std::forward<U>(value))
82 {}
83 inline T const &Get() const {
84 return _value;
85 }
86 inline T &GetMutable() {
87 return _value;
88 }
89private:
90 T _value;
91};
92
105template <class T, size_t Size>
107{
108 // Ensure that Size is large enough to hold remote storage even if this
109 // particular T fits into local storage.
110 static_assert(sizeof(Vdf_FixedSizeHolderRemoteStorage<int>) <= Size,
111 "Size too small to allow remote storage");
112
113 // Choose storage type based on the size of T. Local if small enough,
114 // heap if too big.
115 typedef typename std::conditional<
116 sizeof(T) <= Size,
117 Vdf_FixedSizeHolderLocalStorage<T>,
118 Vdf_FixedSizeHolderRemoteStorage<T>
119 >::type _StorageType;
120
121public:
122
123 Vdf_FixedSizeHolder() : _storage() {}
124
126 explicit Vdf_FixedSizeHolder(T const &obj) : _storage(obj)
127 {
128 }
129
131 explicit Vdf_FixedSizeHolder(T &&obj) : _storage(std::move(obj))
132 {
133 }
134
136 : _storage(other._storage)
137 {
138 }
139
141 : _storage(std::move(other._storage))
142 {
143 }
144
146 _storage.~_StorageType();
147 }
148
149 Vdf_FixedSizeHolder& operator=(const Vdf_FixedSizeHolder &other) {
150 _storage = other._storage;
151 return *this;
152 }
153
154 Vdf_FixedSizeHolder& operator=(Vdf_FixedSizeHolder &&other) {
155 _storage = std::move(other._storage);
156 return *this;
157 }
158
159 inline T const &Get() const {
160 return _storage.Get();
161 }
162
163 inline T &GetMutable() {
164 return _storage.GetMutable();
165 }
166
167 inline void Set(T const &value) {
168 _storage.GetMutable() = value;
169 }
170
171 inline void Set(T &&value) {
172 _storage.GetMutable() = std::move(value);
173 }
174
175private:
176 union {
177 _StorageType _storage;
178 char _padding[Size];
179 };
180};
181
182PXR_NAMESPACE_CLOSE_SCOPE
183
184#endif // PXR_EXEC_VDF_FIXED_SIZE_HOLDER_H
Scoped (i.e.
Definition: mallocTag.h:249
Vdf_FixedSizeHolder holds an object of type T of any size, but the sizeof(Vdf_FixedSizeHolder<T>) is ...
Define preprocessor function name macros.
STL namespace.