5 #ifndef INCLUDE_CPPGC_PERSISTENT_H_
6 #define INCLUDE_CPPGC_PERSISTENT_H_
10 #include "cppgc/internal/persistent-node.h"
11 #include "cppgc/internal/pointer-policies.h"
12 #include "cppgc/source-location.h"
13 #include "cppgc/type-traits.h"
14 #include "cppgc/visitor.h"
21 template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
22 typename CheckingPolicy>
23 class BasicPersistent :
public LocationPolicy,
24 private WeaknessPolicy,
25 private CheckingPolicy {
27 using typename WeaknessPolicy::IsStrongPersistent;
28 using PointeeType = T;
33 : LocationPolicy(loc) {}
37 : LocationPolicy(loc) {}
41 : LocationPolicy(loc), raw_(s) {}
46 : LocationPolicy(loc), raw_(raw) {
47 if (!IsValid())
return;
48 node_ = WeaknessPolicy::GetPersistentRegion(raw_).AllocateNode(
49 this, &BasicPersistent::Trace);
50 this->CheckPointer(
Get());
55 : BasicPersistent(&raw, loc) {}
60 : BasicPersistent(other.Get(), loc) {}
63 template <
typename U,
typename OtherWeaknessPolicy,
64 typename OtherLocationPolicy,
typename OtherCheckingPolicy,
65 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
67 const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
68 OtherCheckingPolicy>& other,
70 : BasicPersistent(other.Get(), loc) {}
75 BasicPersistent&& other,
77 : LocationPolicy(std::move(other)),
78 raw_(std::move(other.raw_)),
79 node_(std::move(other.node_)) {
80 if (!IsValid())
return;
83 other.node_ =
nullptr;
84 this->CheckPointer(
Get());
88 template <
typename U,
typename MemberBarrierPolicy,
89 typename MemberWeaknessTag,
typename MemberCheckingPolicy,
90 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
92 MemberWeaknessTag, MemberCheckingPolicy>
95 : BasicPersistent(member.Get(), loc) {}
100 BasicPersistent&
operator=(
const BasicPersistent& other) {
101 return operator=(other.Get());
104 template <
typename U,
typename OtherWeaknessPolicy,
105 typename OtherLocationPolicy,
typename OtherCheckingPolicy,
106 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
108 const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
109 OtherCheckingPolicy>& other) {
110 return operator=(other.Get());
114 BasicPersistent&
operator=(BasicPersistent&& other) {
115 if (
this == &other)
return *
this;
117 LocationPolicy::operator=(std::move(other));
118 raw_ = std::move(other.raw_);
119 node_ = std::move(other.node_);
120 if (!IsValid())
return *
this;
122 other.raw_ =
nullptr;
123 other.node_ =
nullptr;
124 this->CheckPointer(
Get());
129 template <
typename U,
typename MemberBarrierPolicy,
130 typename MemberWeaknessTag,
typename MemberCheckingPolicy,
131 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
133 internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
134 MemberCheckingPolicy>
136 return operator=(member.Get());
159 T*
Get()
const {
return raw_; }
170 static void Trace(
Visitor* v,
const void* ptr) {
171 const auto* persistent =
static_cast<
const BasicPersistent*>(ptr);
172 v->TraceRoot(*persistent, persistent->Location());
175 bool IsValid()
const {
182 void Assign(T* ptr) {
187 this->CheckPointer(ptr);
190 WeaknessPolicy::GetPersistentRegion(raw_).FreeNode(node_);
194 if (!IsValid())
return;
195 node_ = WeaknessPolicy::GetPersistentRegion(raw_).AllocateNode(
196 this, &BasicPersistent::Trace);
197 this->CheckPointer(
Get());
201 PersistentNode* node_ =
nullptr;
204 template <
typename T1,
typename WeaknessPolicy1,
typename LocationPolicy1,
205 typename CheckingPolicy1,
typename T2,
typename WeaknessPolicy2,
206 typename LocationPolicy2,
typename CheckingPolicy2>
207 bool operator==(
const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
208 CheckingPolicy1>& p1,
209 const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
210 CheckingPolicy2>& p2) {
211 return p1.Get() == p2.Get();
214 template <
typename T1,
typename WeaknessPolicy1,
typename LocationPolicy1,
215 typename CheckingPolicy1,
typename T2,
typename WeaknessPolicy2,
216 typename LocationPolicy2,
typename CheckingPolicy2>
217 bool operator!=(
const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
218 CheckingPolicy1>& p1,
219 const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
220 CheckingPolicy2>& p2) {
224 template <
typename T1,
typename PersistentWeaknessPolicy,
225 typename PersistentLocationPolicy,
typename PersistentCheckingPolicy,
226 typename T2,
typename MemberWriteBarrierPolicy,
227 typename MemberWeaknessTag,
typename MemberCheckingPolicy>
228 bool operator==(
const BasicPersistent<T1, PersistentWeaknessPolicy,
229 PersistentLocationPolicy,
230 PersistentCheckingPolicy>& p,
231 BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
232 MemberCheckingPolicy>
234 return p.Get() == m.Get();
237 template <
typename T1,
typename PersistentWeaknessPolicy,
238 typename PersistentLocationPolicy,
typename PersistentCheckingPolicy,
239 typename T2,
typename MemberWriteBarrierPolicy,
240 typename MemberWeaknessTag,
typename MemberCheckingPolicy>
241 bool operator!=(
const BasicPersistent<T1, PersistentWeaknessPolicy,
242 PersistentLocationPolicy,
243 PersistentCheckingPolicy>& p,
244 BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
245 MemberCheckingPolicy>
250 template <
typename T1,
typename MemberWriteBarrierPolicy,
251 typename MemberWeaknessTag,
typename MemberCheckingPolicy,
252 typename T2,
typename PersistentWeaknessPolicy,
253 typename PersistentLocationPolicy,
typename PersistentCheckingPolicy>
254 bool operator==(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
255 MemberCheckingPolicy>
257 const BasicPersistent<T1, PersistentWeaknessPolicy,
258 PersistentLocationPolicy,
259 PersistentCheckingPolicy>& p) {
260 return m.Get() == p.Get();
263 template <
typename T1,
typename MemberWriteBarrierPolicy,
264 typename MemberWeaknessTag,
typename MemberCheckingPolicy,
265 typename T2,
typename PersistentWeaknessPolicy,
266 typename PersistentLocationPolicy,
typename PersistentCheckingPolicy>
267 bool operator!=(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
268 MemberCheckingPolicy>
270 const BasicPersistent<T1, PersistentWeaknessPolicy,
271 PersistentLocationPolicy,
272 PersistentCheckingPolicy>& p) {
276 template <
typename T,
typename LocationPolicy,
typename CheckingPolicy>
278 CheckingPolicy>> : std::true_type {};
288 template <
typename T>
298 template <
typename T>
299 using WeakPersistent =