XorList.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. //
  2. // Created by kikab on 06.05.2018.
  3. //
  4. #ifndef XOR_LIST_XORLIST_H
  5. #define XOR_LIST_XORLIST_H
  6. #include <forward_list>
  7. #include <bits/allocator.h>
  8. #include <ext/alloc_traits.h>
  9. #include <vector>
  10. #include <list>
  11. #include <memory>
  12. #include <utility>
  13. #include <iostream>
  14. #include <stdexcept>
  15. template<typename T>
  16. struct XorListNode {
  17. public:
  18. XorListNode() = delete;
  19. explicit XorListNode(const T &val) {
  20. val_ = val;
  21. }
  22. explicit XorListNode(T &&val) {
  23. val_ = std::move(val);//std::forward<T>(val);
  24. //std::cout << "move-constructor\n";
  25. }
  26. XorListNode *right(const XorListNode *left) const {
  27. return reinterpret_cast<XorListNode *>(xor_ptr_ ^ reinterpret_cast<uintptr_t>(left));
  28. }
  29. XorListNode *left(const XorListNode *right) const {
  30. return reinterpret_cast<XorListNode *>(xor_ptr_ ^ reinterpret_cast<uintptr_t>(right));
  31. }
  32. void assign_leftright(const XorListNode *left, const XorListNode *right) {
  33. xor_ptr_ = (reinterpret_cast<uintptr_t>(left) ^ reinterpret_cast<uintptr_t>(right));
  34. }
  35. T val_;
  36. private:
  37. uintptr_t xor_ptr_;
  38. };
  39. template<typename T>
  40. struct FwdXorListIterator {
  41. typedef FwdXorListIterator<T> Self;
  42. typedef XorListNode<T> Node;
  43. typedef ptrdiff_t difference_type;
  44. typedef std::bidirectional_iterator_tag iterator_category;
  45. typedef T value_type;
  46. typedef T *pointer;
  47. typedef T &reference;
  48. FwdXorListIterator() = delete;
  49. FwdXorListIterator(Node *x, Node *prev) : node_(x), left_(prev) {}
  50. reference operator*() const {
  51. return node_->val_;
  52. }
  53. pointer operator->() const {
  54. return &node_->val_;
  55. }
  56. Self &operator++() {
  57. Node *future_left_ = node_;
  58. node_ = node_->right(left_);
  59. left_ = future_left_;
  60. return *this;
  61. }
  62. Self operator++(int) {
  63. Self __tmp = *this;
  64. Node *future_left_ = node_;
  65. node_ = node_->right(left_);
  66. left_ = future_left_;
  67. return __tmp;
  68. }
  69. Self &operator--() {
  70. Node *future_right = node_;
  71. node_ = node_->left(node_->right(left_));
  72. left_ = node_->left(future_right);
  73. return *this;
  74. }
  75. Self operator--(int) {
  76. Self __tmp = *this;
  77. Node *future_right = node_;
  78. node_ = node_->left(node_->right(left_));
  79. left_ = node_->left(future_right);
  80. return __tmp;
  81. }
  82. bool operator==(const Self &x) const {
  83. return left_ == x.left_;
  84. }
  85. bool operator!=(const Self &x) const {
  86. return left_ != x.left_;
  87. }
  88. Node *node_;
  89. Node *left_;
  90. };
  91. template<typename T, typename Allocator = std::allocator<T> >
  92. class XorList {
  93. private:
  94. typedef typename __gnu_cxx::__alloc_traits<Allocator>::template
  95. rebind<T>::other T_alloc_type;
  96. typedef __gnu_cxx::__alloc_traits<T_alloc_type> T_alloc_traits;
  97. typedef typename T_alloc_traits::template rebind<XorListNode<T> >::other Node_alloc_type;
  98. typedef __gnu_cxx::__alloc_traits<Node_alloc_type> Node_alloc_traits;
  99. public:
  100. // types:
  101. typedef T value_type;
  102. typedef typename T_alloc_traits::pointer pointer;
  103. typedef typename T_alloc_traits::const_pointer const_pointer;
  104. typedef value_type &reference;
  105. typedef const value_type &const_reference;
  106. typedef FwdXorListIterator<T> iterator;
  107. typedef std::reverse_iterator<iterator> reverse_iterator;
  108. typedef std::size_t size_type;
  109. typedef std::ptrdiff_t difference_type;
  110. //typedef Allocator allocator_type;
  111. explicit XorList(const Allocator &alloc = Allocator())
  112. : front_(nullptr), back_(nullptr), size_(0), allocator_(Node_alloc_type(alloc)) {}
  113. explicit XorList(size_type count, const_reference value = T(), const Allocator &alloc = Allocator())
  114. : front_(nullptr), back_(nullptr), size_(0), allocator_(Node_alloc_type(alloc)) {
  115. for (size_type i = 0; i < count; i++)
  116. push_back(value);
  117. }
  118. XorList &operator=(const XorList &other) {
  119. if (this == &other)
  120. return *this;
  121. clear();
  122. allocator_ = Node_alloc_type(other.allocator_);
  123. front_ = back_ = nullptr;
  124. size_ = 0;
  125. for (const auto& i: other)
  126. push_back(i);
  127. std::cout << "Copy assignment\n";
  128. return *this;
  129. }
  130. XorList &operator=(XorList &&other) noexcept {
  131. if (this == &other)
  132. return *this;
  133. clear();
  134. this->front_ = other.front_;
  135. this->back_ = other.back_;
  136. this->size_ = other.size_;
  137. this->allocator_ = std::move(other.allocator_);
  138. other.front_ = other.back_ = nullptr;
  139. other.size_ = 0;
  140. std::cout << "Move assignment\n";
  141. return *this;
  142. }
  143. ~XorList() {
  144. clear();
  145. }
  146. template <typename xorlist_t>
  147. explicit XorList(xorlist_t &&other) noexcept : XorList() {
  148. *this = std::forward<xorlist_t>(other);
  149. }
  150. value_type front() const {
  151. return front_->val_;
  152. }
  153. value_type back() const {
  154. return back_->val_;
  155. }
  156. iterator begin() const {
  157. return iterator(front_, nullptr);
  158. }
  159. iterator end() const {
  160. if (!back_)
  161. return iterator(nullptr, nullptr);
  162. return ++iterator(back_, back_->left(nullptr));
  163. }
  164. reverse_iterator rbegin() const {
  165. return reverse_iterator(front_, nullptr);
  166. }
  167. reverse_iterator rend() const {
  168. return ++reverse_iterator(back_, back_->left(nullptr));
  169. }
  170. size_type size() const {
  171. return size_;
  172. }
  173. template<typename v_type>
  174. void push_back(v_type &&val) {
  175. insert_after(iterator(back_, back_ ? back_->left(nullptr) : nullptr), std::forward<v_type>(val));
  176. }
  177. template<typename v_type>
  178. void push_front(v_type &&val) {
  179. insert_before(iterator(front_, nullptr), std::forward<v_type>(val));
  180. }
  181. template<typename v_type>
  182. void insert_before(iterator it, v_type &&val) {
  183. _m_insert(it, std::forward<v_type>(val), BEFORE);
  184. }
  185. template<typename v_type>
  186. void insert_after(iterator it, v_type &&val) {
  187. _m_insert(it, std::forward<v_type>(val), AFTER);
  188. }
  189. void pop_back() {
  190. if (!back_)
  191. return;
  192. erase(iterator(back_, back_->left(nullptr)));
  193. }
  194. void pop_front() {
  195. if (!front_)
  196. return;
  197. erase(iterator(front_, nullptr));
  198. }
  199. void erase(iterator it) {
  200. XorListNode<T> *left = it.left_;
  201. XorListNode<T> *cur = it.node_;
  202. XorListNode<T> *right = it.node_->right(left);
  203. if (left)
  204. left->assign_leftright(left->left(cur), right);
  205. if (right)
  206. right->assign_leftright(left, right->right(cur));
  207. if (cur) {
  208. size_--;
  209. if (front_ == cur)
  210. front_ = cur->right(nullptr);
  211. if (back_ == cur)
  212. back_ = cur->left(nullptr);
  213. }
  214. allocator_.destroy(cur);
  215. allocator_.deallocate(cur, 1);
  216. }
  217. void clear() {
  218. XorListNode<T> *xleft = nullptr;
  219. XorListNode<T> *x = front_;
  220. while (x != back_) {
  221. XorListNode<T> *xnext = x->right(xleft);
  222. if (xnext) {
  223. allocator_.destroy(xleft);
  224. allocator_.deallocate(xleft, 1);
  225. }
  226. xleft = x;
  227. x = xnext;
  228. }
  229. if (xleft) {
  230. allocator_.destroy(xleft);
  231. allocator_.deallocate(xleft, 1);
  232. }
  233. if (x) {
  234. allocator_.destroy(x);
  235. allocator_.deallocate(x, 1);
  236. }
  237. size_ = 0;
  238. front_ = back_ = nullptr;
  239. }
  240. private:
  241. enum E_POSITION_TYPE {
  242. BEFORE,
  243. AFTER
  244. };
  245. template<typename v_type>
  246. void _m_insert(iterator it, v_type &&val, E_POSITION_TYPE pos) {
  247. XorListNode<T> *cur = it.node_;
  248. XorListNode<T> *left = it.left_;
  249. XorListNode<T> *new_node = reinterpret_cast<XorListNode<T> *>(allocator_.allocate(1));
  250. Node_alloc_traits::construct(allocator_, new_node, std::forward<v_type>(val));
  251. new_node->assign_leftright(nullptr, nullptr);
  252. if (!front_ || !back_) {
  253. front_ = back_ = new_node;
  254. size_ = 1;
  255. return;
  256. }
  257. XorListNode<T> *right = it.node_->right(left);
  258. if (pos == BEFORE) {
  259. new_node->assign_leftright(left, cur);
  260. cur->assign_leftright(new_node, right);
  261. if (left)
  262. left->assign_leftright(left->left(cur), new_node);
  263. if (cur == front_)
  264. front_ = new_node;
  265. }
  266. if (pos == AFTER) {
  267. new_node->assign_leftright(cur, right);
  268. cur->assign_leftright(left, new_node);
  269. if (right)
  270. right->assign_leftright(new_node, right->right(cur));
  271. if (cur == back_)
  272. back_ = new_node;
  273. }
  274. size_++;
  275. }
  276. private:
  277. XorListNode<T> *front_;
  278. XorListNode<T> *back_; // Pointer to the LAST element
  279. size_type size_;
  280. Node_alloc_type allocator_;
  281. };
  282. #endif //XOR_LIST_XORLIST_H