Advertisement
Guest User

Untitled

a guest
Dec 15th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.27 KB | None | 0 0
  1. #pragma once
  2.  
  3. // linked_ptr header-only implementation
  4.  
  5. namespace smart_ptr
  6. {
  7. namespace details
  8. {
  9. struct linked_ptr_impl
  10. {
  11.     mutable linked_ptr_impl* prev;
  12.     mutable linked_ptr_impl* next;
  13.     explicit linked_ptr_impl(linked_ptr_impl* prev = nullptr, linked_ptr_impl* next = nullptr) : prev(prev), next(next)
  14.     {
  15.     }
  16. };
  17. }  // namespace details
  18.  
  19. template <class T>
  20. struct linked_ptr : details::linked_ptr_impl
  21. {
  22.  
  23. private:
  24.     T* ptr;
  25.  
  26. public:
  27.     template <class U>
  28.     friend struct linked_ptr;
  29.  
  30.     ~linked_ptr()
  31.     {
  32.         release();
  33.     }
  34.  
  35.     T* get() const
  36.     {
  37.         return ptr;
  38.     }
  39.  
  40.     linked_ptr() : linked_ptr_impl()
  41.     {
  42.         ptr = nullptr;
  43.     }
  44.  
  45.     explicit linked_ptr(T* data) : linked_ptr_impl(), ptr(data)
  46.     {
  47.     }
  48.  
  49.     template <class U>
  50.     explicit linked_ptr(U* data) : linked_ptr_impl(), ptr(data)
  51.     {
  52.     }
  53.  
  54.     linked_ptr(const linked_ptr<T>& other)
  55.         : linked_ptr_impl(other.prev, const_cast<linked_ptr<T>*>(&other)), ptr(other.get())
  56.     {
  57.         if (other.prev != nullptr)
  58.         {
  59.             other.prev->next = this;
  60.         }
  61.  
  62.         other.prev = this;
  63.     }
  64.  
  65.     template <class U>
  66.     linked_ptr(const linked_ptr<U>& other)
  67.         : linked_ptr_impl(other.prev, const_cast<linked_ptr<U>*>(&other)), ptr(other.get())
  68.     {
  69.         if (other.prev != nullptr)
  70.         {
  71.             other.prev->next = this;
  72.         }
  73.  
  74.         other.prev = this;
  75.     }
  76.  
  77.     void swap(linked_ptr<T>& other)
  78.     {
  79.         if (ptr != other.get())
  80.         {
  81.             std::swap(ptr, other.ptr);
  82.             if (other.prev != nullptr)
  83.             {
  84.                 other.prev->next = this;
  85.             }
  86.  
  87.             if (other.next != nullptr)
  88.             {
  89.                 other.next->prev = this;
  90.             }
  91.  
  92.             if (this->next != nullptr)
  93.             {
  94.                 this->next->prev = &other;
  95.             }
  96.             if (this->prev != nullptr)
  97.             {
  98.                 this->prev->next = &other;
  99.             }
  100.  
  101.             std::swap(this->prev, other.prev);
  102.             std::swap(this->next, other.next);
  103.         }
  104.     }
  105.  
  106.     bool unique()
  107.     {
  108.         return (ptr != nullptr && prev == nullptr && next == nullptr);
  109.     }
  110.  
  111.     void release()
  112.     {
  113.         if (unique())
  114.         {
  115.             delete ptr;
  116.         }
  117.         else
  118.         {
  119.             if (prev != nullptr)
  120.             {
  121.                 prev->next = next;
  122.             }
  123.  
  124.             if (next != nullptr)
  125.             {
  126.                 next->prev = prev;
  127.             }
  128.         }
  129.     }
  130.  
  131.     void reset()
  132.     {
  133.         release();
  134.     }
  135.  
  136.     void reset(T* new_ptr)
  137.     {
  138.         if (ptr != new_ptr)
  139.         {
  140.             release();
  141.             ptr = new_ptr;
  142.         }
  143.     }
  144.  
  145.     template <class U>
  146.     void reset(U* new_ptr)
  147.     {
  148.         if (ptr != new_ptr)
  149.         {
  150.             release();
  151.             ptr = new_ptr;
  152.         }
  153.     }
  154.  
  155.     template <class U>
  156.     bool operator==(linked_ptr<U>& other)
  157.     {
  158.         return (ptr == other.get());
  159.     }
  160.  
  161.     template <class U>
  162.     bool operator!=(linked_ptr<U>& other)
  163.     {
  164.         return !(*this == other);
  165.     }
  166.  
  167.     linked_ptr<T>& operator=(linked_ptr<T>& other)
  168.     {
  169.         if (*this != other)
  170.         {
  171.             linked_ptr<T>(other).swap(*this);
  172.         }
  173.  
  174.         return *this;
  175.     }
  176.  
  177.     template <class U>
  178.     linked_ptr<U>& operator=(linked_ptr<U>& other)
  179.     {
  180.         if (*this != other)
  181.         {
  182.             linked_ptr<T>(other).swap(*this);
  183.         }
  184.         return *this;
  185.     }
  186.  
  187.     T* operator->()
  188.     {
  189.         return ptr;
  190.     }
  191.  
  192.     T& operator*()
  193.     {
  194.         return *ptr;
  195.     }
  196.  
  197.     template <class U>
  198.     bool operator<(const linked_ptr<U>& other)
  199.     {
  200.         return ptr < other.get();
  201.     }
  202.  
  203.     template <class U>
  204.     bool operator>=(const linked_ptr<U>& other)
  205.     {
  206.         return !(*this < other);
  207.     }
  208.  
  209.     template <class U>
  210.     bool operator>(const linked_ptr<U>& other)
  211.     {
  212.         return other < *this;
  213.     }
  214.  
  215.     template <class U>
  216.     bool operator<=(const linked_ptr<U>& other)
  217.     {
  218.         return !(other < *this);
  219.     }
  220.  
  221.     explicit operator bool()
  222.     {
  223.         return ptr != nullptr;
  224.     }
  225. };
  226.  
  227. }  // namespace smart_ptr
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement