Loading...
Searching...
No Matches
fixedSizePolymorphicHolder.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_POLYMORPHIC_HOLDER_H
8#define PXR_EXEC_VDF_FIXED_SIZE_POLYMORPHIC_HOLDER_H
9
10#include "pxr/pxr.h"
11
12#include "pxr/base/arch/defines.h"
15
16#include <utility>
17#include <type_traits>
18
19PXR_NAMESPACE_OPEN_SCOPE
20
35template <class Base, size_t BufferSize>
37{
38 static_assert(std::is_polymorphic<Base>::value, "");
39
40 // The storage used to contain instances.
41 using _Storage = typename std::aligned_storage_t<BufferSize, sizeof(void *)>;
42
43public:
44
45 // Noncopyable.
47 Vdf_FixedSizePolymorphicHolder const &) = delete;
49 operator=(Vdf_FixedSizePolymorphicHolder const &) = delete;
50
52
58 template <class Derived, class ... Args>
59 void New(Args && ... args) {
60 static_assert(
61 std::is_base_of<Base, Derived>::value,
62 "Derived is not a derived class of Base.");
63 static_assert(
64 sizeof(Derived) <= sizeof(_Storage),
65 "The size of the derived type is larger than the availble storage.");
66 static_assert(
67 alignof(_Storage) % alignof(Derived) == 0,
68 "The derived type has incompatible alignment.");
69 new (_GetStorage()) Derived(std::forward<Args>(args)...);
70 // Verification that Base and Derived start at the same address.
71 // Perhaps this can be done at compile-time?
72 void *const bStart =
73 static_cast<Base *>(static_cast<Derived *>(_GetStorage()));
74 TF_AXIOM(bStart == _GetStorage());
75 }
76
81 void Destroy() {
82#if defined(ARCH_COMPILER_GCC) && ARCH_COMPILER_GCC_MAJOR < 11
83 ARCH_PRAGMA_PUSH
84 ARCH_PRAGMA_MAYBE_UNINITIALIZED
85#endif
86 Get()->~Base();
87#if defined(ARCH_COMPILER_GCC) && ARCH_COMPILER_GCC_MAJOR < 11
88 ARCH_PRAGMA_POP
89#endif
90 }
91
93 inline Base const *Get() const {
94 return static_cast<Base const *>(_GetStorage());
95 }
96
98 inline Base *Get() {
99 return static_cast<Base *>(_GetStorage());
100 }
101
102private:
103
104 // Returns a pointer to the instance storage space.
105 inline void *_GetStorage() {
106 return &_storage;
107 }
108
109 // Returns a pointer to the instance storage space.
110 inline void const *_GetStorage() const {
111 return &_storage;
112 }
113
114
115 //
116 // Data Members
117 //
118
119 _Storage _storage;
120};
121
122PXR_NAMESPACE_CLOSE_SCOPE
123
124#endif
Used to implement small object optimizations for the type-erasure (Any) pattern.
Base * Get()
Returns a Base pointer to the held instance.
void New(Args &&... args)
Creates an instance.
void Destroy()
Destroys a held instance.
Base const * Get() const
Returns a Base pointer to the held instance.
Stripped down version of diagnostic.h that doesn't define std::string.
#define TF_AXIOM(cond)
Aborts if the condition cond is not met.
Definition: diagnostic.h:193
Pragmas for controlling compiler-specific behaviors.