File indexing completed on 2025-02-23 10:08:49
0001
0002
0003
0004
0005 #ifndef INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_
0006 #define INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_
0007
0008 #include <type_traits>
0009
0010 #include "cppgc/type-traits.h"
0011
0012 namespace cppgc {
0013 namespace internal {
0014
0015 using FinalizationCallback = void (*)(void*);
0016
0017 template <typename T, typename = void>
0018 struct HasFinalizeGarbageCollectedObject : std::false_type {};
0019
0020 template <typename T>
0021 struct HasFinalizeGarbageCollectedObject<
0022 T,
0023 std::void_t<decltype(std::declval<T>().FinalizeGarbageCollectedObject())>>
0024 : std::true_type {};
0025
0026
0027 template <typename T, bool isFinalized>
0028 struct FinalizerTraitImpl;
0029
0030 template <typename T>
0031 struct FinalizerTraitImpl<T, true> {
0032 private:
0033
0034 struct Custom {
0035 static void Call(void* obj) {
0036 static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
0037 }
0038 };
0039
0040
0041 struct Destructor {
0042 static void Call(void* obj) { static_cast<T*>(obj)->~T(); }
0043 };
0044
0045 using FinalizeImpl =
0046 std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value, Custom,
0047 Destructor>;
0048
0049 public:
0050 static void Finalize(void* obj) {
0051 static_assert(sizeof(T), "T must be fully defined");
0052 FinalizeImpl::Call(obj);
0053 }
0054 };
0055
0056 template <typename T>
0057 struct FinalizerTraitImpl<T, false> {
0058 static void Finalize(void* obj) {
0059 static_assert(sizeof(T), "T must be fully defined");
0060 }
0061 };
0062
0063
0064
0065 template <typename T>
0066 struct FinalizerTrait {
0067 private:
0068
0069
0070
0071 static constexpr bool kNonTrivialFinalizer =
0072 internal::HasFinalizeGarbageCollectedObject<T>::value ||
0073 !std::is_trivially_destructible<typename std::remove_cv<T>::type>::value;
0074
0075 static void Finalize(void* obj) {
0076 internal::FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj);
0077 }
0078
0079 public:
0080 static constexpr bool HasFinalizer() { return kNonTrivialFinalizer; }
0081
0082
0083 static constexpr FinalizationCallback kCallback =
0084 kNonTrivialFinalizer ? Finalize : nullptr;
0085 };
0086
0087 template <typename T>
0088 constexpr FinalizationCallback FinalizerTrait<T>::kCallback;
0089
0090 }
0091 }
0092
0093 #endif