Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <algorithm>
- #include <stddef.h>
- namespace smart_ptr
- {
- namespace details
- {
- class PtrList
- {
- public:
- PtrList() : left_(nullptr), right_(nullptr) {}
- PtrList(PtrList const & ptr_list) : left_(&ptr_list), right_(ptr_list.right_)
- {
- update();
- }
- PtrList & operator = (PtrList const &ptr_list)
- {
- PtrList(ptr_list).swap(*this);
- return *this;
- }
- void swap(PtrList &ptr_list)
- {
- bool left_fl = (left_ == &ptr_list);
- bool right_fl = (right_ == &ptr_list);
- std::swap(left_, ptr_list.left_);
- std::swap(right_, ptr_list.right_);
- if (left_fl)
- {
- right_ = (&ptr_list);
- ptr_list.left_ = (this);
- }
- if (right_fl)
- {
- left_ = (&ptr_list);
- ptr_list.right_ = (this);
- }
- update();
- ptr_list.update();
- }
- bool is_unique() const
- {
- return (left_ == nullptr && right_ == nullptr);
- }
- ~PtrList()
- {
- if (left_)
- {
- left_->right_ = (right_);
- }
- if (right_)
- {
- right_->left_ = (left_);
- }
- left_ = nullptr;
- right_ = nullptr;
- }
- private:
- void update()
- {
- if (left_)
- {
- left_->right_ = (this);
- }
- if (right_)
- {
- right_->left_ = (this);
- }
- }
- mutable PtrList const *left_;
- mutable PtrList const *right_;
- };
- } // details
- template<class T>
- class linked_ptr
- {
- public:
- template<class> friend class linked_ptr;
- linked_ptr() : data_(nullptr), list_() {}
- explicit linked_ptr(T* item) : data_(item), list_() {}
- explicit linked_ptr(linked_ptr const &pointer): data_(pointer.data_), list_(pointer.list_){}
- template<class U>
- linked_ptr(linked_ptr<U> const &pointer): list_(pointer.list_), data_(pointer.get()) {}
- linked_ptr & operator =(linked_ptr const &pointer)
- {
- linked_ptr(pointer).swap(*this);
- return *this;
- }
- template<class U>
- linked_ptr<T> & operator =(linked_ptr<U> const &pointer)
- {
- linked_ptr(pointer).swap(*this);
- return *this;
- }
- void swap(linked_ptr &pointer)
- {
- list_.swap(pointer.list_);
- std::swap(data_, pointer.data_);
- }
- T* get() const
- {
- return data_;
- }
- T* operator->() const
- {
- return get();
- }
- T& operator*() const
- {
- return *get();
- }
- explicit operator bool() const
- {
- return data_ != nullptr;
- }
- bool unique() const
- {
- return data_ && list_.is_unique();
- }
- void reset()
- {
- list_.~PtrList();
- }
- void reset(T* pointer)
- {
- linked_ptr<T> tmp(pointer);
- swap(tmp);
- }
- template<class U>
- void reset(U* pointer)
- {
- T* cast_pointer = pointer;
- reset(cast_pointer);
- }
- ~linked_ptr()
- {
- enum{ check_for_complete_type = sizeof(T) };
- if (unique() && data_)
- {
- delete data_;
- }
- data_ = nullptr;
- }
- private:
- T* data_;
- smart_ptr::details::PtrList list_;
- };
- template<class T1, class T2>
- inline bool operator == (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
- {
- return first.get() == second.get();
- }
- template<class T1, class T2>
- inline bool operator != (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
- {
- return !(first == second);
- }
- template<class T1, class T2>
- inline bool operator < (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
- {
- return first.get() < second.get();
- }
- template<class T1, class T2>
- inline bool operator > (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
- {
- return (second < first);
- }
- template<class T1, class T2>
- inline bool operator <= (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
- {
- return !(second < first);
- }
- template<class T1, class T2>
- inline bool operator >= (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
- {
- return !(first < second);
- }
- template<class T>
- inline bool operator == (linked_ptr<T> const &first, std::nullptr_t)
- {
- return first.get() == nullptr;
- }
- template<class T>
- inline bool operator == (std::nullptr_t, linked_ptr<T> const &first)
- {
- return first.get() == nullptr;
- }
- template<class T>
- inline bool operator != (linked_ptr<T> const &first, std::nullptr_t)
- {
- return first.get() != nullptr;
- }
- template<class T>
- inline bool operator != (std::nullptr_t, linked_ptr<T> const &first)
- {
- return first.get() != nullptr;
- }
- template<class T>
- inline bool operator < (linked_ptr<T> const &first, std::nullptr_t)
- {
- return first.get() < nullptr;
- }
- template<class T>
- inline bool operator < (std::nullptr_t, linked_ptr<T> const &first)
- {
- return first.get() > nullptr;
- }
- template<class T>
- inline bool operator > (linked_ptr<T> const &first, std::nullptr_t)
- {
- return first.get() > nullptr;
- }
- template<class T>
- inline bool operator > (std::nullptr_t, linked_ptr<T> const &first)
- {
- return first.get() < nullptr;
- }
- template<class T>
- inline bool operator >= (linked_ptr<T> const &first, std::nullptr_t)
- {
- return first.get() >= nullptr;
- }
- template<class T>
- inline bool operator >= (std::nullptr_t, linked_ptr<T> const &first)
- {
- return first.get() <= nullptr;
- }
- template<class T>
- inline bool operator <= (linked_ptr<T> const &first, std::nullptr_t)
- {
- return first.get() <= nullptr;
- }
- template<class T>
- inline bool operator <= (std::nullptr_t, linked_ptr<T> const &first)
- {
- return first.get() >= nullptr;
- }
- } // smart_ptr
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement