36#include <Ultralight/platform/Allocator.h>
43class WeakControlBlock;
92template<
typename T>
class RefPtr;
114template<
typename T,
typename... Args>
117 return AdoptRef(*
new T(std::forward<Args>(args)...));
130 template <
typename U>
friend class RefPtr;
162 : instance_(other.instance_)
173 : instance_(other.instance_)
201 T* old_value = std::move(instance_);
202 instance_ = std::forward<T*>(
nullptr);
204 old_value->Release();
210 inline T*
get()
const {
return instance_; }
218 T* result = std::move(instance_);
219 instance_ = std::forward<T*>(
nullptr);
223 T&
operator*()
const { assert(instance_);
return *instance_; }
231 explicit operator bool()
const {
return instance_ !=
nullptr; }
241 return a.instance_ == b.instance_;
245 return a.instance_ != b.instance_;
249 return a.instance_ < b.instance_;
306 T* old_instance = std::move(instance_);
307 instance_ = std::forward<T*>(
nullptr);
309 old_instance->Release();
316 RefPtr ptr = std::move(other);
325 RefPtr ptr = std::move(other);
337 std::swap(instance_, other.instance_);
346template <
class T>
class RefCountedImpl;
358class WeakControlBlock {
360 WeakControlBlock(
const WeakControlBlock&) =
delete;
361 WeakControlBlock& operator=(
const WeakControlBlock&) =
delete;
366 static void*
operator new(
size_t size) {
367 void* p = ul_malloc(size);
368 assert(p &&
"WeakControlBlock: allocation failed");
371 static void operator delete(
void* p) { ul_free(p); }
374 WeakControlBlock* WeakRef() {
382 bool should_delete_control_block =
false;
385 assert(weak_ref_count_);
386 if (!--weak_ref_count_ && !strong_ref_count_)
387 should_delete_control_block =
true;
389 if (should_delete_control_block)
394 void StrongRef()
const {
401 template <
typename T>
402 void StrongDeref()
const {
409 object =
static_cast<T*
>(object_);
419 RefCountedImpl<T>::DeleteObject(
object);
421 bool has_other_weak_refs;
424 has_other_weak_refs = --weak_ref_count_ != 0;
426 if (!has_other_weak_refs)
439 template <
typename U>
440 RefPtr<U> MakeStrongRefIfPossible(
const U* maybe_interior_pointer)
const {
446 return AdoptRef(*
const_cast<U*
>(maybe_interior_pointer));
457 bool expired()
const {
463 int ref_count()
const {
465 return static_cast<int>(strong_ref_count_);
469 int weak_ref_count()
const {
471 return static_cast<int>(weak_ref_count_);
475 template <
class T>
friend class RefCountedImpl;
477 explicit WeakControlBlock(
void*
object) : object_(object) { }
480 void set_strong_ref_count_during_init(uint32_t count) { strong_ref_count_ = count; }
483 mutable uint32_t strong_ref_count_ = 1;
484 mutable uint32_t weak_ref_count_ = 0;
485 mutable void* object_;
519 static_assert(std::is_base_of<WeakRefCounted, T>::value,
520 "WeakPtr<T> requires T to derive from WeakRefCounted");
526 constexpr WeakPtr() : instance_(nullptr), control_block_(nullptr) { }
531 WeakPtr(std::nullptr_t) : instance_(nullptr), control_block_(nullptr) { }
538 : instance_(strong.get()),
539 control_block_(strong ? strong->weak_control_block() : nullptr)
542 control_block_->WeakRef();
553 : instance_(instance),
554 control_block_(instance ? instance->weak_control_block() : nullptr)
557 control_block_->WeakRef();
564 : instance_(other.instance_),
565 control_block_(other.control_block_ ? other.control_block_->WeakRef() : nullptr)
573 : instance_(other.instance_), control_block_(other.control_block_)
575 other.instance_ =
nullptr;
576 other.control_block_ =
nullptr;
582 control_block_->WeakDeref();
594 WeakPtr ptr = std::move(other);
621 return control_block_ ? control_block_->MakeStrongRefIfPossible(instance_)
632 bool Expired()
const {
return !control_block_ || control_block_->expired(); }
640 control_block_->WeakDeref();
641 control_block_ =
nullptr;
650 std::swap(instance_, other.instance_);
651 std::swap(control_block_, other.control_block_);
659 WeakControlBlock* control_block_;
668template<
typename T,
typename U>
671 return a.
get() == b.
get();
674template<
typename T,
typename U>
680template<
typename T,
typename U>
686template<
typename T,
typename U>
689 return a.
get() != b.
get();
692template<
typename T,
typename U>
698template<
typename T,
typename U>
#define UExport
Definition Exports.h:22
#define UL_LIKELY(x)
Definition Defines.h:84
Interface for all ref-counted objects that will be managed using the RefPtr<> smart pointer.
Definition RefPtr.h:49
virtual void AddRef() const =0
Increment the reference count (thread-safe).
virtual int ref_count() const =0
Get the current reference count.
virtual WeakControlBlock * weak_control_block() const
Get the control block used to track weak references to this object.
Definition RefPtr.h:69
virtual void Release() const =0
Decrement the reference count (thread-safe).
A nullable smart pointer.
Definition RefPtr.h:126
void reset(T *obj)
Replaces the managed object with another.
Definition RefPtr.h:332
T & operator*() const
Definition RefPtr.h:223
friend class RefPtr
Definition RefPtr.h:130
constexpr RefPtr()
Construct a NULL ref-pointer.
Definition RefPtr.h:135
friend RefPtr AdoptRef(T &)
Helper for wrapping new objects with the RefPtr smart pointer.
Definition RefPtr.h:104
void swap(RefPtr &ptr)
Exchanges the stored pointer values and the ownerships of *this and ptr.
Definition RefPtr.h:335
friend bool operator==(const RefPtr &a, const RefPtr &b)
Definition RefPtr.h:240
RefPtr(T &object, AdoptTag)
Definition RefPtr.h:272
RefPtr(RefPtr &&other)
Move constructor.
Definition RefPtr.h:182
AdoptTag
Definition RefPtr.h:271
@ Adopt
Definition RefPtr.h:271
RefPtr & operator=(RefPtr< U > &&)
bool operator!() const
Definition RefPtr.h:226
RefPtr & operator=(const RefPtr &)
Definition RefPtr.h:279
friend bool operator!=(const RefPtr &a, const RefPtr &b)
Definition RefPtr.h:244
RefPtr(std::nullptr_t)
Construct a NULL ref-pointer.
Definition RefPtr.h:143
RefPtr & operator=(const RefPtr< U > &)
T * operator->() const
Definition RefPtr.h:224
RefPtr & operator=(T *)
Definition RefPtr.h:296
RefPtr(T *other)
Construct from a pointer.
Definition RefPtr.h:151
RefPtr & operator=(std::nullptr_t)
Definition RefPtr.h:304
RefPtr(const RefPtr &other)
Copy constructor.
Definition RefPtr.h:161
RefPtr(RefPtr< U > &&other)
Move constructor.
Definition RefPtr.h:191
LayoutNode * LeakRef()
Definition RefPtr.h:217
friend bool operator<(const RefPtr &a, const RefPtr &b)
Definition RefPtr.h:248
void reset()
Releases the ownership of the managed object, if any.
Definition RefPtr.h:330
~RefPtr()
Destroy RefPtr (will decrement ref-count by one).
Definition RefPtr.h:199
RefPtr & operator=(RefPtr &&)
Definition RefPtr.h:314
T * get() const
Get a pointer to wrapped object.
Definition RefPtr.h:210
RefPtr(const RefPtr< U > &other)
Copy constructor with internal type conversion.
Definition RefPtr.h:172
A weak (non-owning) smart pointer that observes a WeakRefCounted object.
Definition RefPtr.h:518
bool Expired() const
Whether the observed object has been destroyed (or this WeakPtr is null).
Definition RefPtr.h:632
~WeakPtr()
Definition RefPtr.h:579
WeakPtr & operator=(const RefPtr< U > &strong)
Definition RefPtr.h:606
RefPtr< T > Lock() const
Atomically take a strong reference to the observed object.
Definition RefPtr.h:619
WeakPtr(const WeakPtr &other)
Copy constructor.
Definition RefPtr.h:563
friend class WeakPtr
Definition RefPtr.h:521
WeakPtr(U *instance)
Construct a WeakPtr observing a raw pointer (may be null).
Definition RefPtr.h:552
void Reset()
Stop observing the object and become a null WeakPtr.
Definition RefPtr.h:637
WeakPtr(WeakPtr &&other)
Move constructor.
Definition RefPtr.h:572
WeakPtr(std::nullptr_t)
Construct a null WeakPtr.
Definition RefPtr.h:531
constexpr WeakPtr()
Construct a null WeakPtr.
Definition RefPtr.h:526
WeakPtr & operator=(std::nullptr_t)
Definition RefPtr.h:599
WeakPtr & operator=(WeakPtr &&other)
Definition RefPtr.h:592
WeakPtr & operator=(const WeakPtr &other)
Definition RefPtr.h:585
WeakPtr(const RefPtr< U > &strong)
Construct a WeakPtr observing the object held by a RefPtr (may be null).
Definition RefPtr.h:537
void swap(WeakPtr &other)
Exchanges the observed objects of *this and other.
Definition RefPtr.h:648
Interface for ref-counted objects that can additionally be observed via the WeakPtr<> smart pointer.
Definition RefPtr.h:83
virtual ~WeakRefCounted()=default
virtual WeakControlBlock * weak_control_block() const override=0
Get the control block used to track weak references to this object (never nullptr).
Root namespace for every public Ultralight type, function, and enumeration.
void swap(RefPtr< T > &a, RefPtr< T > &b)
Definition RefPtr.h:341
std::lock_guard< Lock > LockHolder
Definition Lock.h:84
RefPtr< T > AdoptRef(T &reference)
Helper for wrapping new objects with the RefPtr smart pointer.
Definition RefPtr.h:104
bool operator==(const Matrix &a, const Matrix &b)
bool operator!=(const Matrix &a, const Matrix &b)
RefPtr< T > MakeRefPtr(Args &&... args)
Construct a new object of type T and wrap it in a RefPtr.
Definition RefPtr.h:115