SHARE
TWEET

Untitled

a guest Sep 21st, 2019 58 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top