[+] AU_SAFE_DESTROY utility for defining standard object destruction

This commit is contained in:
Reece Wilson 2022-07-19 15:21:35 +01:00
parent c3e01d31f8
commit f81f99f45e
3 changed files with 120 additions and 1 deletions

View File

@ -8,4 +8,4 @@
#pragma once #pragma once
#include "ClassHelpers.hpp" #include "ClassHelpers.hpp"
#include "ModuleApi.hpp" #include "ModuleApi.hpp"

View File

@ -0,0 +1,118 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: SafeDestroy.hpp
Date: 2022-07-19
Author: Reece
***/
#pragma once
namespace AuUtil
{
namespace Detail
{
template <class T>
struct AuHasDestroy
{
template <class C> static constexpr AuTrueType Test(decltype(&C::DestroyPrivate));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
struct AuHasDeconstruct
{
template <class C> static constexpr AuTrueType Test(decltype(&C::DeconstructPrivate));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
struct AuHasPreDeconstruct
{
template <class C> static constexpr AuTrueType Test(decltype(&C::PreDeconstructPrivate));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
constexpr inline bool AuHasDestroy_v = AuHasDestroy<T>::type::value;
template <class T>
constexpr inline bool AuHasDesconstruct_v = AuHasDeconstruct<T>::type::value;
template <class T>
constexpr inline bool AuHasPreDesconstruct_v = AuHasPreDeconstruct<T>::type::value;
}
#define AU_SAFE_DESTROY(type) \
public: \
virtual ~type() \
{ \
if (AuExchange(this->bDestroyCtrOnce_, true)) return; \
\
type :: _TryPreDeconstruct<type>(this); \
\
this->Destroy(); \
\
type :: _TryDeconstruct<type>(this); \
\
} \
\
inline void Destroy() \
{ \
if (AuExchange(this->bDestroyDesOnce_, true)) return; \
\
type :: _TryDeconstructPrivate<type>(this); \
} \
\
friend AuUtil::Detail::AuHasDestroy<type>; \
friend AuUtil::Detail::AuHasDeconstruct<type>; \
friend AuUtil::Detail::AuHasPreDeconstruct<type>; \
\
private: \
bool bDestroyCtrOnce_ {}; \
bool bDestroyDesOnce_ {}; \
\
template<typename T> \
static void _TryPreDeconstruct(T *that) \
{ \
if constexpr (AuUtil::Detail::AuHasPreDesconstruct_v<T>) \
{ \
that->PreDeconstructPrivate(); \
} \
} \
\
template<typename T> \
static void _TryDeconstruct(T *that) \
{ \
if constexpr (AuUtil::Detail::AuHasDesconstruct_v<T>) \
{ \
that->DeconstructPrivate(); \
} \
} \
\
template<typename T> \
static void _TryDeconstructPrivate(T *that) \
{ \
if constexpr (AuUtil::Detail::AuHasDestroy_v<T>) \
{ \
that->DestroyPrivate(); \
} \
} \
\
public:
}
/**
Defines #define AU_SAFE_DESTROY(type)
Implements safe multiple-detor, and multiple ::Destroy() call, based destructible interfaces.
Simply add AU_SAFE_DESTROY to the types body add arbitrarily add the following callback methods as needed
void DestroyPrivate(void) - Generic called once object destroy
void DeconstructPrivate(void) - Object destruction hook. Called once. Called After DestroyPrivate.
void PreDeconstructPrivate(void) - Object destruction hook. Called once. Called before DestroyPrivate.
These user defined functions may be private and/or virtual, if implemented at all.
*/

View File

@ -49,6 +49,7 @@
#include <auROXTL/auHashUtils.hpp> #include <auROXTL/auHashUtils.hpp>
#include <auROXTL/auTryConstructUtils.hpp> #include <auROXTL/auTryConstructUtils.hpp>
#include <auROXTL/Objects/SafeDestroy.hpp>
struct IAuNullDelegate struct IAuNullDelegate
{ {