summaryrefslogtreecommitdiff
path: root/chromium/v8/include/cppgc/type-traits.h
blob: 693c4fb87235a869d7e851d5c4081f9d6a8576fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef INCLUDE_CPPGC_TYPE_TRAITS_H_
#define INCLUDE_CPPGC_TYPE_TRAITS_H_

// This file should stay with minimal dependencies to allow embedder to check
// against Oilpan types without including any other parts.
#include <cstddef>
#include <type_traits>

namespace cppgc {

class Visitor;

namespace internal {
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
          typename CheckingPolicy>
class BasicMember;
struct DijkstraWriteBarrierPolicy;
struct NoWriteBarrierPolicy;
class StrongMemberTag;
class UntracedMemberTag;
class WeakMemberTag;

// Not supposed to be specialized by the user.
template <typename T>
struct IsWeak : std::false_type {};

// IsTraceMethodConst is used to verify that all Trace methods are marked as
// const. It is equivalent to IsTraceable but for a non-const object.
template <typename T, typename = void>
struct IsTraceMethodConst : std::false_type {};

template <typename T>
struct IsTraceMethodConst<T, std::void_t<decltype(std::declval<const T>().Trace(
                                 std::declval<Visitor*>()))>> : std::true_type {
};

template <typename T, typename = void>
struct IsTraceable : std::false_type {
//  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T>
struct IsTraceable<
    T, std::void_t<decltype(std::declval<T>().Trace(std::declval<Visitor*>()))>>
    : std::true_type {
  // All Trace methods should be marked as const. If an object of type
  // 'T' is traceable then any object of type 'const T' should also
  // be traceable.
  static_assert(IsTraceMethodConst<T>(),
                "Trace methods should be marked as const.");
};

template <typename T>
constexpr bool IsTraceableV = IsTraceable<T>::value;

template <typename T, typename = void>
struct HasGarbageCollectedMixinTypeMarker : std::false_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T>
struct HasGarbageCollectedMixinTypeMarker<
    T, std::void_t<
           typename std::remove_const_t<T>::IsGarbageCollectedMixinTypeMarker>>
    : std::true_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T, typename = void>
struct HasGarbageCollectedTypeMarker : std::false_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T>
struct HasGarbageCollectedTypeMarker<
    T,
    std::void_t<typename std::remove_const_t<T>::IsGarbageCollectedTypeMarker>>
    : std::true_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T, bool = HasGarbageCollectedTypeMarker<T>::value,
          bool = HasGarbageCollectedMixinTypeMarker<T>::value>
struct IsGarbageCollectedMixinType : std::false_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T>
struct IsGarbageCollectedMixinType<T, false, true> : std::true_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T, bool = HasGarbageCollectedTypeMarker<T>::value>
struct IsGarbageCollectedType : std::false_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T>
struct IsGarbageCollectedType<T, true> : std::true_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T>
struct IsGarbageCollectedOrMixinType
    : std::integral_constant<bool, IsGarbageCollectedType<T>::value ||
                                       IsGarbageCollectedMixinType<T>::value> {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T, bool = (HasGarbageCollectedTypeMarker<T>::value &&
                              HasGarbageCollectedMixinTypeMarker<T>::value)>
struct IsGarbageCollectedWithMixinType : std::false_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename T>
struct IsGarbageCollectedWithMixinType<T, true> : std::true_type {
  static_assert(sizeof(T), "T must be fully defined");
};

template <typename BasicMemberCandidate, typename WeaknessTag,
          typename WriteBarrierPolicy>
struct IsSubclassOfBasicMemberTemplate {
 private:
  template <typename T, typename CheckingPolicy>
  static std::true_type SubclassCheck(
      BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy>*);
  static std::false_type SubclassCheck(...);

 public:
  static constexpr bool value =
      decltype(SubclassCheck(std::declval<BasicMemberCandidate*>()))::value;
};

template <typename T,
          bool = IsSubclassOfBasicMemberTemplate<
              T, StrongMemberTag, DijkstraWriteBarrierPolicy>::value>
struct IsMemberType : std::false_type {};

template <typename T>
struct IsMemberType<T, true> : std::true_type {};

template <typename T, bool = IsSubclassOfBasicMemberTemplate<
                          T, WeakMemberTag, DijkstraWriteBarrierPolicy>::value>
struct IsWeakMemberType : std::false_type {};

template <typename T>
struct IsWeakMemberType<T, true> : std::true_type {};

template <typename T, bool = IsSubclassOfBasicMemberTemplate<
                          T, UntracedMemberTag, NoWriteBarrierPolicy>::value>
struct IsUntracedMemberType : std::false_type {};

template <typename T>
struct IsUntracedMemberType<T, true> : std::true_type {};

template <typename T>
struct IsComplete {
 private:
  template <typename U, size_t = sizeof(U)>
  static std::true_type IsSizeOfKnown(U*);
  static std::false_type IsSizeOfKnown(...);

 public:
  static constexpr bool value =
      decltype(IsSizeOfKnown(std::declval<T*>()))::value;
};

template <typename T, typename U>
constexpr bool IsDecayedSameV =
    std::is_same_v<std::decay_t<T>, std::decay_t<U>>;

template <typename B, typename D>
constexpr bool IsStrictlyBaseOfV =
    std::is_base_of_v<std::decay_t<B>, std::decay_t<D>> &&
    !IsDecayedSameV<B, D>;

}  // namespace internal

/**
 * Value is true for types that inherit from `GarbageCollectedMixin` but not
 * `GarbageCollected<T>` (i.e., they are free mixins), and false otherwise.
 */
template <typename T>
constexpr bool IsGarbageCollectedMixinTypeV =
    internal::IsGarbageCollectedMixinType<T>::value;

/**
 * Value is true for types that inherit from `GarbageCollected<T>`, and false
 * otherwise.
 */
template <typename T>
constexpr bool IsGarbageCollectedTypeV =
    internal::IsGarbageCollectedType<T>::value;

/**
 * Value is true for types that inherit from either `GarbageCollected<T>` or
 * `GarbageCollectedMixin`, and false otherwise.
 */
template <typename T>
constexpr bool IsGarbageCollectedOrMixinTypeV =
    internal::IsGarbageCollectedOrMixinType<T>::value;

/**
 * Value is true for types that inherit from `GarbageCollected<T>` and
 * `GarbageCollectedMixin`, and false otherwise.
 */
template <typename T>
constexpr bool IsGarbageCollectedWithMixinTypeV =
    internal::IsGarbageCollectedWithMixinType<T>::value;

/**
 * Value is true for types of type `Member<T>`, and false otherwise.
 */
template <typename T>
constexpr bool IsMemberTypeV = internal::IsMemberType<T>::value;

/**
 * Value is true for types of type `UntracedMember<T>`, and false otherwise.
 */
template <typename T>
constexpr bool IsUntracedMemberTypeV = internal::IsUntracedMemberType<T>::value;

/**
 * Value is true for types of type `WeakMember<T>`, and false otherwise.
 */
template <typename T>
constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType<T>::value;

/**
 * Value is true for types that are considered weak references, and false
 * otherwise.
 */
template <typename T>
constexpr bool IsWeakV = internal::IsWeak<T>::value;

/**
 * Value is true for types that are complete, and false otherwise.
 */
template <typename T>
constexpr bool IsCompleteV = internal::IsComplete<T>::value;

}  // namespace cppgc

#endif  // INCLUDE_CPPGC_TYPE_TRAITS_H_