Advertisement
Guest User

Untitled

a guest
Dec 20th, 2014
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.49 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <algorithm>
  4. #include <stddef.h>
  5.  
  6. namespace smart_ptr
  7. {
  8.  
  9. namespace details
  10. {
  11.  
  12. class PtrList
  13. {
  14.  
  15. public:
  16.  
  17. PtrList() : left_(nullptr), right_(nullptr) {}
  18.  
  19. PtrList(PtrList const & ptr_list) : left_(&ptr_list), right_(ptr_list.right_)
  20. {
  21. update();
  22. }
  23.  
  24. PtrList & operator = (PtrList const &ptr_list)
  25. {
  26. PtrList(ptr_list).swap(*this);
  27. return *this;
  28. }
  29.  
  30. void swap(PtrList &ptr_list)
  31. {
  32. bool left_fl = (left_ == &ptr_list);
  33. bool right_fl = (right_ == &ptr_list);
  34.  
  35. std::swap(left_, ptr_list.left_);
  36. std::swap(right_, ptr_list.right_);
  37.  
  38. if (left_fl)
  39. {
  40. right_ = (&ptr_list);
  41. ptr_list.left_ = (this);
  42. }
  43.  
  44. if (right_fl)
  45. {
  46. left_ = (&ptr_list);
  47. ptr_list.right_ = (this);
  48. }
  49.  
  50. update();
  51. ptr_list.update();
  52. }
  53.  
  54. bool is_unique() const
  55. {
  56. return (left_ == nullptr && right_ == nullptr);
  57. }
  58.  
  59. ~PtrList()
  60. {
  61. if (left_)
  62. {
  63. left_->right_ = (right_);
  64. }
  65.  
  66. if (right_)
  67. {
  68. right_->left_ = (left_);
  69. }
  70.  
  71. left_ = nullptr;
  72. right_ = nullptr;
  73. }
  74.  
  75. private:
  76.  
  77. void update()
  78. {
  79. if (left_)
  80. {
  81. left_->right_ = (this);
  82. }
  83.  
  84. if (right_)
  85. {
  86. right_->left_ = (this);
  87. }
  88. }
  89.  
  90. mutable PtrList const *left_;
  91. mutable PtrList const *right_;
  92. };
  93.  
  94. } // details
  95.  
  96. template<class T>
  97. class linked_ptr
  98. {
  99. public:
  100.  
  101. template<class> friend class linked_ptr;
  102. linked_ptr() : data_(nullptr), list_() {}
  103.  
  104. explicit linked_ptr(T* item) : data_(item), list_() {}
  105.  
  106. explicit linked_ptr(linked_ptr const &pointer): data_(pointer.data_), list_(pointer.list_){}
  107.  
  108. template<class U>
  109. linked_ptr(linked_ptr<U> const &pointer): list_(pointer.list_), data_(pointer.get()) {}
  110.  
  111. linked_ptr & operator =(linked_ptr const &pointer)
  112. {
  113. linked_ptr(pointer).swap(*this);
  114. return *this;
  115. }
  116.  
  117. template<class U>
  118. linked_ptr<T> & operator =(linked_ptr<U> const &pointer)
  119. {
  120. linked_ptr(pointer).swap(*this);
  121. return *this;
  122. }
  123.  
  124. void swap(linked_ptr &pointer)
  125. {
  126. list_.swap(pointer.list_);
  127. std::swap(data_, pointer.data_);
  128. }
  129.  
  130. T* get() const
  131. {
  132. return data_;
  133. }
  134.  
  135. T* operator->() const
  136. {
  137. return get();
  138. }
  139.  
  140. T& operator*() const
  141. {
  142. return *get();
  143. }
  144.  
  145. explicit operator bool() const
  146. {
  147. return data_ != nullptr;
  148. }
  149.  
  150. bool unique() const
  151. {
  152. return data_ && list_.is_unique();
  153. }
  154.  
  155. void reset()
  156. {
  157. list_.~PtrList();
  158. }
  159.  
  160. void reset(T* pointer)
  161. {
  162. linked_ptr<T> tmp(pointer);
  163. swap(tmp);
  164. }
  165.  
  166. template<class U>
  167. void reset(U* pointer)
  168. {
  169. T* cast_pointer = pointer;
  170. reset(cast_pointer);
  171. }
  172.  
  173. ~linked_ptr()
  174. {
  175. enum{ check_for_complete_type = sizeof(T) };
  176. if (unique() && data_)
  177. {
  178. delete data_;
  179. }
  180. data_ = nullptr;
  181. }
  182.  
  183.  
  184.  
  185. private:
  186. T* data_;
  187. smart_ptr::details::PtrList list_;
  188. };
  189.  
  190. template<class T1, class T2>
  191. inline bool operator == (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
  192. {
  193. return first.get() == second.get();
  194. }
  195.  
  196. template<class T1, class T2>
  197. inline bool operator != (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
  198. {
  199. return !(first == second);
  200. }
  201.  
  202. template<class T1, class T2>
  203. inline bool operator < (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
  204. {
  205. return first.get() < second.get();
  206. }
  207.  
  208. template<class T1, class T2>
  209. inline bool operator > (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
  210. {
  211. return (second < first);
  212. }
  213.  
  214. template<class T1, class T2>
  215. inline bool operator <= (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
  216. {
  217. return !(second < first);
  218. }
  219.  
  220. template<class T1, class T2>
  221. inline bool operator >= (linked_ptr<T1> const &first, linked_ptr<T2> const &second)
  222. {
  223. return !(first < second);
  224. }
  225.  
  226. template<class T>
  227. inline bool operator == (linked_ptr<T> const &first, std::nullptr_t)
  228. {
  229. return first.get() == nullptr;
  230. }
  231.  
  232. template<class T>
  233. inline bool operator == (std::nullptr_t, linked_ptr<T> const &first)
  234. {
  235. return first.get() == nullptr;
  236. }
  237.  
  238. template<class T>
  239. inline bool operator != (linked_ptr<T> const &first, std::nullptr_t)
  240. {
  241. return first.get() != nullptr;
  242. }
  243.  
  244. template<class T>
  245. inline bool operator != (std::nullptr_t, linked_ptr<T> const &first)
  246. {
  247. return first.get() != nullptr;
  248. }
  249.  
  250. template<class T>
  251. inline bool operator < (linked_ptr<T> const &first, std::nullptr_t)
  252. {
  253. return first.get() < nullptr;
  254. }
  255.  
  256. template<class T>
  257. inline bool operator < (std::nullptr_t, linked_ptr<T> const &first)
  258. {
  259. return first.get() > nullptr;
  260. }
  261.  
  262. template<class T>
  263. inline bool operator > (linked_ptr<T> const &first, std::nullptr_t)
  264. {
  265. return first.get() > nullptr;
  266. }
  267.  
  268. template<class T>
  269. inline bool operator > (std::nullptr_t, linked_ptr<T> const &first)
  270. {
  271. return first.get() < nullptr;
  272. }
  273.  
  274. template<class T>
  275. inline bool operator >= (linked_ptr<T> const &first, std::nullptr_t)
  276. {
  277. return first.get() >= nullptr;
  278. }
  279.  
  280. template<class T>
  281. inline bool operator >= (std::nullptr_t, linked_ptr<T> const &first)
  282. {
  283. return first.get() <= nullptr;
  284. }
  285.  
  286. template<class T>
  287. inline bool operator <= (linked_ptr<T> const &first, std::nullptr_t)
  288. {
  289. return first.get() <= nullptr;
  290. }
  291.  
  292. template<class T>
  293. inline bool operator <= (std::nullptr_t, linked_ptr<T> const &first)
  294. {
  295. return first.get() >= nullptr;
  296. }
  297.  
  298.  
  299.  
  300.  
  301. } // smart_ptr
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement