7#ifndef PXR_EXEC_ESF_FIXED_SIZE_POLYMORPHIC_HOLDER_H
8#define PXR_EXEC_ESF_FIXED_SIZE_POLYMORPHIC_HOLDER_H
14#include "pxr/exec/esf/api.h"
24PXR_NAMESPACE_OPEN_SCOPE
37 template <
class Base,
size_t BufferSize>
47 ESF_API
virtual void _CopyTo(std::byte *storage)
const;
56 ESF_API
virtual void _MoveTo(std::byte *storage);
76template <
class Base,
size_t BufferSize = sizeof(Base)>
79 static_assert(std::is_base_of_v<EsfFixedSizePolymorphicBase, Base>);
80 constexpr static size_t _REQUIRED_ALIGNMENT =
alignof(Base);
98 template <
class Derived,
class... Args>
100 std::in_place_type_t<Derived> derivedTypeHint, Args &&...args);
106 other->_CopyTo(_storage);
116 other->_MoveTo(_storage);
132 if (
this != &other) {
134 other->_CopyTo(_storage);
147 if (
this != &other) {
149 other->_MoveTo(_storage);
160 return reinterpret_cast<Base *
>(_storage);
163 inline const Base *Get()
const {
164 return reinterpret_cast<const Base *
>(_storage);
167 inline Base *operator->() {
171 inline const Base *operator->()
const {
175 inline Base &operator*() {
179 inline const Base &operator*()
const {
192 template <
class Derived>
193 constexpr static bool FITS_IN_BUFFER =
sizeof(Derived) <= BufferSize;
195 template <
class Derived>
196 constexpr static bool DERIVES_FROM_BASE =
197 std::is_base_of_v<Base, Derived>;
199 template <
class Derived>
200 constexpr static bool HAS_ALIGNMENT =
201 alignof(Derived) == _REQUIRED_ALIGNMENT;
209 template <
class Derived>
215 template <
class Derived>
216 class _Holder :
public Derived
220 template <
class... Args>
221 _Holder(Args &&...args) : Derived(
std::forward<Args>(args)...) {
226 void _CopyTo(std::byte *storage)
const final {
227 const Derived *thisDerived =
static_cast<const Derived *
>(
this);
228 ::new (
static_cast<void *
>(storage)) _Holder<Derived>(*thisDerived);
231 void _MoveTo(std::byte *storage)
final {
232 Derived *thisDerived =
static_cast<Derived *
>(
this);
233 ::new (
static_cast<void *
>(storage)) _Holder<Derived>(
234 std::move(*thisDerived));
239 alignas(_REQUIRED_ALIGNMENT) std::byte _storage[BufferSize];
242template <
class Base,
size_t BufferSize>
243template <
class Derived,
class... Args>
245 std::in_place_type_t<Derived> derivedTypeHint, Args &&...args)
250 Compatibility::template FITS_IN_BUFFER<Derived>,
251 "The size of the derived type is larger than the availble "
254 Compatibility::template DERIVES_FROM_BASE<Derived>,
255 "Derived is not a derived class of Base.");
257 Compatibility::template HAS_ALIGNMENT<Derived>,
258 "The derived type has incompatible alignment.");
260 ::new (
static_cast<void *
>(_storage)) _Holder<Derived>(
261 std::forward<Args>(args)...);
264template <
class Base,
size_t BufferSize>
265template <
class Derived>
270 if constexpr (!DERIVES_FROM_BASE<Derived>) {
274 const Base *base =
static_cast<const Base *
>(&derived);
275 const void *baseAddress =
static_cast<const void *
>(base);
276 const void *derivedAddress =
static_cast<const void *
>(&derived);
277 return baseAddress == derivedAddress;
280PXR_NAMESPACE_CLOSE_SCOPE
Enables a base class to be used with EsfFixedSizePolymorphicHolder.
Stores polymorphic objects in a fixed-size buffer.
This & operator=(const This &other)
Construct a new instance that is copy-constructed from the instance in another holder.
EsfFixedSizePolymorphicHolder(const This &other)
Construct a holder containing a derived type instance that is copy- constructed from another holder.
This & operator=(This &&other)
Construct a new instance that is move-constructed from the instance in another holder.
EsfFixedSizePolymorphicHolder(This &&other)
Construct a holder containing a derived type that is move-constructed from another holder.
EsfFixedSizePolymorphicHolder()=delete
The default constructor is deleted because instances must always contain a derived object.
~EsfFixedSizePolymorphicHolder()
Destroys the derived instance held by this object.
Stripped down version of diagnostic.h that doesn't define std::string.
#define TF_AXIOM(cond)
Aborts if the condition cond is not met.
#define TF_UNUSED(x)
Stops compiler from producing unused argument or variable warnings.
Checks if instances of Derived can be stored in this holder.
static bool HasBaseAtSameAddress(const Derived &derived)
Verifies that a Derived instance has the same address as its Base.
A file containing basic constants and definitions.