| | |
| | |
| | |
| |
|
| | #ifndef INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_ |
| | #define INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_ |
| |
|
| | #include <type_traits> |
| |
|
| | #include "cppgc/type-traits.h" |
| |
|
| | namespace cppgc { |
| | namespace internal { |
| |
|
| | using FinalizationCallback = void (*)(void*); |
| |
|
| | template <typename T, typename = void> |
| | struct HasFinalizeGarbageCollectedObject : std::false_type {}; |
| |
|
| | template <typename T> |
| | struct HasFinalizeGarbageCollectedObject< |
| | T, void_t<decltype(std::declval<T>().FinalizeGarbageCollectedObject())>> |
| | : std::true_type {}; |
| |
|
| | |
| | template <typename T, bool isFinalized> |
| | struct FinalizerTraitImpl; |
| |
|
| | template <typename T> |
| | struct FinalizerTraitImpl<T, true> { |
| | private: |
| | |
| | struct Custom { |
| | static void Call(void* obj) { |
| | static_cast<T*>(obj)->FinalizeGarbageCollectedObject(); |
| | } |
| | }; |
| |
|
| | |
| | struct Destructor { |
| | static void Call(void* obj) { static_cast<T*>(obj)->~T(); } |
| | }; |
| |
|
| | using FinalizeImpl = |
| | std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value, Custom, |
| | Destructor>; |
| |
|
| | public: |
| | static void Finalize(void* obj) { |
| | static_assert(sizeof(T), "T must be fully defined"); |
| | FinalizeImpl::Call(obj); |
| | } |
| | }; |
| |
|
| | template <typename T> |
| | struct FinalizerTraitImpl<T, false> { |
| | static void Finalize(void* obj) { |
| | static_assert(sizeof(T), "T must be fully defined"); |
| | } |
| | }; |
| |
|
| | |
| | |
| | template <typename T> |
| | struct FinalizerTrait { |
| | private: |
| | |
| | |
| | |
| | static constexpr bool kNonTrivialFinalizer = |
| | internal::HasFinalizeGarbageCollectedObject<T>::value || |
| | !std::is_trivially_destructible<typename std::remove_cv<T>::type>::value; |
| |
|
| | static void Finalize(void* obj) { |
| | internal::FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj); |
| | } |
| |
|
| | public: |
| | |
| | static constexpr FinalizationCallback kCallback = |
| | kNonTrivialFinalizer ? Finalize : nullptr; |
| | }; |
| |
|
| | template <typename T> |
| | constexpr FinalizationCallback FinalizerTrait<T>::kCallback; |
| |
|
| | } |
| | } |
| |
|
| | #endif |
| |
|