libhatchet
Loading...
Searching...
No Matches
hxdeque.hpp
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: © 2025 Adrian Johnston.
3// SPDX-License-Identifier: MIT
4// This file is licensed under the MIT license found in the LICENSE.md file.
5
8
9#include "libhatchet.h"
10
11// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
12#if HX_USE_MACROS_WITH_MODULE
13#error Header does not provide macros alone.
14#endif
15
16#include "hxallocator.hpp"
17#include "hxrange.hpp"
18#include "hxutility.h"
19
20HX_NS_BEGIN_
21
22#if HX_CPLUSPLUS >= 202002L
24template<typename T_>
25concept hxdeque_concept_ = requires(T_& x_) {
26 sizeof(T_);
27 x_.~T_();
28};
30#else
31#define hxdeque_concept_ typename
32#endif
33
41template<hxdeque_concept_ T_, hxsize_t capacity_=hxallocator_dynamic_capacity>
42class hxdeque : private hxallocator<T_, capacity_> {
43public:
47 public:
49 const_iterator(void) : m_deque_(hxnull), m_index_(0) { }
50
52 const T_& operator*(void) const { return (*m_deque_)[m_index_]; }
53
56 const_iterator operator+(hxsize_t n_) const { return const_iterator(m_deque_, m_index_ + n_); }
57
60 const_iterator operator-(hxsize_t n_) const { return const_iterator(m_deque_, m_index_ - n_); }
61
64 hxsize_t operator-(const const_iterator& x_) const { return m_index_ - x_.m_index_; }
65
69 const T_& operator[](hxsize_t n_) const { return *operator+(n_); }
70
72 const_iterator& operator++(void) { ++m_index_; return *this; }
73
75 const_iterator operator++(int) { const_iterator t_(*this); ++m_index_; return t_; }
76
78 const_iterator& operator--(void) { --m_index_; return *this; }
79
81 const_iterator operator--(int) { const_iterator t_(*this); operator--(); return t_; }
82
85 bool operator==(const const_iterator& x_) const { return m_index_ == x_.m_index_; }
86
89 bool operator<(const const_iterator& x_) const { return m_index_ < x_.m_index_; }
90
91#if HX_CPLUSPLUS < 202002L
94 bool operator!=(const const_iterator& x_) const { return m_index_ != x_.m_index_; }
95#endif
96
97 protected:
99 friend class hxdeque;
100 const_iterator(const hxdeque* deque_, hxsize_t index_)
101 : m_deque_(deque_), m_index_(index_) { }
102 const hxdeque* m_deque_;
103 hxsize_t m_index_;
105 };
106
108 class iterator : public const_iterator {
109 public:
111 iterator(void) { }
112
114 T_& operator*(void) const { return (*const_cast<hxdeque*>(this->m_deque_))[this->m_index_]; }
115
118 iterator operator+(hxsize_t n_) const { return iterator(const_cast<hxdeque*>(this->m_deque_), this->m_index_ + n_); }
119
122 iterator operator-(hxsize_t n_) const { return iterator(const_cast<hxdeque*>(this->m_deque_), this->m_index_ - n_); }
123
127
130 T_& operator[](hxsize_t n_) const { return *operator+(n_); }
131
134
136 iterator operator++(int) { iterator t_(*this); const_iterator::operator++(); return t_; }
137
140
142 iterator operator--(int) { iterator t_(*this); const_iterator::operator--(); return t_; }
143
144 protected:
146 friend class hxdeque;
147 iterator(hxdeque* deque_, hxsize_t index_) : const_iterator(deque_, index_) { }
148 iterator(const const_iterator& x_) : const_iterator(x_) { }
150 };
151
155 explicit hxdeque(hxsize_t dynamic_capacity_=0);
156
158 ~hxdeque(void);
159
162 hxattr_nodiscard const T_& operator[](hxsize_t index_) const;
163
165
169 hxattr_nodiscard bool operator==(const hxdeque& x_) const;
170
174 hxattr_nodiscard bool operator<(const hxdeque& x_) const;
175
177 const_iterator begin(void) const { return const_iterator(this, 0); }
178
179 iterator begin(void) { return iterator(this, 0); }
180
184 template<hxrange_concept_ range_t_>
185 void add_range(range_t_& range_) noexcept;
186
191 template<hxrange_concept_ range_t_,
192 hxenable_if_t<!hxis_lvalue_reference<range_t_>(), int> = 0>
193 void add_range(range_t_&& range_) noexcept;
194
197
198 hxattr_nodiscard const T_& back(void) const;
199
202
205 const_iterator cbegin(void) const { return const_iterator(this, 0); }
206
208 const_iterator cend(void) const { return const_iterator(this, this->size()); }
209
211 void clear(void) noexcept;
212
216 template<typename... args_t_>
217 void emplace_back(args_t_&&... args_) noexcept;
218
222 template<typename... args_t_>
223 void emplace_front(args_t_&&... args_) noexcept;
224
226 hxattr_nodiscard bool empty(void) const;
227
229 const_iterator end(void) const { return const_iterator(this, this->size()); }
230
231 iterator end(void) { return iterator(this, this->size()); }
232
235
236 hxattr_nodiscard const T_& front(void) const;
237
239 hxattr_nodiscard bool full(void) const;
240
242 hxattr_nodiscard hxsize_t max_size(void) const { return this->capacity(); }
243
245 void pop_back(void) noexcept;
246
248 void pop_front(void) noexcept;
249
253 template<typename... args_t_>
254 void push_back(args_t_&&... args_) noexcept;
255
259 template<typename... args_t_>
260 void push_front(args_t_&&... args_) noexcept;
261
265 void reserve(hxsize_t dynamic_capacity_);
266
269
270private:
271 // This is raw underlying data and would not be what was expected.
272 using hxallocator<T_, capacity_>::data;
273
274 hxdeque(const hxdeque&) = delete;
275 void operator=(const hxdeque&) = delete;
276
277 size_t m_head_;
278 size_t m_tail_;
279};
280
281#include "detail/hxdeque.inl"
282HX_NS_END_
const T * data(void) const
Returns a pointer to a const and potentially uninitialized array of T.
Definition hxallocator.hpp:96
hxallocator(void)
Does not allocate until reserve_storage is called.
Definition hxallocator.hpp:78
const_iterator - A const random-access iterator over logical indices.
Definition hxdeque.hpp:46
bool operator==(const const_iterator &x_) const
Compares two iterators for equality.
Definition hxdeque.hpp:85
const_iterator operator--(int)
Retreats the iterator to the previous element (post-decrement).
Definition hxdeque.hpp:81
const_iterator operator+(hxsize_t n_) const
Returns an iterator advanced by n positions.
Definition hxdeque.hpp:56
const_iterator operator-(hxsize_t n_) const
Returns an iterator retreated by n positions.
Definition hxdeque.hpp:60
const_iterator & operator--(void)
Retreats the iterator to the previous element.
Definition hxdeque.hpp:78
const_iterator & operator++(void)
Advances the iterator to the next element.
Definition hxdeque.hpp:72
const_iterator(void)
Constructs an end iterator.
Definition hxdeque.hpp:49
hxsize_t operator-(const const_iterator &x_) const
Returns the signed distance between two iterators.
Definition hxdeque.hpp:64
const T & operator[](hxsize_t n_) const
Returns a const reference to the element n positions ahead of this one.
Definition hxdeque.hpp:69
const_iterator operator++(int)
Advances the iterator to the next element (post-increment).
Definition hxdeque.hpp:75
bool operator<(const const_iterator &x_) const
Returns true when this iterator is ordered before x.
Definition hxdeque.hpp:89
const T & operator*(void) const
Returns a const reference to the element at the current position.
Definition hxdeque.hpp:52
iterator - A mutable random-access iterator over logical indices.
Definition hxdeque.hpp:108
hxsize_t operator-(const const_iterator &x_) const
Returns the signed distance from x to this position.
Definition hxdeque.hpp:126
T & operator*(void) const
Returns a reference to the element at the current position.
Definition hxdeque.hpp:114
iterator & operator--(void)
Retreats the iterator to the previous element.
Definition hxdeque.hpp:139
iterator operator+(hxsize_t n_) const
Returns an iterator advanced by n positions.
Definition hxdeque.hpp:118
iterator operator--(int)
Retreats the iterator to the previous element (post-decrement).
Definition hxdeque.hpp:142
iterator(void)
Constructs an end iterator.
Definition hxdeque.hpp:111
iterator operator++(int)
Advances the iterator to the next element (post-increment).
Definition hxdeque.hpp:136
iterator operator-(hxsize_t n_) const
Returns an iterator retreated by n positions.
Definition hxdeque.hpp:122
iterator & operator++(void)
Advances the iterator to the next element.
Definition hxdeque.hpp:133
T & operator[](hxsize_t n_) const
Returns a reference to the element n positions ahead of this one.
Definition hxdeque.hpp:130
hxdeque - A fixed-capacity deque backed by a power-of-two ring buffer.
Definition hxdeque.hpp:42
iterator end(void)
Definition hxdeque.hpp:231
T & front(void)
Returns a reference to the front element. The deque must not be empty.
void pop_back(void) noexcept
Removes and destroys the back element. The deque must not be empty.
void emplace_front(args_t_ &&... args_) noexcept
Constructs an element in place at the front using forwarded arguments.
iterator begin(void)
Definition hxdeque.hpp:179
const_iterator end(void) const
Returns a const iterator pointing past the last element.
Definition hxdeque.hpp:229
hxsize_t size(void) const
Returns the number of elements currently in the deque.
void emplace_back(args_t_ &&... args_) noexcept
Constructs an element in place at the back using forwarded arguments.
hxsize_t max_size(void) const
Returns the capacity of the deque or 0 if unallocated.
Definition hxdeque.hpp:242
void clear(void) noexcept
Destroys all elements and resets the deque to empty without deallocating.
bool empty(void) const
Returns true if the deque contains no elements.
const_iterator begin(void) const
Returns a const iterator pointing to the first element.
Definition hxdeque.hpp:177
bool full(void) const
Returns true if the deque is at capacity.
void add_range(range_t_ &range_) noexcept
Appends elements from a range referenced by an lvalue, copying each element with push_back.
bool operator<(const hxdeque &x_) const
Returns true if this deque compares less than x lexicographically, using hxkey_equal and hxkey_less.
const T & operator[](hxsize_t index_) const
Returns a const reference to the element at logical index index.
bool operator==(const hxdeque &x_) const
Returns true if this deque and x contain the same elements in the same order, using hxkey_equal.
const T & back(void) const
const_iterator cbegin(void) const
Returns a const iterator pointing to the first element (alias for begin).
Definition hxdeque.hpp:205
hxdeque(hxsize_t dynamic_capacity_=0)
Constructs an empty hxdeque.
void add_range(range_t_ &&range_) noexcept
Appends elements from a temporary range, moving each element with push_back.
void push_front(args_t_ &&... args_) noexcept
Prepends an element at the front using forwarded arguments.
T & operator[](hxsize_t index_)
T & back(void)
Returns a reference to the back element. The deque must not be empty.
~hxdeque(void)
Destroys all elements in the deque.
void pop_front(void) noexcept
Removes and destroys the front element. The deque must not be empty.
const T & front(void) const
void push_back(args_t_ &&... args_) noexcept
Appends an element at the back using forwarded arguments.
const_iterator cend(void) const
Returns a const iterator pointing past the last element.
Definition hxdeque.hpp:208
hxsize_t capacity(void) const
Returns the capacity of the deque or 0 if unallocated.
void reserve(hxsize_t dynamic_capacity_)
Allocates storage for a dynamic deque.
Similar to std::allocator.
Read-only range utilities for libhatchet.
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:98
A few utility functions and most standard C++ meta programming functions.
Provides core macros, memory management and feature detection.
#define hxnull
hxnull - The null pointer value for a given pointer type represented by the numeric literal 0.
Definition libhatchet.h:280
ptrdiff_t hxsize_t
hxsize_t - A signed size type, same as ssize_t or ptrdiff_t.
Definition libhatchet.h:207