v8  10.1.124 (node 18.2.0)
V8 is Google's open source JavaScript engine
finalizer-trait.h
Go to the documentation of this file.
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>
22  T, void_t<decltype(std::declval<T>().FinalizeGarbageCollectedObject())>>
23  : std::true_type {};
24 
25 // The FinalizerTraitImpl specifies how to finalize objects.
26 template <typename T, bool isFinalized>
27 struct FinalizerTraitImpl;
28 
29 template <typename T>
30 struct FinalizerTraitImpl<T, true> {
31  private:
32  // Dispatch to custom FinalizeGarbageCollectedObject().
33  struct Custom {
34  static void Call(void* obj) {
35  static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
36  }
37  };
38 
39  // Dispatch to regular destructor.
40  struct Destructor {
41  static void Call(void* obj) { static_cast<T*>(obj)->~T(); }
42  };
43 
44  using FinalizeImpl =
45  std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value, Custom,
46  Destructor>;
47 
48  public:
49  static void Finalize(void* obj) {
50  static_assert(sizeof(T), "T must be fully defined");
51  FinalizeImpl::Call(obj);
52  }
53 };
54 
55 template <typename T>
56 struct FinalizerTraitImpl<T, false> {
57  static void Finalize(void* obj) {
58  static_assert(sizeof(T), "T must be fully defined");
59  }
60 };
61 
62 // The FinalizerTrait is used to determine if a type requires finalization and
63 // what finalization means.
64 template <typename T>
66  private:
67  // Object has a finalizer if it has
68  // - a custom FinalizeGarbageCollectedObject method, or
69  // - a destructor.
70  static constexpr bool kNonTrivialFinalizer =
72  !std::is_trivially_destructible<typename std::remove_cv<T>::type>::value;
73 
74  static void Finalize(void* obj) {
75  internal::FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj);
76  }
77 
78  public:
79  static constexpr bool HasFinalizer() { return kNonTrivialFinalizer; }
80 
81  // The callback used to finalize an object of type T.
82  static constexpr FinalizationCallback kCallback =
83  kNonTrivialFinalizer ? Finalize : nullptr;
84 };
85 
86 template <typename T>
87 constexpr FinalizationCallback FinalizerTrait<T>::kCallback;
88 
89 } // namespace internal
90 } // namespace cppgc
91 
92 #endif // INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_