Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 10:08:49

0001 // Copyright 2020 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
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 // The FinalizerTraitImpl specifies how to finalize objects.
0027 template <typename T, bool isFinalized>
0028 struct FinalizerTraitImpl;
0029 
0030 template <typename T>
0031 struct FinalizerTraitImpl<T, true> {
0032  private:
0033   // Dispatch to custom FinalizeGarbageCollectedObject().
0034   struct Custom {
0035     static void Call(void* obj) {
0036       static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
0037     }
0038   };
0039 
0040   // Dispatch to regular destructor.
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 // The FinalizerTrait is used to determine if a type requires finalization and
0064 // what finalization means.
0065 template <typename T>
0066 struct FinalizerTrait {
0067  private:
0068   // Object has a finalizer if it has
0069   // - a custom FinalizeGarbageCollectedObject method, or
0070   // - a destructor.
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   // The callback used to finalize an object of type T.
0083   static constexpr FinalizationCallback kCallback =
0084       kNonTrivialFinalizer ? Finalize : nullptr;
0085 };
0086 
0087 template <typename T>
0088 constexpr FinalizationCallback FinalizerTrait<T>::kCallback;
0089 
0090 }  // namespace internal
0091 }  // namespace cppgc
0092 
0093 #endif  // INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_