MRCHelpers.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2022 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. // clang-format off
  4. #ifndef __OBJC__
  5. #error This header is for use with Objective-C++ only.
  6. #endif
  7. #if __has_feature(objc_arc)
  8. #error This file is for manual reference counting! Compile without -fobjc-arc
  9. #endif
  10. // clang-format on
  11. #pragma once
  12. #include <cstddef>
  13. #include <utility>
  14. /// Managed Obj-C pointer
  15. template <typename T>
  16. class MRCOwned
  17. {
  18. T ptr;
  19. MRCOwned(T ptr) : ptr(ptr) {}
  20. public:
  21. MRCOwned() : ptr(nullptr) {}
  22. MRCOwned(std::nullptr_t) : ptr(nullptr) {}
  23. MRCOwned(MRCOwned&& other) : ptr(other.ptr) { other.ptr = nullptr; }
  24. MRCOwned(const MRCOwned& other) : ptr(other.ptr) { [ptr retain]; }
  25. ~MRCOwned()
  26. {
  27. if (ptr)
  28. [ptr release];
  29. }
  30. operator T() const { return ptr; }
  31. MRCOwned& operator=(const MRCOwned& other)
  32. {
  33. [other.ptr retain];
  34. if (ptr)
  35. [ptr release];
  36. ptr = other.ptr;
  37. return *this;
  38. }
  39. MRCOwned& operator=(MRCOwned&& other)
  40. {
  41. std::swap(ptr, other.ptr);
  42. return *this;
  43. }
  44. void Reset()
  45. {
  46. [ptr release];
  47. ptr = nullptr;
  48. }
  49. T Disown()
  50. {
  51. T tmp = ptr;
  52. ptr = nullptr;
  53. return tmp;
  54. }
  55. T Get() const { return ptr; }
  56. static MRCOwned Transfer(T ptr) { return MRCOwned(ptr); }
  57. static MRCOwned Retain(T ptr)
  58. {
  59. [ptr retain];
  60. return MRCOwned(ptr);
  61. }
  62. };
  63. /// Take ownership of an Obj-C pointer (equivalent to __bridge_transfer)
  64. template <typename T>
  65. static inline MRCOwned<T> MRCTransfer(T ptr)
  66. {
  67. return MRCOwned<T>::Transfer(ptr);
  68. }
  69. /// Retain an Obj-C pointer (equivalent to __bridge)
  70. template <typename T>
  71. static inline MRCOwned<T> MRCRetain(T ptr)
  72. {
  73. return MRCOwned<T>::Retain(ptr);
  74. }