123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- /*
- * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/Traits.h>
- #include <AK/Types.h>
- namespace JS {
- template<typename T>
- class GCPtr;
- template<typename T>
- class NonnullGCPtr {
- public:
- NonnullGCPtr() = delete;
- NonnullGCPtr(T& ptr)
- : m_ptr(&ptr)
- {
- }
- template<typename U>
- NonnullGCPtr(U& ptr)
- requires(IsConvertible<U*, T*>)
- : m_ptr(&static_cast<T&>(ptr))
- {
- }
- template<typename U>
- NonnullGCPtr(NonnullGCPtr<U> const& other)
- requires(IsConvertible<U*, T*>)
- : m_ptr(other.ptr())
- {
- }
- template<typename U>
- NonnullGCPtr& operator=(NonnullGCPtr<U> const& other)
- requires(IsConvertible<U*, T*>)
- {
- m_ptr = static_cast<T*>(other.ptr());
- return *this;
- }
- NonnullGCPtr& operator=(T& other)
- {
- m_ptr = &other;
- return *this;
- }
- template<typename U>
- NonnullGCPtr& operator=(U& other)
- requires(IsConvertible<U*, T*>)
- {
- m_ptr = &static_cast<T&>(other);
- return *this;
- }
- RETURNS_NONNULL T* operator->() const { return m_ptr; }
- T& operator*() const { return *m_ptr; }
- RETURNS_NONNULL T* ptr() const { return m_ptr; }
- RETURNS_NONNULL operator T*() const { return m_ptr; }
- operator T&() const { return *m_ptr; }
- private:
- T* m_ptr { nullptr };
- };
- template<typename T>
- class GCPtr {
- public:
- constexpr GCPtr() = default;
- GCPtr(T& ptr)
- : m_ptr(&ptr)
- {
- }
- GCPtr(T* ptr)
- : m_ptr(ptr)
- {
- }
- template<typename U>
- GCPtr(GCPtr<U> const& other)
- requires(IsConvertible<U*, T*>)
- : m_ptr(other.ptr())
- {
- }
- GCPtr(NonnullGCPtr<T> const& other)
- : m_ptr(other.ptr())
- {
- }
- template<typename U>
- GCPtr(NonnullGCPtr<U> const& other)
- requires(IsConvertible<U*, T*>)
- : m_ptr(other.ptr())
- {
- }
- GCPtr(nullptr_t)
- : m_ptr(nullptr)
- {
- }
- template<typename U>
- GCPtr& operator=(GCPtr<U> const& other)
- requires(IsConvertible<U*, T*>)
- {
- m_ptr = static_cast<T*>(other.ptr());
- return *this;
- }
- GCPtr& operator=(NonnullGCPtr<T> const& other)
- {
- m_ptr = other.ptr();
- return *this;
- }
- template<typename U>
- GCPtr& operator=(NonnullGCPtr<U> const& other)
- requires(IsConvertible<U*, T*>)
- {
- m_ptr = static_cast<T*>(other.ptr());
- return *this;
- }
- GCPtr& operator=(T& other)
- {
- m_ptr = &other;
- return *this;
- }
- template<typename U>
- GCPtr& operator=(U& other)
- requires(IsConvertible<U*, T*>)
- {
- m_ptr = &static_cast<T&>(other);
- return *this;
- }
- GCPtr& operator=(T* other)
- {
- m_ptr = other;
- return *this;
- }
- template<typename U>
- GCPtr& operator=(U* other)
- requires(IsConvertible<U*, T*>)
- {
- m_ptr = static_cast<T*>(other);
- return *this;
- }
- T* operator->() const
- {
- VERIFY(m_ptr);
- return m_ptr;
- }
- T& operator*() const
- {
- VERIFY(m_ptr);
- return *m_ptr;
- }
- T* ptr() const { return m_ptr; }
- operator bool() const { return !!m_ptr; }
- bool operator!() const { return !m_ptr; }
- operator T*() const { return m_ptr; }
- private:
- T* m_ptr { nullptr };
- };
- template<typename T, typename U>
- inline bool operator==(GCPtr<T> const& a, GCPtr<U> const& b)
- {
- return a.ptr() == b.ptr();
- }
- template<typename T, typename U>
- inline bool operator==(GCPtr<T> const& a, NonnullGCPtr<U> const& b)
- {
- return a.ptr() == b.ptr();
- }
- template<typename T, typename U>
- inline bool operator==(NonnullGCPtr<T> const& a, NonnullGCPtr<U> const& b)
- {
- return a.ptr() == b.ptr();
- }
- template<typename T, typename U>
- inline bool operator==(NonnullGCPtr<T> const& a, GCPtr<U> const& b)
- {
- return a.ptr() == b.ptr();
- }
- }
- namespace AK {
- template<typename T>
- struct Traits<JS::GCPtr<T>> : public DefaultTraits<JS::GCPtr<T>> {
- static unsigned hash(JS::GCPtr<T> const& value)
- {
- return Traits<T*>::hash(value.ptr());
- }
- };
- template<typename T>
- struct Traits<JS::NonnullGCPtr<T>> : public DefaultTraits<JS::NonnullGCPtr<T>> {
- static unsigned hash(JS::NonnullGCPtr<T> const& value)
- {
- return Traits<T*>::hash(value.ptr());
- }
- };
- }
|