YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
bidirectional_intrusive_list.cpp
Go to the documentation of this file.
2
3#include <utility>
4
5namespace yaclib::detail::fiber {
6
7void BiList::PushBack(Node* node) noexcept {
8 YACLIB_DEBUG(node->prev != nullptr && node->prev != node, "Pushed but not popped");
9 node->next = &_head;
10 _head.prev->next = node;
11 node->prev = _head.prev;
12 _head.prev = node;
13}
14
16 return _head.next == &_head;
17}
18
20 if (this == &other || other.Empty()) {
21 return;
22 }
23 *this = std::move(other);
24}
25
27 auto* elem = _head.prev;
28 elem->Erase();
29 return elem;
30}
31
32Node* BiList::GetElement(std::size_t ind, bool reversed) const noexcept {
33 std::size_t i = 0;
34 Node* node{};
35 if (reversed) {
36 node = _head.prev;
37 } else {
38 node = _head.next;
39 }
40 while (i != ind) {
41 if (node == &_head) {
42 break;
43 }
44 ++i;
45 if (reversed) {
46 node = node->prev;
47 } else {
48 node = node->next;
49 }
50 }
51 if (i == ind && node != &_head) {
52 return node;
53 }
54 auto size = i;
55 if (size == 0) {
56 return nullptr;
57 }
58 i = reversed ? (size - ind % size) % size : ind % size;
59 if (i < size / 2) {
60 std::size_t current_i = 0;
61 node = _head.next;
62 while (current_i < i) {
63 node = node->next;
64 current_i++;
65 }
66 } else {
67 std::size_t current_i = size - 1;
68 node = _head.prev;
69 while (current_i > i) {
70 node = node->prev;
71 current_i--;
72 }
73 }
74 return node;
75}
76
78 if (this == &other) {
79 return *this;
80 }
81 if (other.Empty()) {
82 _head.next = &_head;
83 _head.prev = &_head;
84 return *this;
85 }
86 _head.next = std::exchange(other._head.next, &other._head);
87 _head.prev = std::exchange(other._head.prev, &other._head);
88 _head.next->prev = &_head;
89 _head.prev->next = &_head;
90 return *this;
91}
92
93void BiList::PushAll(BiList&& other) noexcept {
94 if (this == &other || other.Empty()) {
95 return;
96 }
97 _head.prev->next = std::exchange(other._head.next, &other._head);
98 _head.prev->next->prev = _head.prev;
99 _head.prev = std::exchange(other._head.prev, &other._head);
100 _head.prev->next = &_head;
101}
102
104 if (this->next == nullptr || this->prev == nullptr) {
105 return false;
106 }
107 Node* prev_node = this->prev;
108 Node* next_node = this->next;
109 prev_node->next = next_node;
111 this->next = nullptr;
112 this->prev = nullptr;
113 return true;
114}
115
116} // namespace yaclib::detail::fiber
Node * GetElement(std::size_t ind, bool reversed) const noexcept
BiList() noexcept=default
BiList & operator=(const BiList &)=delete
#define YACLIB_DEBUG(cond, message)
Definition log.hpp:84
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25