Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- // linked_ptr header-only implementation
- namespace smart_ptr
- {
- namespace details
- {
- struct linked_ptr_impl
- {
- mutable linked_ptr_impl* prev;
- mutable linked_ptr_impl* next;
- explicit linked_ptr_impl(linked_ptr_impl* prev = nullptr, linked_ptr_impl* next = nullptr) : prev(prev), next(next)
- {
- }
- };
- } // namespace details
- template <class T>
- struct linked_ptr : details::linked_ptr_impl
- {
- private:
- T* ptr;
- public:
- template <class U>
- friend struct linked_ptr;
- ~linked_ptr()
- {
- release();
- }
- T* get() const
- {
- return ptr;
- }
- linked_ptr() : linked_ptr_impl()
- {
- ptr = nullptr;
- }
- explicit linked_ptr(T* data) : linked_ptr_impl(), ptr(data)
- {
- }
- template <class U>
- explicit linked_ptr(U* data) : linked_ptr_impl(), ptr(data)
- {
- }
- linked_ptr(const linked_ptr<T>& other)
- : linked_ptr_impl(other.prev, const_cast<linked_ptr<T>*>(&other)), ptr(other.get())
- {
- if (other.prev != nullptr)
- {
- other.prev->next = this;
- }
- other.prev = this;
- }
- template <class U>
- linked_ptr(const linked_ptr<U>& other)
- : linked_ptr_impl(other.prev, const_cast<linked_ptr<U>*>(&other)), ptr(other.get())
- {
- if (other.prev != nullptr)
- {
- other.prev->next = this;
- }
- other.prev = this;
- }
- void swap(linked_ptr<T>& other)
- {
- if (ptr != other.get())
- {
- std::swap(ptr, other.ptr);
- if (other.prev != nullptr)
- {
- other.prev->next = this;
- }
- if (other.next != nullptr)
- {
- other.next->prev = this;
- }
- if (this->next != nullptr)
- {
- this->next->prev = &other;
- }
- if (this->prev != nullptr)
- {
- this->prev->next = &other;
- }
- std::swap(this->prev, other.prev);
- std::swap(this->next, other.next);
- }
- }
- bool unique()
- {
- return (ptr != nullptr && prev == nullptr && next == nullptr);
- }
- void release()
- {
- if (unique())
- {
- delete ptr;
- }
- else
- {
- if (prev != nullptr)
- {
- prev->next = next;
- }
- if (next != nullptr)
- {
- next->prev = prev;
- }
- }
- }
- void reset()
- {
- release();
- }
- void reset(T* new_ptr)
- {
- if (ptr != new_ptr)
- {
- release();
- ptr = new_ptr;
- }
- }
- template <class U>
- void reset(U* new_ptr)
- {
- if (ptr != new_ptr)
- {
- release();
- ptr = new_ptr;
- }
- }
- template <class U>
- bool operator==(linked_ptr<U>& other)
- {
- return (ptr == other.get());
- }
- template <class U>
- bool operator!=(linked_ptr<U>& other)
- {
- return !(*this == other);
- }
- linked_ptr<T>& operator=(linked_ptr<T>& other)
- {
- if (*this != other)
- {
- linked_ptr<T>(other).swap(*this);
- }
- return *this;
- }
- template <class U>
- linked_ptr<U>& operator=(linked_ptr<U>& other)
- {
- if (*this != other)
- {
- linked_ptr<T>(other).swap(*this);
- }
- return *this;
- }
- T* operator->()
- {
- return ptr;
- }
- T& operator*()
- {
- return *ptr;
- }
- template <class U>
- bool operator<(const linked_ptr<U>& other)
- {
- return ptr < other.get();
- }
- template <class U>
- bool operator>=(const linked_ptr<U>& other)
- {
- return !(*this < other);
- }
- template <class U>
- bool operator>(const linked_ptr<U>& other)
- {
- return other < *this;
- }
- template <class U>
- bool operator<=(const linked_ptr<U>& other)
- {
- return !(other < *this);
- }
- explicit operator bool()
- {
- return ptr != nullptr;
- }
- };
- } // namespace smart_ptr
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement