File indexing completed on 2025-02-22 10:42:26
0001
0002
0003
0004
0005 #ifndef INCLUDE_CPPGC_TYPE_TRAITS_H_
0006 #define INCLUDE_CPPGC_TYPE_TRAITS_H_
0007
0008
0009
0010 #include <cstddef>
0011 #include <type_traits>
0012
0013 namespace cppgc {
0014
0015 class Visitor;
0016
0017 namespace internal {
0018 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0019 typename CheckingPolicy, typename StorageType>
0020 class BasicMember;
0021 struct DijkstraWriteBarrierPolicy;
0022 struct NoWriteBarrierPolicy;
0023 class StrongMemberTag;
0024 class UntracedMemberTag;
0025 class WeakMemberTag;
0026
0027
0028 template <typename T>
0029 struct IsWeak : std::false_type {};
0030
0031
0032
0033 template <typename T, typename = void>
0034 struct IsTraceMethodConst : std::false_type {};
0035
0036 template <typename T>
0037 struct IsTraceMethodConst<T, std::void_t<decltype(std::declval<const T>().Trace(
0038 std::declval<Visitor*>()))>> : std::true_type {
0039 };
0040
0041 template <typename T, typename = void>
0042 struct IsTraceable : std::false_type {
0043 static_assert(sizeof(T), "T must be fully defined");
0044 };
0045
0046 template <typename T>
0047 struct IsTraceable<
0048 T, std::void_t<decltype(std::declval<T>().Trace(std::declval<Visitor*>()))>>
0049 : std::true_type {
0050
0051
0052
0053 static_assert(IsTraceMethodConst<T>(),
0054 "Trace methods should be marked as const.");
0055 };
0056
0057 template <typename T>
0058 constexpr bool IsTraceableV = IsTraceable<T>::value;
0059
0060 template <typename T, typename = void>
0061 struct HasGarbageCollectedMixinTypeMarker : std::false_type {
0062 static_assert(sizeof(T), "T must be fully defined");
0063 };
0064
0065 template <typename T>
0066 struct HasGarbageCollectedMixinTypeMarker<
0067 T, std::void_t<
0068 typename std::remove_const_t<T>::IsGarbageCollectedMixinTypeMarker>>
0069 : std::true_type {
0070 static_assert(sizeof(T), "T must be fully defined");
0071 };
0072
0073 template <typename T, typename = void>
0074 struct HasGarbageCollectedTypeMarker : std::false_type {
0075 static_assert(sizeof(T), "T must be fully defined");
0076 };
0077
0078 template <typename T>
0079 struct HasGarbageCollectedTypeMarker<
0080 T,
0081 std::void_t<typename std::remove_const_t<T>::IsGarbageCollectedTypeMarker>>
0082 : std::true_type {
0083 static_assert(sizeof(T), "T must be fully defined");
0084 };
0085
0086 template <typename T, bool = HasGarbageCollectedTypeMarker<T>::value,
0087 bool = HasGarbageCollectedMixinTypeMarker<T>::value>
0088 struct IsGarbageCollectedMixinType : std::false_type {
0089 static_assert(sizeof(T), "T must be fully defined");
0090 };
0091
0092 template <typename T>
0093 struct IsGarbageCollectedMixinType<T, false, true> : std::true_type {
0094 static_assert(sizeof(T), "T must be fully defined");
0095 };
0096
0097 template <typename T, bool = HasGarbageCollectedTypeMarker<T>::value>
0098 struct IsGarbageCollectedType : std::false_type {
0099 static_assert(sizeof(T), "T must be fully defined");
0100 };
0101
0102 template <typename T>
0103 struct IsGarbageCollectedType<T, true> : std::true_type {
0104 static_assert(sizeof(T), "T must be fully defined");
0105 };
0106
0107 template <typename T>
0108 struct IsGarbageCollectedOrMixinType
0109 : std::integral_constant<bool, IsGarbageCollectedType<T>::value ||
0110 IsGarbageCollectedMixinType<T>::value> {
0111 static_assert(sizeof(T), "T must be fully defined");
0112 };
0113
0114 template <typename T, bool = (HasGarbageCollectedTypeMarker<T>::value &&
0115 HasGarbageCollectedMixinTypeMarker<T>::value)>
0116 struct IsGarbageCollectedWithMixinType : std::false_type {
0117 static_assert(sizeof(T), "T must be fully defined");
0118 };
0119
0120 template <typename T>
0121 struct IsGarbageCollectedWithMixinType<T, true> : std::true_type {
0122 static_assert(sizeof(T), "T must be fully defined");
0123 };
0124
0125 template <typename BasicMemberCandidate, typename WeaknessTag,
0126 typename WriteBarrierPolicy>
0127 struct IsSubclassOfBasicMemberTemplate {
0128 private:
0129 template <typename T, typename CheckingPolicy, typename StorageType>
0130 static std::true_type SubclassCheck(
0131 const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
0132 StorageType>*);
0133 static std::false_type SubclassCheck(...);
0134
0135 public:
0136 static constexpr bool value = decltype(SubclassCheck(
0137 std::declval<std::decay_t<BasicMemberCandidate>*>()))::value;
0138 };
0139
0140 template <typename T,
0141 bool = IsSubclassOfBasicMemberTemplate<
0142 T, StrongMemberTag, DijkstraWriteBarrierPolicy>::value>
0143 struct IsMemberType : std::false_type {};
0144
0145 template <typename T>
0146 struct IsMemberType<T, true> : std::true_type {};
0147
0148 template <typename T, bool = IsSubclassOfBasicMemberTemplate<
0149 T, WeakMemberTag, DijkstraWriteBarrierPolicy>::value>
0150 struct IsWeakMemberType : std::false_type {};
0151
0152 template <typename T>
0153 struct IsWeakMemberType<T, true> : std::true_type {};
0154
0155 template <typename T, bool = IsSubclassOfBasicMemberTemplate<
0156 T, UntracedMemberTag, NoWriteBarrierPolicy>::value>
0157 struct IsUntracedMemberType : std::false_type {};
0158
0159 template <typename T>
0160 struct IsUntracedMemberType<T, true> : std::true_type {};
0161
0162 template <typename T>
0163 struct IsComplete {
0164 private:
0165 template <typename U, size_t = sizeof(U)>
0166 static std::true_type IsSizeOfKnown(U*);
0167 static std::false_type IsSizeOfKnown(...);
0168
0169 public:
0170 static constexpr bool value =
0171 decltype(IsSizeOfKnown(std::declval<T*>()))::value;
0172 };
0173
0174 template <typename T, typename U>
0175 constexpr bool IsDecayedSameV =
0176 std::is_same_v<std::decay_t<T>, std::decay_t<U>>;
0177
0178 template <typename B, typename D>
0179 constexpr bool IsStrictlyBaseOfV =
0180 std::is_base_of_v<std::decay_t<B>, std::decay_t<D>> &&
0181 !IsDecayedSameV<B, D>;
0182
0183 template <typename T>
0184 constexpr bool IsAnyMemberTypeV = false;
0185
0186 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0187 typename CheckingPolicy, typename StorageType>
0188 constexpr bool IsAnyMemberTypeV<internal::BasicMember<
0189 T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy, StorageType>> = true;
0190
0191 }
0192
0193
0194
0195
0196
0197 template <typename T>
0198 constexpr bool IsGarbageCollectedMixinTypeV =
0199 internal::IsGarbageCollectedMixinType<T>::value;
0200
0201
0202
0203
0204
0205 template <typename T>
0206 constexpr bool IsGarbageCollectedTypeV =
0207 internal::IsGarbageCollectedType<T>::value;
0208
0209
0210
0211
0212
0213 template <typename T>
0214 constexpr bool IsGarbageCollectedOrMixinTypeV =
0215 internal::IsGarbageCollectedOrMixinType<T>::value;
0216
0217
0218
0219
0220
0221 template <typename T>
0222 constexpr bool IsGarbageCollectedWithMixinTypeV =
0223 internal::IsGarbageCollectedWithMixinType<T>::value;
0224
0225
0226
0227
0228 template <typename T>
0229 constexpr bool IsMemberTypeV = internal::IsMemberType<T>::value;
0230
0231
0232
0233
0234 template <typename T>
0235 constexpr bool IsUntracedMemberTypeV = internal::IsUntracedMemberType<T>::value;
0236
0237
0238
0239
0240 template <typename T>
0241 constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType<T>::value;
0242
0243
0244
0245
0246
0247 template <typename T>
0248 constexpr bool IsWeakV = internal::IsWeak<T>::value;
0249
0250
0251
0252
0253 template <typename T>
0254 constexpr bool IsCompleteV = internal::IsComplete<T>::value;
0255
0256
0257
0258
0259 template <typename T>
0260 constexpr bool IsMemberOrWeakMemberTypeV =
0261 IsMemberTypeV<T> || IsWeakMemberTypeV<T>;
0262
0263
0264
0265
0266 template <typename T>
0267 constexpr bool IsAnyMemberTypeV = internal::IsAnyMemberTypeV<std::decay_t<T>>;
0268
0269 }
0270
0271 #endif