31#ifndef FENNEC_CONTAINERS_DEQUE_H
32#define FENNEC_CONTAINERS_DEQUE_H
64template<
typename TypeT,
typename AllocT = allocator<TypeT>>
77 template<
typename...ArgsT>
78 node(node* prev, node* next, ArgsT&&...args)
79 : value(fennec::
forward<ArgsT>(args)...)
80 , prev(prev), next(next) {
87 using alloc_t = allocator_traits<AllocT>::template rebind<node>;
119 : _alloc(
deque._alloc)
123 const elem_t node =
deque._first;
134 : _alloc(
deque._alloc)
135 , _first(
deque._first)
137 , _size(
deque._size) {
138 deque._first =
nullptr;
139 deque._last =
nullptr;
163 constexpr size_t size()
const {
178 assert(not
empty(),
"Attempted to access an empty deque.");
179 return _first->value;
185 assert(not
empty(),
"Attempted to access an empty deque.");
186 return _first->value;
192 assert(not
empty(),
"Attempted to access an empty deque.");
199 assert(not
empty(),
"Attempted to access an empty deque.");
215 this->_push_front(elem);
222 this->_push_front(elem);
229 template<
typename...ArgsT>
231 this->_push_front(fennec::forward<ArgsT>(args)...);
239 this->_push_back(elem);
246 this->_push_back(elem);
253 template<
typename...ArgsT>
255 this->_push_back(fennec::forward<ArgsT>(args)...);
263 elem_t next = it->next;
264 fennec::destruct(it);
265 _alloc.deallocate(it);
276 if (_first ==
nullptr) {
279 elem_t next = _first->next;
280 fennec::destruct(_first);
281 _alloc.deallocate(_first);
283 _last = next ? _last :
nullptr;
290 if (_last ==
nullptr) {
293 elem_t prev = _last->prev;
294 fennec::destruct(_last);
295 _alloc.deallocate(_last);
297 _first = prev ? _first :
nullptr;
312 node *_first, *_last;
315 template<
typename...ArgsT>
316 void _push_front(ArgsT&&...args) {
317 elem_t next = _first;
318 _first = _alloc.allocate(1);
319 fennec::construct(_first,
nullptr, next, fennec::forward<ArgsT>(args)...);
328 template<
typename...ArgsT>
329 void _push_back(ArgsT&&...args) {
331 _last = _alloc.allocate(1);
332 fennec::construct(_last, prev,
nullptr, fennec::forward<ArgsT>(args)...);
This header contains structures and classes related to allocating blocks of memory.
Data structure defining a double-ended queue.
Definition deque.h:65
void push_back(value_t &&elem)
Push Back Move, moves a value to the back of the deque.
Definition deque.h:238
constexpr bool empty() const
Definition deque.h:157
const value_t & front() const
Definition deque.h:184
void emplace_back(ArgsT &&...args)
Emplace Back, constructs a new value at the back of the deque.
Definition deque.h:254
TypeT value_t
Alias for the value type.
Definition deque.h:69
void push_front(value_t &&elem)
Push Front Move, moves a value to the front of the deque.
Definition deque.h:214
void emplace_front(ArgsT &&...args)
Emplace Front, constructs a new value at the front of the deque.
Definition deque.h:230
void pop_front()
Erase the First Element.
Definition deque.h:275
value_t & back()
Definition deque.h:191
deque()
Default Constructor, initializes an empty deque.
Definition deque.h:98
deque(const deque &deque)
Copy Constructor.
Definition deque.h:118
value_t & front()
Definition deque.h:177
const value_t & back() const
Definition deque.h:198
deque(const alloc_t &alloc)
Alloc Constructor, initializes an empty deque with the specified allocator.
Definition deque.h:108
void pop_back()
Erase the Last Element.
Definition deque.h:289
constexpr size_t size() const
Definition deque.h:163
~deque()
Destructor, calls deque::clear.
Definition deque.h:144
void push_back(const value_t &elem)
Push Back Copy, copies a value to the back of the deque.
Definition deque.h:245
deque(deque &&deque) noexcept
Deque Move Constructor.
Definition deque.h:133
void clear()
Clears the contents of the deque.
Definition deque.h:260
void push_front(const value_t &elem)
Push Front Copy, copies a value to the front of the deque.
Definition deque.h:221
constexpr T && forward(remove_reference_t< T > &x) noexcept
forwards reference types to extend their lifetime
Definition utility.h:75