Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement