Advertisement
Guest User

Untitled

a guest
Sep 21st, 2019
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.47 KB | None | 0 0
  1. #include <atomic>
  2. #include <cassert>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. template <class T>
  7. class MutableRef;
  8. template <class T>
  9. class ImmutableRef;
  10.  
  11. template <class T>
  12. class OwnerPointer {
  13. private:
  14. T *rep_ = nullptr;
  15. atomic<int> ref_;
  16.  
  17. public:
  18. OwnerPointer(T *rep = nullptr) : rep_(rep), ref_(0) {}
  19. ~OwnerPointer() { delete rep_; }
  20.  
  21. OwnerPointer(const OwnerPointer<T> &other) = delete;
  22. OwnerPointer(OwnerPointer<T> &&other) { swap(rep_, other.rep_); }
  23.  
  24. operator T *() { return rep_; }
  25. OwnerPointer &operator=(const OwnerPointer<T> &other) = delete;
  26. OwnerPointer &operator=(OwnerPointer<T> &&other) {
  27. swap(rep_, other.rep_);
  28. return *this;
  29. }
  30.  
  31. MutableRef<T> RefMutable();
  32. ImmutableRef<T> RefImmutable();
  33.  
  34. private:
  35. friend class MutableRef<T>;
  36. void UnrefMutable() { ++ref_; }
  37. friend class ImmutableRef<T>;
  38. void UnrefImmutable() { --ref_; }
  39. };
  40.  
  41. template <class T>
  42. class ImmutableRef {
  43. private:
  44. OwnerPointer<T> *rep_;
  45.  
  46. private:
  47. friend class OwnerPointer<T>;
  48. ImmutableRef(OwnerPointer<T> *rep) : rep_(rep) {}
  49.  
  50. public:
  51. ~ImmutableRef() { rep_->UnrefImmutable(); }
  52.  
  53. operator const T *() { return rep_->rep_; }
  54. };
  55.  
  56. template <class T>
  57. class MutableRef {
  58. private:
  59. OwnerPointer<T> *rep_;
  60.  
  61. private:
  62. friend class OwnerPointer<T>;
  63. MutableRef(OwnerPointer<T> *rep) : rep_(rep) {}
  64.  
  65. public:
  66. ~MutableRef() { rep_->UnrefMutable(); }
  67.  
  68. operator T *() { return rep_->rep_; }
  69. };
  70.  
  71. template <class T>
  72. ImmutableRef<T> OwnerPointer<T>::RefImmutable() {
  73. assert(ref_ >= 0);
  74. ++ref_;
  75. return ImmutableRef<T>(this);
  76. }
  77.  
  78. template <class T>
  79. MutableRef<T> OwnerPointer<T>::RefMutable() {
  80. assert(ref_ == 0);
  81. --ref_;
  82. return MutableRef<T>(this);
  83. }
  84.  
  85. template <class T, class... Args>
  86. OwnerPointer<T> make_owner(Args &&... args) {
  87. return OwnerPointer<T>(new T(std::forward<Args>(args)...));
  88. }
  89.  
  90. int main() {
  91. auto owner1 = make_owner<int>(20);
  92. printf("Owner1: %d\n", *owner1);
  93.  
  94. auto owner2 = std::move(owner1);
  95. printf("Owner2: %d\n", *owner2);
  96.  
  97. OwnerPointer<int> owner3;
  98. owner3 = std::move(owner2);
  99. printf("Owner3: %d\n", *owner3);
  100.  
  101. {
  102. auto immutable1 = owner3.RefImmutable();
  103. printf("Immutable1: %d\n", *immutable1);
  104. // *immutable1 = 30; // Err
  105.  
  106. auto immutable2 = owner3.RefImmutable();
  107. printf("Immutable2: %d\n", *immutable2);
  108. }
  109.  
  110. {
  111. auto mutable1 = owner3.RefMutable();
  112. printf("Mutable1: %d\n", *mutable1);
  113. *mutable1 = 30; // Err
  114. printf("Mutable1: %d\n", *mutable1);
  115.  
  116. // auto immutable1 = owner3.RefImmutable(); // Err
  117. }
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement