• 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_TYPE_TRAITS_H_
6 #define INCLUDE_CPPGC_TYPE_TRAITS_H_
7 
8 // This file should stay with minimal dependencies to allow embedder to check
9 // against Oilpan types without including any other parts.
10 #include <cstddef>
11 #include <type_traits>
12 
13 namespace cppgc {
14 
15 class Visitor;
16 
17 namespace internal {
18 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
19           typename CheckingPolicy>
20 class BasicMember;
21 struct DijkstraWriteBarrierPolicy;
22 struct NoWriteBarrierPolicy;
23 class StrongMemberTag;
24 class UntracedMemberTag;
25 class WeakMemberTag;
26 
27 // Not supposed to be specialized by the user.
28 template <typename T>
29 struct IsWeak : std::false_type {};
30 
31 // IsTraceMethodConst is used to verify that all Trace methods are marked as
32 // const. It is equivalent to IsTraceable but for a non-const object.
33 template <typename T, typename = void>
34 struct IsTraceMethodConst : std::false_type {};
35 
36 template <typename T>
37 struct IsTraceMethodConst<T, std::void_t<decltype(std::declval<const T>().Trace(
38                                  std::declval<Visitor*>()))>> : std::true_type {
39 };
40 
41 template <typename T, typename = void>
42 struct IsTraceable : std::false_type {
43   static_assert(sizeof(T), "T must be fully defined");
44 };
45 
46 template <typename T>
47 struct IsTraceable<
48     T, std::void_t<decltype(std::declval<T>().Trace(std::declval<Visitor*>()))>>
49     : std::true_type {
50   // All Trace methods should be marked as const. If an object of type
51   // 'T' is traceable then any object of type 'const T' should also
52   // be traceable.
53   static_assert(IsTraceMethodConst<T>(),
54                 "Trace methods should be marked as const.");
55 };
56 
57 template <typename T>
58 constexpr bool IsTraceableV = IsTraceable<T>::value;
59 
60 template <typename T, typename = void>
61 struct HasGarbageCollectedMixinTypeMarker : std::false_type {
62   static_assert(sizeof(T), "T must be fully defined");
63 };
64 
65 template <typename T>
66 struct HasGarbageCollectedMixinTypeMarker<
67     T, std::void_t<
68            typename std::remove_const_t<T>::IsGarbageCollectedMixinTypeMarker>>
69     : std::true_type {
70   static_assert(sizeof(T), "T must be fully defined");
71 };
72 
73 template <typename T, typename = void>
74 struct HasGarbageCollectedTypeMarker : std::false_type {
75   static_assert(sizeof(T), "T must be fully defined");
76 };
77 
78 template <typename T>
79 struct HasGarbageCollectedTypeMarker<
80     T,
81     std::void_t<typename std::remove_const_t<T>::IsGarbageCollectedTypeMarker>>
82     : std::true_type {
83   static_assert(sizeof(T), "T must be fully defined");
84 };
85 
86 template <typename T, bool = HasGarbageCollectedTypeMarker<T>::value,
87           bool = HasGarbageCollectedMixinTypeMarker<T>::value>
88 struct IsGarbageCollectedMixinType : std::false_type {
89   static_assert(sizeof(T), "T must be fully defined");
90 };
91 
92 template <typename T>
93 struct IsGarbageCollectedMixinType<T, false, true> : std::true_type {
94   static_assert(sizeof(T), "T must be fully defined");
95 };
96 
97 template <typename T, bool = HasGarbageCollectedTypeMarker<T>::value>
98 struct IsGarbageCollectedType : std::false_type {
99   static_assert(sizeof(T), "T must be fully defined");
100 };
101 
102 template <typename T>
103 struct IsGarbageCollectedType<T, true> : std::true_type {
104   static_assert(sizeof(T), "T must be fully defined");
105 };
106 
107 template <typename T>
108 struct IsGarbageCollectedOrMixinType
109     : std::integral_constant<bool, IsGarbageCollectedType<T>::value ||
110                                        IsGarbageCollectedMixinType<T>::value> {
111   static_assert(sizeof(T), "T must be fully defined");
112 };
113 
114 template <typename T, bool = (HasGarbageCollectedTypeMarker<T>::value &&
115                               HasGarbageCollectedMixinTypeMarker<T>::value)>
116 struct IsGarbageCollectedWithMixinType : std::false_type {
117   static_assert(sizeof(T), "T must be fully defined");
118 };
119 
120 template <typename T>
121 struct IsGarbageCollectedWithMixinType<T, true> : std::true_type {
122   static_assert(sizeof(T), "T must be fully defined");
123 };
124 
125 template <typename BasicMemberCandidate, typename WeaknessTag,
126           typename WriteBarrierPolicy>
127 struct IsSubclassOfBasicMemberTemplate {
128  private:
129   template <typename T, typename CheckingPolicy>
130   static std::true_type SubclassCheck(
131       BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy>*);
132   static std::false_type SubclassCheck(...);
133 
134  public:
135   static constexpr bool value =
136       decltype(SubclassCheck(std::declval<BasicMemberCandidate*>()))::value;
137 };
138 
139 template <typename T,
140           bool = IsSubclassOfBasicMemberTemplate<
141               T, StrongMemberTag, DijkstraWriteBarrierPolicy>::value>
142 struct IsMemberType : std::false_type {};
143 
144 template <typename T>
145 struct IsMemberType<T, true> : std::true_type {};
146 
147 template <typename T, bool = IsSubclassOfBasicMemberTemplate<
148                           T, WeakMemberTag, DijkstraWriteBarrierPolicy>::value>
149 struct IsWeakMemberType : std::false_type {};
150 
151 template <typename T>
152 struct IsWeakMemberType<T, true> : std::true_type {};
153 
154 template <typename T, bool = IsSubclassOfBasicMemberTemplate<
155                           T, UntracedMemberTag, NoWriteBarrierPolicy>::value>
156 struct IsUntracedMemberType : std::false_type {};
157 
158 template <typename T>
159 struct IsUntracedMemberType<T, true> : std::true_type {};
160 
161 template <typename T>
162 struct IsComplete {
163  private:
164   template <typename U, size_t = sizeof(U)>
165   static std::true_type IsSizeOfKnown(U*);
166   static std::false_type IsSizeOfKnown(...);
167 
168  public:
169   static constexpr bool value =
170       decltype(IsSizeOfKnown(std::declval<T*>()))::value;
171 };
172 
173 }  // namespace internal
174 
175 /**
176  * Value is true for types that inherit from `GarbageCollectedMixin` but not
177  * `GarbageCollected<T>` (i.e., they are free mixins), and false otherwise.
178  */
179 template <typename T>
180 constexpr bool IsGarbageCollectedMixinTypeV =
181     internal::IsGarbageCollectedMixinType<T>::value;
182 
183 /**
184  * Value is true for types that inherit from `GarbageCollected<T>`, and false
185  * otherwise.
186  */
187 template <typename T>
188 constexpr bool IsGarbageCollectedTypeV =
189     internal::IsGarbageCollectedType<T>::value;
190 
191 /**
192  * Value is true for types that inherit from either `GarbageCollected<T>` or
193  * `GarbageCollectedMixin`, and false otherwise.
194  */
195 template <typename T>
196 constexpr bool IsGarbageCollectedOrMixinTypeV =
197     internal::IsGarbageCollectedOrMixinType<T>::value;
198 
199 /**
200  * Value is true for types that inherit from `GarbageCollected<T>` and
201  * `GarbageCollectedMixin`, and false otherwise.
202  */
203 template <typename T>
204 constexpr bool IsGarbageCollectedWithMixinTypeV =
205     internal::IsGarbageCollectedWithMixinType<T>::value;
206 
207 /**
208  * Value is true for types of type `Member<T>`, and false otherwise.
209  */
210 template <typename T>
211 constexpr bool IsMemberTypeV = internal::IsMemberType<T>::value;
212 
213 /**
214  * Value is true for types of type `UntracedMember<T>`, and false otherwise.
215  */
216 template <typename T>
217 constexpr bool IsUntracedMemberTypeV = internal::IsUntracedMemberType<T>::value;
218 
219 /**
220  * Value is true for types of type `WeakMember<T>`, and false otherwise.
221  */
222 template <typename T>
223 constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType<T>::value;
224 
225 /**
226  * Value is true for types that are considered weak references, and false
227  * otherwise.
228  */
229 template <typename T>
230 constexpr bool IsWeakV = internal::IsWeak<T>::value;
231 
232 /**
233  * Value is true for types that are complete, and false otherwise.
234  */
235 template <typename T>
236 constexpr bool IsCompleteV = internal::IsComplete<T>::value;
237 
238 }  // namespace cppgc
239 
240 #endif  // INCLUDE_CPPGC_TYPE_TRAITS_H_
241