6 namespace honey {
namespace lockfree
15 template<class T, class Alloc_ = typename DefaultAllocator<T>::type>
20 typedef typename Alloc_::template rebind<T>::other
Alloc;
24 _data(nullptr,
finalize<T, Alloc>()),
42 sdt dif = _capacity - _size;
43 for (
sdt i = 0; i < dif; ++i) _alloc.construct(_data + ringIndex(_head+_size+i), initVal);
57 if (_size == _capacity) expand();
58 _head = ringDec(_head);
59 _alloc.construct(_data + _head, forward<T_>(val));
70 if (_size == 0 || _size >= _capacity-1) { tailLock.
unlock(); headLock.
lock(); tailLock.
lock(); }
71 if (_size == _capacity) expand();
72 _alloc.construct(_data + _tail, forward<T_>(val));
73 _tail = ringInc(_tail);
83 if (_size == 0)
return false;
84 if (val) val = move(_data[_head]);
85 _alloc.destroy(_data + _head);
86 _head = ringInc(_head);
96 if (_size == 1) { tailLock.
unlock(); headLock.
lock(); tailLock.
lock(); }
97 if (_size == 0)
return false;
98 _tail = ringDec(_tail);
99 if (val) val = move(_data[_tail]);
100 _alloc.destroy(_data + _tail);
114 szt ringIndex(
szt index)
const {
return index % _capacity; }
115 szt ringInc(
szt index)
const {
return index >= _capacity - 1 ? 0 : index + 1; }
116 szt ringDec(
szt index)
const {
return index == 0 ? _capacity - 1 : index - 1; }
118 void setCapacity(
szt capacity)
120 if (capacity == _capacity)
return;
122 szt size = capacity < _size ? capacity : _size.load();
127 data = _alloc.allocate(capacity);
131 szt copyTail = ringIndex(_head + size);
132 if (copyTail > _head)
134 std::copy(_data.get() + _head, _data + copyTail, data);
138 std::copy(_data.get() + _head, _data + _capacity, data);
139 std::copy(_data.get(), _data + copyTail, data + (_capacity - _head));
145 for (
sdt i = 0; i < dif; ++i) _alloc.destroy(_data + ringIndex(_head+size+i));
148 _capacity = capacity;
154 void expand() { setCapacity(_capacity + _capacity/2 + 1); }
157 UniquePtr<T, finalize<T,Alloc>> _data;
szt size() const
Number of elements in deque.
Definition: SpscDeque.h:109
Alloc_::template rebind< T >::other Alloc
Definition: SpscDeque.h:20
void push_back(T_ &&val)
Add new element constructed with val onto the end of the list.
Definition: SpscDeque.h:65
static optnull_t optnull
Null optional, use to reset an optional to an uninitialized state or test for initialization.
Definition: Optional.h:12
void resize(szt size, const T &initVal=T())
Resize the deque to contain a number of elements.
Definition: SpscDeque.h:36
ptrdiff_t sdt
Size difference type, shorthand for ptrdiff_t.
Definition: Core.h:92
Inherit to declare that class is not copyable.
Definition: Meta.h:286
bool pop_back(optional< T & > val=optnull)
Pop element from the end of the list and move it into val. Returns true on success, false if there is no element to pop.
Definition: SpscDeque.h:92
void clear()
Remove all elements.
Definition: SpscDeque.h:106
static auto _
Definition: Module.cpp:8
~SpscDeque()
Definition: SpscDeque.h:33
void push_front(T_ &&val)
Insert new element constructed with val at the beginning of the list.
Definition: SpscDeque.h:50
void unlock()
Definition: Unique.h:103
Not yet locked, will lock manually.
void lock()
Definition: Unique.h:95
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
T * alloc(szt count=1)
Allocate memory for count number of T objects. Objects are not constructed.
Definition: Allocator.h:31
Deque that is lock-free only when used by a single producer and consumer, otherwise contention is spl...
Definition: SpscDeque.h:16
Functor to delete a pointer.
Definition: Allocator.h:161
SpscDeque(szt size=0, const T &initVal=T(), const Alloc &alloc=Alloc())
Definition: SpscDeque.h:22
Specialization for references.
Definition: Optional.h:132
bool empty() const
Check whether the deque does not contain any elements.
Definition: SpscDeque.h:111
T value_type
Definition: SpscDeque.h:19
bool pop_front(optional< T & > val=optnull)
Pop element from the beginning of the list and move it into val. Returns true on success, false if there is no element to pop.
Definition: SpscDeque.h:78
Global Honeycomb namespace.