File indexing completed on 2025-02-22 10:42:26
0001
0002
0003
0004
0005 #ifndef INCLUDE_CPPGC_MEMBER_H_
0006 #define INCLUDE_CPPGC_MEMBER_H_
0007
0008 #include <atomic>
0009 #include <cstddef>
0010 #include <type_traits>
0011
0012 #include "cppgc/internal/api-constants.h"
0013 #include "cppgc/internal/member-storage.h"
0014 #include "cppgc/internal/pointer-policies.h"
0015 #include "cppgc/sentinel-pointer.h"
0016 #include "cppgc/type-traits.h"
0017 #include "v8config.h" // NOLINT(build/include_directory)
0018
0019 namespace cppgc {
0020
0021 namespace subtle {
0022 class HeapConsistency;
0023 }
0024
0025 class Visitor;
0026
0027 namespace internal {
0028
0029
0030
0031 template <typename StorageType>
0032 class V8_TRIVIAL_ABI MemberBase {
0033 public:
0034 using RawStorage = StorageType;
0035
0036 protected:
0037 struct AtomicInitializerTag {};
0038
0039 V8_INLINE MemberBase() = default;
0040 V8_INLINE explicit MemberBase(const void* value) : raw_(value) {}
0041 V8_INLINE MemberBase(const void* value, AtomicInitializerTag) {
0042 SetRawAtomic(value);
0043 }
0044
0045 V8_INLINE explicit MemberBase(RawStorage raw) : raw_(raw) {}
0046 V8_INLINE explicit MemberBase(std::nullptr_t) : raw_(nullptr) {}
0047 V8_INLINE explicit MemberBase(SentinelPointer s) : raw_(s) {}
0048
0049 V8_INLINE const void** GetRawSlot() const {
0050 return reinterpret_cast<const void**>(const_cast<MemberBase*>(this));
0051 }
0052 V8_INLINE const void* GetRaw() const { return raw_.Load(); }
0053 V8_INLINE void SetRaw(void* value) { raw_.Store(value); }
0054
0055 V8_INLINE const void* GetRawAtomic() const { return raw_.LoadAtomic(); }
0056 V8_INLINE void SetRawAtomic(const void* value) { raw_.StoreAtomic(value); }
0057
0058 V8_INLINE RawStorage GetRawStorage() const { return raw_; }
0059 V8_INLINE void SetRawStorageAtomic(RawStorage other) {
0060 reinterpret_cast<std::atomic<RawStorage>&>(raw_).store(
0061 other, std::memory_order_relaxed);
0062 }
0063
0064 V8_INLINE bool IsCleared() const { return raw_.IsCleared(); }
0065
0066 V8_INLINE void ClearFromGC() const { raw_.Clear(); }
0067
0068 private:
0069 friend class MemberDebugHelper;
0070
0071 mutable RawStorage raw_;
0072 };
0073
0074
0075 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0076 typename CheckingPolicy, typename StorageType>
0077 class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
0078 private CheckingPolicy {
0079 using Base = MemberBase<StorageType>;
0080
0081 public:
0082 using PointeeType = T;
0083 using RawStorage = typename Base::RawStorage;
0084
0085 V8_INLINE constexpr BasicMember() = default;
0086 V8_INLINE constexpr BasicMember(std::nullptr_t) {}
0087 V8_INLINE BasicMember(SentinelPointer s) : Base(s) {}
0088 V8_INLINE BasicMember(T* raw) : Base(raw) {
0089 InitializingWriteBarrier(raw);
0090 this->CheckPointer(Get());
0091 }
0092 V8_INLINE BasicMember(T& raw)
0093 : BasicMember(&raw) {}
0094
0095
0096
0097
0098 using AtomicInitializerTag = typename Base::AtomicInitializerTag;
0099 V8_INLINE BasicMember(std::nullptr_t, AtomicInitializerTag atomic)
0100 : Base(nullptr, atomic) {}
0101 V8_INLINE BasicMember(SentinelPointer s, AtomicInitializerTag atomic)
0102 : Base(s, atomic) {}
0103 V8_INLINE BasicMember(T* raw, AtomicInitializerTag atomic)
0104 : Base(raw, atomic) {
0105 InitializingWriteBarrier(raw);
0106 this->CheckPointer(Get());
0107 }
0108 V8_INLINE BasicMember(T& raw, AtomicInitializerTag atomic)
0109 : BasicMember(&raw, atomic) {}
0110
0111
0112 V8_INLINE BasicMember(const BasicMember& other)
0113 : BasicMember(other.GetRawStorage()) {}
0114
0115
0116
0117
0118 template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
0119 typename OtherCheckingPolicy,
0120 std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr>
0121 V8_INLINE BasicMember(
0122 const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
0123 OtherCheckingPolicy, StorageType>& other)
0124 : BasicMember(other.GetRawStorage()) {}
0125
0126 template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
0127 typename OtherCheckingPolicy,
0128 std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr>
0129 V8_INLINE BasicMember(
0130 const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
0131 OtherCheckingPolicy, StorageType>& other)
0132 : BasicMember(other.Get()) {}
0133
0134
0135 V8_INLINE BasicMember(BasicMember&& other) noexcept
0136 : BasicMember(other.GetRawStorage()) {
0137 other.Clear();
0138 }
0139
0140
0141
0142
0143 template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
0144 typename OtherCheckingPolicy,
0145 std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr>
0146 V8_INLINE BasicMember(
0147 BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
0148 StorageType>&& other) noexcept
0149 : BasicMember(other.GetRawStorage()) {
0150 other.Clear();
0151 }
0152
0153 template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
0154 typename OtherCheckingPolicy,
0155 std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr>
0156 V8_INLINE BasicMember(
0157 BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
0158 StorageType>&& other) noexcept
0159 : BasicMember(other.Get()) {
0160 other.Clear();
0161 }
0162
0163
0164 template <typename U, typename PersistentWeaknessPolicy,
0165 typename PersistentLocationPolicy,
0166 typename PersistentCheckingPolicy,
0167 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
0168 V8_INLINE BasicMember(const BasicPersistent<U, PersistentWeaknessPolicy,
0169 PersistentLocationPolicy,
0170 PersistentCheckingPolicy>& p)
0171 : BasicMember(p.Get()) {}
0172
0173
0174 V8_INLINE BasicMember& operator=(const BasicMember& other) {
0175 return operator=(other.GetRawStorage());
0176 }
0177
0178
0179
0180
0181 template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
0182 typename OtherCheckingPolicy>
0183 V8_INLINE BasicMember& operator=(
0184 const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
0185 OtherCheckingPolicy, StorageType>& other) {
0186 if constexpr (internal::IsDecayedSameV<T, U>) {
0187 return operator=(other.GetRawStorage());
0188 } else {
0189 static_assert(internal::IsStrictlyBaseOfV<T, U>);
0190 return operator=(other.Get());
0191 }
0192 }
0193
0194
0195 V8_INLINE BasicMember& operator=(BasicMember&& other) noexcept {
0196 operator=(other.GetRawStorage());
0197 other.Clear();
0198 return *this;
0199 }
0200
0201
0202
0203
0204 template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
0205 typename OtherCheckingPolicy>
0206 V8_INLINE BasicMember& operator=(
0207 BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
0208 StorageType>&& other) noexcept {
0209 if constexpr (internal::IsDecayedSameV<T, U>) {
0210 operator=(other.GetRawStorage());
0211 } else {
0212 static_assert(internal::IsStrictlyBaseOfV<T, U>);
0213 operator=(other.Get());
0214 }
0215 other.Clear();
0216 return *this;
0217 }
0218
0219
0220 template <typename U, typename PersistentWeaknessPolicy,
0221 typename PersistentLocationPolicy,
0222 typename PersistentCheckingPolicy,
0223 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
0224 V8_INLINE BasicMember& operator=(
0225 const BasicPersistent<U, PersistentWeaknessPolicy,
0226 PersistentLocationPolicy, PersistentCheckingPolicy>&
0227 other) {
0228 return operator=(other.Get());
0229 }
0230
0231 V8_INLINE BasicMember& operator=(T* other) {
0232 Base::SetRawAtomic(other);
0233 AssigningWriteBarrier(other);
0234 this->CheckPointer(Get());
0235 return *this;
0236 }
0237
0238 V8_INLINE BasicMember& operator=(std::nullptr_t) {
0239 Clear();
0240 return *this;
0241 }
0242 V8_INLINE BasicMember& operator=(SentinelPointer s) {
0243 Base::SetRawAtomic(s);
0244 return *this;
0245 }
0246
0247 template <typename OtherWeaknessTag, typename OtherBarrierPolicy,
0248 typename OtherCheckingPolicy>
0249 V8_INLINE void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy,
0250 OtherCheckingPolicy, StorageType>& other) {
0251 auto tmp = GetRawStorage();
0252 *this = other;
0253 other = tmp;
0254 }
0255
0256 V8_INLINE explicit operator bool() const { return !Base::IsCleared(); }
0257 V8_INLINE operator T*() const { return Get(); }
0258 V8_INLINE T* operator->() const { return Get(); }
0259 V8_INLINE T& operator*() const { return *Get(); }
0260
0261
0262
0263
0264 V8_INLINE V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
0265
0266
0267
0268
0269
0270 return static_cast<T*>(const_cast<void*>(Base::GetRaw()));
0271 }
0272
0273 V8_INLINE void Clear() {
0274 Base::SetRawStorageAtomic(RawStorage{});
0275 }
0276
0277 V8_INLINE T* Release() {
0278 T* result = Get();
0279 Clear();
0280 return result;
0281 }
0282
0283 V8_INLINE const T** GetSlotForTesting() const {
0284 return reinterpret_cast<const T**>(Base::GetRawSlot());
0285 }
0286
0287 V8_INLINE RawStorage GetRawStorage() const {
0288 return Base::GetRawStorage();
0289 }
0290
0291 private:
0292 V8_INLINE explicit BasicMember(RawStorage raw) : Base(raw) {
0293 InitializingWriteBarrier(Get());
0294 this->CheckPointer(Get());
0295 }
0296
0297 V8_INLINE BasicMember& operator=(RawStorage other) {
0298 Base::SetRawStorageAtomic(other);
0299 AssigningWriteBarrier();
0300 this->CheckPointer(Get());
0301 return *this;
0302 }
0303
0304 V8_INLINE const T* GetRawAtomic() const {
0305 return static_cast<const T*>(Base::GetRawAtomic());
0306 }
0307
0308 V8_INLINE void InitializingWriteBarrier(T* value) const {
0309 WriteBarrierPolicy::InitializingBarrier(Base::GetRawSlot(), value);
0310 }
0311 V8_INLINE void AssigningWriteBarrier(T* value) const {
0312 WriteBarrierPolicy::template AssigningBarrier<
0313 StorageType::kWriteBarrierSlotType>(Base::GetRawSlot(), value);
0314 }
0315 V8_INLINE void AssigningWriteBarrier() const {
0316 WriteBarrierPolicy::template AssigningBarrier<
0317 StorageType::kWriteBarrierSlotType>(Base::GetRawSlot(),
0318 Base::GetRawStorage());
0319 }
0320
0321 V8_INLINE void ClearFromGC() const { Base::ClearFromGC(); }
0322
0323 V8_INLINE T* GetFromGC() const { return Get(); }
0324
0325 friend class cppgc::subtle::HeapConsistency;
0326 friend class cppgc::Visitor;
0327 template <typename U>
0328 friend struct cppgc::TraceTrait;
0329 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
0330 typename CheckingPolicy1, typename StorageType1>
0331 friend class BasicMember;
0332 };
0333
0334
0335 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
0336 typename CheckingPolicy1, typename T2, typename WeaknessTag2,
0337 typename WriteBarrierPolicy2, typename CheckingPolicy2,
0338 typename StorageType>
0339 V8_INLINE bool operator==(
0340 const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
0341 StorageType>& member1,
0342 const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
0343 StorageType>& member2) {
0344 if constexpr (internal::IsDecayedSameV<T1, T2>) {
0345
0346 return member1.GetRawStorage() == member2.GetRawStorage();
0347 } else {
0348 static_assert(internal::IsStrictlyBaseOfV<T1, T2> ||
0349 internal::IsStrictlyBaseOfV<T2, T1>);
0350
0351 return member1.Get() == member2.Get();
0352 }
0353 }
0354
0355 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
0356 typename CheckingPolicy1, typename T2, typename WeaknessTag2,
0357 typename WriteBarrierPolicy2, typename CheckingPolicy2,
0358 typename StorageType>
0359 V8_INLINE bool operator!=(
0360 const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
0361 StorageType>& member1,
0362 const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
0363 StorageType>& member2) {
0364 return !(member1 == member2);
0365 }
0366
0367
0368 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0369 typename CheckingPolicy, typename StorageType, typename U>
0370 V8_INLINE bool operator==(
0371 const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
0372 StorageType>& member,
0373 U* raw) {
0374
0375 static_assert(!internal::IsDecayedSameV<void, U>);
0376
0377 if constexpr (internal::IsDecayedSameV<T, U>) {
0378
0379 return member.GetRawStorage() == StorageType(raw);
0380 } else if constexpr (internal::IsStrictlyBaseOfV<T, U>) {
0381
0382 return member.GetRawStorage() == StorageType(static_cast<T*>(raw));
0383 } else {
0384
0385 return member.Get() == raw;
0386 }
0387 }
0388
0389 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0390 typename CheckingPolicy, typename StorageType, typename U>
0391 V8_INLINE bool operator!=(
0392 const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
0393 StorageType>& member,
0394 U* raw) {
0395 return !(member == raw);
0396 }
0397
0398 template <typename T, typename U, typename WeaknessTag,
0399 typename WriteBarrierPolicy, typename CheckingPolicy,
0400 typename StorageType>
0401 V8_INLINE bool operator==(
0402 T* raw, const BasicMember<U, WeaknessTag, WriteBarrierPolicy,
0403 CheckingPolicy, StorageType>& member) {
0404 return member == raw;
0405 }
0406
0407 template <typename T, typename U, typename WeaknessTag,
0408 typename WriteBarrierPolicy, typename CheckingPolicy,
0409 typename StorageType>
0410 V8_INLINE bool operator!=(
0411 T* raw, const BasicMember<U, WeaknessTag, WriteBarrierPolicy,
0412 CheckingPolicy, StorageType>& member) {
0413 return !(raw == member);
0414 }
0415
0416
0417 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0418 typename CheckingPolicy, typename StorageType>
0419 V8_INLINE bool operator==(
0420 const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
0421 StorageType>& member,
0422 SentinelPointer) {
0423 return member.GetRawStorage().IsSentinel();
0424 }
0425
0426 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0427 typename CheckingPolicy, typename StorageType>
0428 V8_INLINE bool operator!=(
0429 const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
0430 StorageType>& member,
0431 SentinelPointer s) {
0432 return !(member == s);
0433 }
0434
0435 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0436 typename CheckingPolicy, typename StorageType>
0437 V8_INLINE bool operator==(
0438 SentinelPointer s, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
0439 CheckingPolicy, StorageType>& member) {
0440 return member == s;
0441 }
0442
0443 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0444 typename CheckingPolicy, typename StorageType>
0445 V8_INLINE bool operator!=(
0446 SentinelPointer s, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
0447 CheckingPolicy, StorageType>& member) {
0448 return !(s == member);
0449 }
0450
0451
0452 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0453 typename CheckingPolicy, typename StorageType>
0454 V8_INLINE bool operator==(
0455 const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
0456 StorageType>& member,
0457 std::nullptr_t) {
0458 return !static_cast<bool>(member);
0459 }
0460
0461 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0462 typename CheckingPolicy, typename StorageType>
0463 V8_INLINE bool operator!=(
0464 const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
0465 StorageType>& member,
0466 std::nullptr_t n) {
0467 return !(member == n);
0468 }
0469
0470 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0471 typename CheckingPolicy, typename StorageType>
0472 V8_INLINE bool operator==(
0473 std::nullptr_t n, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
0474 CheckingPolicy, StorageType>& member) {
0475 return member == n;
0476 }
0477
0478 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0479 typename CheckingPolicy, typename StorageType>
0480 V8_INLINE bool operator!=(
0481 std::nullptr_t n, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
0482 CheckingPolicy, StorageType>& member) {
0483 return !(n == member);
0484 }
0485
0486
0487 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
0488 typename CheckingPolicy1, typename T2, typename WeaknessTag2,
0489 typename WriteBarrierPolicy2, typename CheckingPolicy2,
0490 typename StorageType>
0491 V8_INLINE bool operator<(
0492 const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
0493 StorageType>& member1,
0494 const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
0495 StorageType>& member2) {
0496 static_assert(
0497 internal::IsDecayedSameV<T1, T2>,
0498 "Comparison works only for same pointer type modulo cv-qualifiers");
0499 return member1.GetRawStorage() < member2.GetRawStorage();
0500 }
0501
0502 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
0503 typename CheckingPolicy1, typename T2, typename WeaknessTag2,
0504 typename WriteBarrierPolicy2, typename CheckingPolicy2,
0505 typename StorageType>
0506 V8_INLINE bool operator<=(
0507 const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
0508 StorageType>& member1,
0509 const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
0510 StorageType>& member2) {
0511 static_assert(
0512 internal::IsDecayedSameV<T1, T2>,
0513 "Comparison works only for same pointer type modulo cv-qualifiers");
0514 return member1.GetRawStorage() <= member2.GetRawStorage();
0515 }
0516
0517 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
0518 typename CheckingPolicy1, typename T2, typename WeaknessTag2,
0519 typename WriteBarrierPolicy2, typename CheckingPolicy2,
0520 typename StorageType>
0521 V8_INLINE bool operator>(
0522 const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
0523 StorageType>& member1,
0524 const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
0525 StorageType>& member2) {
0526 static_assert(
0527 internal::IsDecayedSameV<T1, T2>,
0528 "Comparison works only for same pointer type modulo cv-qualifiers");
0529 return member1.GetRawStorage() > member2.GetRawStorage();
0530 }
0531
0532 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
0533 typename CheckingPolicy1, typename T2, typename WeaknessTag2,
0534 typename WriteBarrierPolicy2, typename CheckingPolicy2,
0535 typename StorageType>
0536 V8_INLINE bool operator>=(
0537 const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
0538 StorageType>& member1,
0539 const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
0540 StorageType>& member2) {
0541 static_assert(
0542 internal::IsDecayedSameV<T1, T2>,
0543 "Comparison works only for same pointer type modulo cv-qualifiers");
0544 return member1.GetRawStorage() >= member2.GetRawStorage();
0545 }
0546
0547 template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy,
0548 typename StorageType>
0549 struct IsWeak<internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy,
0550 CheckingPolicy, StorageType>>
0551 : std::true_type {};
0552
0553 }
0554
0555
0556
0557
0558
0559
0560 template <typename T>
0561 using Member = internal::BasicMember<
0562 T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
0563 internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573 template <typename T>
0574 using WeakMember = internal::BasicMember<
0575 T, internal::WeakMemberTag, internal::DijkstraWriteBarrierPolicy,
0576 internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
0577
0578
0579
0580
0581
0582
0583
0584 template <typename T>
0585 using UntracedMember = internal::BasicMember<
0586 T, internal::UntracedMemberTag, internal::NoWriteBarrierPolicy,
0587 internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
0588
0589 namespace subtle {
0590
0591
0592
0593
0594
0595 template <typename T>
0596 using UncompressedMember = internal::BasicMember<
0597 T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
0598 internal::DefaultMemberCheckingPolicy, internal::RawPointer>;
0599
0600 #if defined(CPPGC_POINTER_COMPRESSION)
0601
0602
0603
0604
0605 template <typename T>
0606 using CompressedMember = internal::BasicMember<
0607 T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
0608 internal::DefaultMemberCheckingPolicy, internal::CompressedPointer>;
0609 #endif
0610
0611 }
0612
0613 namespace internal {
0614
0615 struct Dummy;
0616
0617 static constexpr size_t kSizeOfMember = sizeof(Member<Dummy>);
0618 static constexpr size_t kSizeOfUncompressedMember =
0619 sizeof(subtle::UncompressedMember<Dummy>);
0620 #if defined(CPPGC_POINTER_COMPRESSION)
0621 static constexpr size_t kSizeofCompressedMember =
0622 sizeof(subtle::CompressedMember<Dummy>);
0623 #endif
0624
0625 }
0626
0627 }
0628
0629 #endif