tyler569 icon

kinda c++ rust things

tyler569 | PRO | 08/25/18 06:16:07 AM UTC | 0 ⭐ | 883 👁️ | Never ⏰ | []
C++ |

1.68 KB

|

None

|

0 👍

/

0 👎

 
#include <cstdio>
 
template <typename T>
struct const_ref;
 
template <typename T>
struct mut_ref;
 
struct unsafe_op {};
 
template <typename T>
struct safe_ptr {
    long refcnt;
    T *data;
 
    safe_ptr() : refcnt(0), data(new T) {}
    safe_ptr(T val) : refcnt(0), data(new T) {
        *data = val;
    }
    ~safe_ptr() { delete data; }
    safe_ptr(safe_ptr const&) = delete;
 
    const_ref<T> operator &() {
        if (refcnt >= 0)
            return const_ref<T>{this};
        else
            throw unsafe_op{};
    }
 
    mut_ref<T> operator +() {
        if (refcnt == 0)
            return mut_ref<T>{this};
        else
            throw unsafe_op{};
    }
};
 
template <typename T>
struct const_ref {
    safe_ptr<T>& ptr;
 
    const_ref(safe_ptr<T> *upstream)
      : ptr(*upstream) {
        ptr.refcnt += 1;
    }
 
    ~const_ref() {
        ptr.refcnt -= 1;
    }
 
    T const& operator *() {
        return *ptr.data;
    }
};
 
template <typename T>
struct mut_ref {
    safe_ptr<T>& ptr;
 
    mut_ref(safe_ptr<T> *upstream)
      : ptr(*upstream) {
        ptr.refcnt -= 1;
    }
 
    ~mut_ref() {
        ptr.refcnt += 1;
    }
 
    T& operator *() {
        return *ptr.data;
    }
};
 
int main() {
    safe_ptr<int> x { 1 };
 
    {
        auto ref = &x;
        // *ref = 100; // would fail for modification of const
        auto ref2 = &x;
        printf("%i", *ref, *ref2);
 
        // auto mut_ref = +x; // would fail for taking mutable ref while const refs exist
    }
 
    {
        auto mut_ref = +x;
        *mut_ref = 10;
    }
 
    {
        auto ref = &x;
        printf("%i", *ref);
    }
}

Comments