Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <atomic>
- #include <cassert>
- #include <iostream>
- using namespace std;
- template <class T>
- class MutableRef;
- template <class T>
- class ImmutableRef;
- template <class T>
- class OwnerPointer {
- private:
- T *rep_ = nullptr;
- atomic<int> ref_;
- public:
- OwnerPointer(T *rep = nullptr) : rep_(rep), ref_(0) {}
- ~OwnerPointer() { delete rep_; }
- OwnerPointer(const OwnerPointer<T> &other) = delete;
- OwnerPointer(OwnerPointer<T> &&other) { swap(rep_, other.rep_); }
- operator T *() { return rep_; }
- OwnerPointer &operator=(const OwnerPointer<T> &other) = delete;
- OwnerPointer &operator=(OwnerPointer<T> &&other) {
- swap(rep_, other.rep_);
- return *this;
- }
- MutableRef<T> RefMutable();
- ImmutableRef<T> RefImmutable();
- private:
- friend class MutableRef<T>;
- void UnrefMutable() { ++ref_; }
- friend class ImmutableRef<T>;
- void UnrefImmutable() { --ref_; }
- };
- template <class T>
- class ImmutableRef {
- private:
- OwnerPointer<T> *rep_;
- private:
- friend class OwnerPointer<T>;
- ImmutableRef(OwnerPointer<T> *rep) : rep_(rep) {}
- public:
- ~ImmutableRef() { rep_->UnrefImmutable(); }
- operator const T *() { return rep_->rep_; }
- };
- template <class T>
- class MutableRef {
- private:
- OwnerPointer<T> *rep_;
- private:
- friend class OwnerPointer<T>;
- MutableRef(OwnerPointer<T> *rep) : rep_(rep) {}
- public:
- ~MutableRef() { rep_->UnrefMutable(); }
- operator T *() { return rep_->rep_; }
- };
- template <class T>
- ImmutableRef<T> OwnerPointer<T>::RefImmutable() {
- assert(ref_ >= 0);
- ++ref_;
- return ImmutableRef<T>(this);
- }
- template <class T>
- MutableRef<T> OwnerPointer<T>::RefMutable() {
- assert(ref_ == 0);
- --ref_;
- return MutableRef<T>(this);
- }
- template <class T, class... Args>
- OwnerPointer<T> make_owner(Args &&... args) {
- return OwnerPointer<T>(new T(std::forward<Args>(args)...));
- }
- int main() {
- auto owner1 = make_owner<int>(20);
- printf("Owner1: %d\n", *owner1);
- auto owner2 = std::move(owner1);
- printf("Owner2: %d\n", *owner2);
- OwnerPointer<int> owner3;
- owner3 = std::move(owner2);
- printf("Owner3: %d\n", *owner3);
- {
- auto immutable1 = owner3.RefImmutable();
- printf("Immutable1: %d\n", *immutable1);
- // *immutable1 = 30; // Err
- auto immutable2 = owner3.RefImmutable();
- printf("Immutable2: %d\n", *immutable2);
- }
- {
- auto mutable1 = owner3.RefMutable();
- printf("Mutable1: %d\n", *mutable1);
- *mutable1 = 30; // Err
- printf("Mutable1: %d\n", *mutable1);
- // auto immutable1 = owner3.RefImmutable(); // Err
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement