/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: SOO.hpp Date: 2023-1-18 Author: Reece Note: ~~removed~~ Recovered and fixed up: 2023-3-21 ***/ #pragma once namespace ___soodetail { template static void _reconstruct(T &ref) { new (&ref) T(); } } #if defined(_AUROXTL_INTERFACE_SOO_FORCE_NO_STRING) #define _AUROXTL_INTERFACE_SOO_TYPE2NAME(Type) "" #else #define _AUROXTL_INTERFACE_SOO_TYPE2NAME(Type) #Type #endif #define _AUROXTL_INTERRFACE_SOO_THIS(FullType) (reinterpret_cast(this)) #define _AUROXTL_INTERRFACE_SOO_EMITTER_0(a) AU_EMIT_FIRST a AU_EMIT_SECOND a #define _AUROXTL_INTERRFACE_SOO_EMITTER_1(a) , AU_EMIT_FIRST a AU_EMIT_SECOND a #define _AUROXTL_INTERRFACE_SOO_EMITTER_2(a) AU_EMIT_SECOND a #define _AUROXTL_INTERRFACE_SOO_EMITTER_3(a) , AU_EMIT_SECOND a #if !defined(_ZAUFE_FE_1_FIRST) #define _ZAUFE_FE_1_FIRST(...) #endif #define AUROXTL_INTERFACE_SOO_HDR_(vis, type, maxSize, ...) \ protected: \ char padding[maxSize] {}; \ inline type(std::nullptr_t) \ {} \ public: \ static const AuUInt kSSOPaddedSize = maxSize; \ static const AuUInt kSSORealSize; \ vis type(AU_FOR_EACH_FIRST(_AUROXTL_INTERRFACE_SOO_EMITTER_0, _AUROXTL_INTERRFACE_SOO_EMITTER_1, ## __VA_ARGS__, (AuUInt32, uSOOSize = kSSOPaddedSize)));\ vis ~type(); #define AUROXTL_INTERFACE_SOO_HDR_EX2(vis, Type, extends, targetSize, ex, ...) \ struct AU_ALIGN(sizeof(AuUInt)) Type ## SOO \ { \ AU_WHAT ex \ AUROXTL_INTERFACE_SOO_HDR_(vis, Type ## SOO, targetSize, ## __VA_ARGS__) \ inline auto operator ->() \ { \ if constexpr (std::is_const_v>) \ { \ return (const extends *)this->padding; \ \ } \ else \ { \ return ( extends *)this->padding; \ } \ } \ \ inline auto AsPointer() \ { \ if constexpr (std::is_const_v>) \ { \ return (const extends *)this->padding; \ } \ else \ { \ return (extends *)this->padding; \ } \ } \ inline auto AsUnsafeSharedPointer() \ { \ if constexpr (std::is_const_v>) \ { \ return AuUnsafeRaiiToShared((const extends *)this->padding); \ } \ else \ { \ return AuUnsafeRaiiToShared((extends *)this->padding); \ } \ } \ inline operator extends&() \ { \ return *(extends *)this->padding; \ } \ inline operator extends*() \ { \ return (extends *)this->padding; \ } \ inline operator AuSPtr() \ { \ return AuUnsafeRaiiToShared((extends *)this->padding); \ } \ inline operator const extends&() const \ { \ return *(const extends *)this->padding; \ } \ inline operator const extends*() const \ { \ return (const extends *)this->padding; \ } \ }; \ \ using Type ## SOO_t = Type ## SOO; \ using Type = Type ## SOO; #define AU_SOO_MOVE_BASIC(Type) \ inline Type(Type &&that) \ { \ AuMemcpy(this->padding, that.padding, sizeof(this->padding)); \ AuMemset(that.padding, 0, sizeof(this->padding)); \ } \ \ inline Type &operator=(Type &&that) \ { \ AuMemcpy(this->padding, that.padding, sizeof(this->padding)); \ AuMemset(that.padding, 0, sizeof(this->padding)); \ if constexpr (AuIsConstructible_v) \ { \ ___soodetail::_reconstruct(that); \ } \ return *this; \ } \ #define AU_SOO_COPY_BASIC(Type) \ inline Type(const Type &that) \ { \ AuMemcpy(this->padding, that.padding, sizeof(this->padding)); \ } \ \ inline Type &operator=(const Type &that) \ { \ AuMemcpy(this->padding, that.padding, sizeof(this->padding)); \ return *this; \ } #define _AUROXTL_INTERFACE_SOO_CC_CTOR(Type, extends) \ inline Type ## SOO(const Type ## SOO &that) \ { \ Type ## Copy((extends *)this->padding, (const extends *)that.padding); \ } \ \ inline Type ## SOO &operator=(const Type ## SOO &that) \ { \ Type ## Copy((extends *)this->padding, (const extends *)that.padding); \ return *this; \ } #define AUROXTL_INTERFACE_SOO_HDR_EX(vis, Type, extends, targetSize, ...) \ AUROXTL_INTERFACE_SOO_HDR_EX2(vis, Type, extends, targetSize, (AU_SOO_COPY_BASIC(Type ## SOO); AU_SOO_MOVE_BASIC(Type ## SOO);), ## __VA_ARGS__) #define AUROXTL_INTERFACE_SOO_HDR_EX_NC(vis, Type, extends, targetSize, ...) \ AUROXTL_INTERFACE_SOO_HDR_EX2(vis, Type, extends, targetSize, (AU_NO_COPY(Type ## SOO); AU_SOO_MOVE_BASIC(Type ## SOO);), ## __VA_ARGS__) #define AUROXTL_INTERFACE_SOO_HDR_EX_CC(vis, Type, extends, targetSize, ...) \ vis void Type ## Copy(extends *dest, const extends *source); \ AUROXTL_INTERFACE_SOO_HDR_EX2(vis, Type, extends, targetSize, (_AUROXTL_INTERFACE_SOO_CC_CTOR(Type, extends); AU_SOO_MOVE_BASIC(Type ## SOO);), ## __VA_ARGS__) #define AUROXTL_INTERFACE_SOO_HDR_EX_CCNM(vis, Type, extends, targetSize, ...) \ vis void Type ## Copy(extends *dest, const extends *source); \ AUROXTL_INTERFACE_SOO_HDR_EX2(vis, Type, extends, targetSize, (_AUROXTL_INTERFACE_SOO_CC_CTOR(Type, extends); AU_NO_MOVE(Type ## SOO);), ## __VA_ARGS__) #define AUROXTL_INTERFACE_SOO_HDR_EX_NCM(vis, Type, extends, targetSize, ...) \ AUROXTL_INTERFACE_SOO_HDR_EX2(vis, Type, extends, targetSize, (AU_NO_COPY_NO_MOVE(Type ## SOO)), ## __VA_ARGS__) #define AUROXTL_INTERFACE_SOO_HDR(Type, extends, targetSize, ...) \ AUROXTL_INTERFACE_SOO_HDR_EX(, Type, extends, targetSize, ## __VA_ARGS__) #define AUROXTL_INTERFACE_SOO_SRC_EX(vis, Type, FullType, ...) \ vis Type ## SOO::Type ## SOO(AU_FOR_EACH_FIRST(_AUROXTL_INTERRFACE_SOO_EMITTER_0, _AUROXTL_INTERRFACE_SOO_EMITTER_1, ## __VA_ARGS__, (AuUInt32, uSize))) \ { \ if (kSSORealSize > uSize) \ { \ AuMemoryPanic("SOO out of overhead: " \ _AUROXTL_INTERFACE_SOO_TYPE2NAME(Type)); \ } \ \ { \ new (_AUROXTL_INTERRFACE_SOO_THIS(FullType)) FullType(AU_FOR_EACH_FIRST(_AUROXTL_INTERRFACE_SOO_EMITTER_2, _AUROXTL_INTERRFACE_SOO_EMITTER_3, ## __VA_ARGS__)); \ } \ } \ \ vis Type ## SOO::~ Type ## SOO() \ { \ _AUROXTL_INTERRFACE_SOO_THIS(FullType)->~FullType(); \ } \ const AuUInt Type ## SOO::kSSORealSize = sizeof(FullType); #define AUROXTL_INTERFACE_SOO_SRC(Type, FullType, ...) \ AUROXTL_INTERFACE_SOO_SRC_EX(, Type, FullType, ##__VA_ARGS__) #if !defined(AU_SHARED_API_SOO) #define AU_SHARED_API_SOO(name, size, type, ...) \ AU_SHARED_API_EX(, name, type, ##__VA_ARGS__) \ AUROXTL_INTERFACE_SOO_HDR(name, type, size) #endif #if !defined(AU_SHARED_API_SOO_2) #define AU_SHARED_API_SOO_2(name, size, type, ctr, ...) \ AU_SHARED_API_EX(, name, type, ##__VA_ARGS__) \ AUROXTL_INTERFACE_SOO_HDR(name, type, size, AU_WHAT ctr) #endif