Handle.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. namespace JS {
  14. class HandleImpl : public RefCounted<HandleImpl> {
  15. AK_MAKE_NONCOPYABLE(HandleImpl);
  16. AK_MAKE_NONMOVABLE(HandleImpl);
  17. public:
  18. ~HandleImpl();
  19. Cell* cell() { return m_cell; }
  20. const Cell* cell() const { return m_cell; }
  21. private:
  22. template<class T>
  23. friend class Handle;
  24. explicit HandleImpl(Cell*);
  25. Cell* m_cell { nullptr };
  26. IntrusiveListNode<HandleImpl> m_list_node;
  27. public:
  28. using List = IntrusiveList<&HandleImpl::m_list_node>;
  29. };
  30. template<class T>
  31. class Handle {
  32. public:
  33. Handle() = default;
  34. static Handle create(T* cell)
  35. {
  36. return Handle(adopt_ref(*new HandleImpl(cell)));
  37. }
  38. T* cell() { return static_cast<T*>(m_impl->cell()); }
  39. const T* cell() const { return static_cast<const T*>(m_impl->cell()); }
  40. bool is_null() const { return m_impl.is_null(); }
  41. private:
  42. explicit Handle(NonnullRefPtr<HandleImpl> impl)
  43. : m_impl(move(impl))
  44. {
  45. }
  46. RefPtr<HandleImpl> m_impl;
  47. };
  48. template<class T>
  49. inline Handle<T> make_handle(T* cell)
  50. {
  51. return Handle<T>::create(cell);
  52. }
  53. }