Handle.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Badge.h>
  8. #include <AK/IntrusiveList.h>
  9. #include <AK/Noncopyable.h>
  10. #include <AK/RefCounted.h>
  11. #include <AK/RefPtr.h>
  12. #include <LibJS/Forward.h>
  13. #include <LibJS/Runtime/Value.h>
  14. namespace JS {
  15. class HandleImpl : public RefCounted<HandleImpl> {
  16. AK_MAKE_NONCOPYABLE(HandleImpl);
  17. AK_MAKE_NONMOVABLE(HandleImpl);
  18. public:
  19. ~HandleImpl();
  20. Cell* cell() { return m_cell; }
  21. Cell const* cell() const { return m_cell; }
  22. private:
  23. template<class T>
  24. friend class Handle;
  25. explicit HandleImpl(Cell*);
  26. GCPtr<Cell> m_cell;
  27. IntrusiveListNode<HandleImpl> m_list_node;
  28. public:
  29. using List = IntrusiveList<&HandleImpl::m_list_node>;
  30. };
  31. template<class T>
  32. class Handle {
  33. public:
  34. Handle() = default;
  35. static Handle create(T* cell)
  36. {
  37. return Handle(adopt_ref(*new HandleImpl(const_cast<RemoveConst<T>*>(cell))));
  38. }
  39. Handle(T* cell)
  40. {
  41. if (cell)
  42. m_impl = adopt_ref(*new HandleImpl(cell));
  43. }
  44. Handle(T& cell)
  45. : m_impl(adopt_ref(*new HandleImpl(&cell)))
  46. {
  47. }
  48. Handle(GCPtr<T> cell)
  49. : Handle(cell.ptr())
  50. {
  51. }
  52. Handle(NonnullGCPtr<T> cell)
  53. : Handle(*cell)
  54. {
  55. }
  56. T* cell() const
  57. {
  58. if (!m_impl)
  59. return nullptr;
  60. return static_cast<T*>(m_impl->cell());
  61. }
  62. T* ptr() const
  63. {
  64. return cell();
  65. }
  66. bool is_null() const
  67. {
  68. return m_impl.is_null();
  69. }
  70. T* operator->() const
  71. {
  72. return cell();
  73. }
  74. T& operator*() const
  75. {
  76. return *cell();
  77. }
  78. bool operator!() const
  79. {
  80. return !cell();
  81. }
  82. operator bool() const
  83. {
  84. return cell();
  85. }
  86. operator T*() const { return cell(); }
  87. private:
  88. explicit Handle(NonnullRefPtr<HandleImpl> impl)
  89. : m_impl(move(impl))
  90. {
  91. }
  92. RefPtr<HandleImpl> m_impl;
  93. };
  94. template<class T>
  95. inline Handle<T> make_handle(T* cell)
  96. {
  97. if (!cell)
  98. return Handle<T> {};
  99. return Handle<T>::create(cell);
  100. }
  101. template<class T>
  102. inline Handle<T> make_handle(T& cell)
  103. {
  104. return Handle<T>::create(&cell);
  105. }
  106. template<class T>
  107. inline Handle<T> make_handle(GCPtr<T> cell)
  108. {
  109. if (!cell)
  110. return Handle<T> {};
  111. return Handle<T>::create(cell.ptr());
  112. }
  113. template<class T>
  114. inline Handle<T> make_handle(NonnullGCPtr<T> cell)
  115. {
  116. return Handle<T>::create(cell.ptr());
  117. }
  118. template<>
  119. class Handle<Value> {
  120. public:
  121. Handle() = default;
  122. static Handle create(Value value)
  123. {
  124. if (value.is_cell())
  125. return Handle(value, &value.as_cell());
  126. return Handle(value);
  127. }
  128. auto cell() { return m_handle.cell(); }
  129. auto cell() const { return m_handle.cell(); }
  130. auto value() const { return *m_value; }
  131. bool is_null() const { return m_handle.is_null() && !m_value.has_value(); }
  132. private:
  133. explicit Handle(Value value)
  134. : m_value(value)
  135. {
  136. }
  137. explicit Handle(Value value, Cell* cell)
  138. : m_value(value)
  139. , m_handle(Handle<Cell>::create(cell))
  140. {
  141. }
  142. Optional<Value> m_value;
  143. Handle<Cell> m_handle;
  144. };
  145. inline Handle<Value> make_handle(Value value)
  146. {
  147. return Handle<Value>::create(value);
  148. }
  149. }