• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_
6 #define INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_
7 
8 #include <type_traits>
9 
10 #include "cppgc/type-traits.h"
11 
12 namespace cppgc {
13 namespace internal {
14 
15 using FinalizationCallback = void (*)(void*);
16 
17 template <typename T, typename = void>
18 struct HasFinalizeGarbageCollectedObject : std::false_type {};
19 
20 template <typename T>
21 struct HasFinalizeGarbageCollectedObject<
22     T,
23     std::void_t<decltype(std::declval<T>().FinalizeGarbageCollectedObject())>>
24     : std::true_type {};
25 
26 // The FinalizerTraitImpl specifies how to finalize objects.
27 template <typename T, bool isFinalized>
28 struct FinalizerTraitImpl;
29 
30 template <typename T>
31 struct FinalizerTraitImpl<T, true> {
32  private:
33   // Dispatch to custom FinalizeGarbageCollectedObject().
34   struct Custom {
35     static void Call(void* obj) {
36       static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
37     }
38   };
39 
40   // Dispatch to regular destructor.
41   struct Destructor {
42     static void Call(void* obj) { static_cast<T*>(obj)->~T(); }
43   };
44 
45   using FinalizeImpl =
46       std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value, Custom,
47                          Destructor>;
48 
49  public:
50   static void Finalize(void* obj) {
51     static_assert(sizeof(T), "T must be fully defined");
52     FinalizeImpl::Call(obj);
53   }
54 };
55 
56 template <typename T>
57 struct FinalizerTraitImpl<T, false> {
58   static void Finalize(void* obj) {
59     static_assert(sizeof(T), "T must be fully defined");
60   }
61 };
62 
63 // The FinalizerTrait is used to determine if a type requires finalization and
64 // what finalization means.
65 template <typename T>
66 struct FinalizerTrait {
67  private:
68   // Object has a finalizer if it has
69   // - a custom FinalizeGarbageCollectedObject method, or
70   // - a destructor.
71   static constexpr bool kNonTrivialFinalizer =
72       internal::HasFinalizeGarbageCollectedObject<T>::value ||
73       !std::is_trivially_destructible<typename std::remove_cv<T>::type>::value;
74 
75   static void Finalize(void* obj) {
76     internal::FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj);
77   }
78 
79  public:
80   static constexpr bool HasFinalizer() { return kNonTrivialFinalizer; }
81 
82   // The callback used to finalize an object of type T.
83   static constexpr FinalizationCallback kCallback =
84       kNonTrivialFinalizer ? Finalize : nullptr;
85 };
86 
87 template <typename T>
88 constexpr FinalizationCallback FinalizerTrait<T>::kCallback;
89 
90 }  // namespace internal
91 }  // namespace cppgc
92 
93 #endif  // INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_
94