libhatchet
Loading...
Searching...
No Matches
hxlist.hpp
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: © 2017-2026 Adrian Johnston.
3// SPDX-License-Identifier: MIT
4// This file is licensed under the MIT license found in the LICENSE.md file.
5
10
11#include "libhatchet.h"
12
13// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
14#if HX_USE_MACROS_WITH_MODULE
15#error Header does not provide macros alone.
16#endif
17
18#include "hxptr.hpp"
19#include "hxutility.h"
20
21HX_NS_BEGIN_
22
29public:
31 hxlist_node(void) : m_list_link_(0) { }
32
35
38 hxassertmsg(this != &other_, "self_assignment"); (void)other_;
39 return *this;
40 }
41
42private:
44 template<typename, typename> friend class hxlist;
45 intptr_t m_list_link_; // Previous address XOR next address.
47};
48
78template<typename T_, typename deleter_t_=hxdefault_delete>
79class hxlist : private deleter_t_ {
80public:
81 using T = T_;
82
85 public:
87 const_iterator(void) : m_prev_(hxnull), m_current_node_(hxnull)
89 , m_sentinel_(hxnull)
90#endif
91 { }
92
104 bool operator==(const const_iterator& x_) const;
105#if HX_CPLUSPLUS < 202002L // C++20 defaults != from ==.
108 bool operator!=(const const_iterator& x_) const { return !(*this == x_); }
109#endif
111 const T_& operator*(void) const {
112 hxassertmsg(this->m_current_node_ != hxnull
113 && this->m_current_node_ != this->m_sentinel_, "invalid_iterator");
114 return *static_cast<const T_*>(m_current_node_);
115 }
116
117 const T_* operator->(void) const {
118 hxassertmsg(this->m_current_node_ != hxnull
119 && this->m_current_node_ != this->m_sentinel_, "invalid_iterator");
120 return static_cast<const T_*>(m_current_node_);
121 }
122 protected:
124 template<typename, typename> friend class hxlist;
125 const_iterator(hxlist_node* prev_, hxlist_node* current_, const hxlist_node* sentinel_)
126 : m_prev_(prev_), m_current_node_(current_)
128 , m_sentinel_(sentinel_)
129#endif
130 { (void)sentinel_; }
131 hxlist_node* m_prev_;
132 hxlist_node* m_current_node_;
133#if (HX_HARDENING_MODE) == HX_HARDENING_MODE_DEBUG
134 const hxlist_node* m_sentinel_;
135#endif
137 };
138
140 class iterator : public const_iterator {
141 public:
143 iterator(void) { }
153 T_& operator*(void) const {
154 hxassertmsg(this->m_current_node_ != hxnull
155 && this->m_current_node_ != this->m_sentinel_, "invalid_iterator");
156 return *static_cast<T_*>(this->m_current_node_);
157 }
158
159 T_* operator->(void) const {
160 hxassertmsg(this->m_current_node_ != hxnull
161 && this->m_current_node_ != this->m_sentinel_, "invalid_iterator");
162 return static_cast<T_*>(this->m_current_node_);
163 }
164 private:
166 template<typename, typename> friend class hxlist;
167 iterator(hxlist_node* prev_, hxlist_node* current_, const hxlist_node* sentinel_)
168 : const_iterator(prev_, current_, sentinel_) { }
170 };
171
174 explicit hxlist(deleter_t_ deleter_=deleter_t_());
175
178 ~hxlist(void) { this->clear(this->deleter()); }
179
182
184 hxattr_nodiscard const T_& back(void) const;
185
188
191
193 const_iterator cbegin(void) const { return this->begin(); }
194
196 const_iterator cend(void) const { return this->end(); }
197
201 template<typename deleter_u_>
202 void clear(deleter_u_&& deleter_) noexcept;
203
205 void clear(void) { this->clear(this->deleter()); }
206
208 hxattr_nodiscard bool empty(void) const { return m_size_ == 0; }
209
213
216 const_iterator end(void) const;
217
222 template<typename deleter_u_>
223 void erase(const_iterator pos_, deleter_u_&& deleter_) noexcept;
224
227 void erase(const_iterator pos_) noexcept;
228
233
237 template<typename callable_t_>
238 hxattr_nodiscard const_iterator find_if(callable_t_&& callable_) const;
239
241 template<typename callable_t_>
242 hxattr_nodiscard iterator find_if(callable_t_&& callable_);
243
246 template<typename callable_t_>
247 void for_each(callable_t_&& callable_) const;
248
250 template<typename callable_t_>
251 void for_each(callable_t_&& callable_);
252
254 hxattr_nodiscard const deleter_t_& deleter(void) const;
255
257 hxattr_nodiscard deleter_t_& deleter(void);
258
261
263 hxattr_nodiscard const T_& front(void) const;
264
269 template<typename deleter_u_>
271
277
282 template<typename deleter_u_>
284
290
294
298
302 template<typename deleter_u_>
304
309
313 template<typename deleter_u_>
315
320
324 void release_all(void);
325
331 template<typename callable_t_, typename deleter_u_>
332 hxsize_t remove_if(callable_t_&& callable_, deleter_u_&& deleter_) noexcept;
333
337 template<typename callable_t_>
338 hxsize_t remove_if(callable_t_&& callable_) noexcept;
339
342 void reverse(void);
343
345 hxattr_nodiscard hxsize_t size(void) const { return m_size_; }
346
351 void splice(const_iterator pos_, hxlist& other_);
352
353private:
354 hxlist(const hxlist&) = delete;
355 hxlist(hxlist&&) = delete;
356 hxlist& operator=(const hxlist&) = delete;
357 hxlist& operator=(hxlist&&) = delete;
358
359 void insert_(hxlist_node* prev_, hxlist_node* next_, hxlist_node* ptr_);
360 void extract_(hxlist_node* prev_, hxlist_node* ptr_);
361
362 hxsize_t m_size_;
363 hxlist_node m_sentinel_;
364 // When empty m_sentinel_.m_list_link_ == 0 and m_tail_ == &m_sentinel_.
365 hxlist_node* m_tail_;
366};
367
368#include "detail/hxlist.inl"
369HX_NS_END_
const_iterator - Bidirectional iterator over const nodes.
Definition hxlist.hpp:84
const_iterator(void)
Constructs an iterator that must not be incremented or dereferenced.
Definition hxlist.hpp:87
const T & operator*(void) const
Returns a const reference to the current node.
Definition hxlist.hpp:111
const_iterator & operator++(void)
Advances to the next node and returns this iterator.
const_iterator operator--(int)
Post-decrement: retreats to the previous node and returns the prior position.
const_iterator & operator--(void)
Retreats to the previous node and returns this iterator.
const_iterator operator++(int)
Post-increment: advances to the next node and returns the prior position.
const T * operator->(void) const
Returns a const pointer to the current node.
Definition hxlist.hpp:117
bool operator==(const const_iterator &x_) const
Returns true if both iterators point to the same node.
iterator - Bidirectional iterator over mutable nodes.
Definition hxlist.hpp:140
iterator & operator++(void)
Advances to the next node and returns this iterator.
Definition hxlist.hpp:145
iterator operator--(int)
Post-decrement: retreats to the previous node and returns the prior position.
T & operator*(void) const
Returns a mutable reference to the current node.
Definition hxlist.hpp:153
iterator & operator--(void)
Retreats to the previous node and returns this iterator.
Definition hxlist.hpp:149
T * operator->(void) const
Returns a mutable pointer to the current node.
Definition hxlist.hpp:159
iterator operator++(int)
Post-increment: advances to the next node and returns the prior position.
iterator(void)
Constructs an iterator that must not be incremented or dereferenced.
Definition hxlist.hpp:143
hxlist_node - Intrusive doubly linked list node base.
Definition hxlist.hpp:28
hxlist_node(const hxlist_node &)
Constructs an unlinked node.
Definition hxlist.hpp:34
hxlist_node(void)
Constructs an unlinked node.
Definition hxlist.hpp:31
hxlist_node & operator=(const hxlist_node &other_)
Assigns nothing. List linkage of either node is not affected.
Definition hxlist.hpp:37
hxlist - An intrusive doubly linked list that takes ownership of nodes via a deleter_t callable,...
Definition hxlist.hpp:79
const T & front(void) const
Returns a const reference to the first node. The list must not be empty.
hxsize_t size(void) const
Returns the number of nodes currently in the list.
Definition hxlist.hpp:345
iterator end(void)
Returns an iterator to the sentinel, representing one past the last node.
hxsize_t remove_if(callable_t_ &&callable_, deleter_u_ &&deleter_) noexcept
Removes all nodes for which predicate returns true, invoking deleter on each removed node.
iterator push_back(hxptr< T, deleter_u_ > &&ptr_)
push_back - Inserts the node owned by ptr at the back of the list.
void erase(const_iterator pos_) noexcept
Unlinks and deletes the node at pos using the stored deleter.
iterator insert(const_iterator pos_, hxptr< T, deleter_u_ > &&ptr_)
insert - Inserts the node owned by ptr immediately before pos.
const T & back(void) const
Returns a const reference to the last node. The list must not be empty.
~hxlist(void)
Destroys the list by calling clear(), which invokes the deleter on every remaining node.
Definition hxlist.hpp:178
void release_all(void)
Resets the list to empty without invoking the deleter on any node.
const deleter_t_ & deleter(void) const
Returns a const reference to the stored deleter.
deleter_t_ & deleter(void)
Returns a reference to the stored deleter.
iterator push_front(hxptr< T, deleter_u_ > &&ptr_)
push_front - Inserts the node owned by ptr at the front of the list.
iterator push_front(T *ptr_)
push_front - Inserts ptr at the front of the list.
const_iterator cbegin(void) const
Returns a const iterator to the first node, or cend() if the list is empty.
Definition hxlist.hpp:193
void erase(const_iterator pos_, deleter_u_ &&deleter_) noexcept
Unlinks the node at pos and invokes deleter on it.
iterator find_if(callable_t_ &&callable_)
Non-const version of find_if.
iterator insert_after(const_iterator pos_, T *ptr_)
insert_after - Inserts ptr immediately after pos.
const_iterator cend(void) const
Returns a const iterator to the sentinel, representing one past the last node.
Definition hxlist.hpp:196
iterator insert(const_iterator pos_, T *ptr_)
insert - Inserts ptr immediately before pos.
T & front(void)
Returns a reference to the first node. The list must not be empty.
hxptr< T, deleter_t_ > extract(const_iterator pos_)
extract - Returns an hxptr owning the node at pos after unlinking it from the list.
iterator begin(void)
Returns an iterator to the first node, or end() if the list is empty.
const_iterator begin(void) const
Returns a const iterator to the first node, or end() if the list is empty.
void clear(deleter_u_ &&deleter_) noexcept
Removes all nodes, invoking deleter on each.
hxlist(deleter_t_ deleter_=deleter_t_())
Constructs an empty list with an optional deleter instance.
const_iterator find_if(callable_t_ &&callable_) const
Finds the first node for which the predicate returns true.
iterator push_back(T *ptr_)
push_back - Inserts ptr at the back of the list.
iterator insert_after(const_iterator pos_, hxptr< T, deleter_u_ > &&ptr_)
insert_after - Inserts the node owned by ptr immediately after pos.
hxptr< T, deleter_t_ > pop_front(void)
pop_front - Returns an hxptr owning the first node.
void for_each(callable_t_ &&callable_)
Non-const version of for_each.
bool empty(void) const
Returns true if the list contains no nodes.
Definition hxlist.hpp:208
void splice(const_iterator pos_, hxlist &other_)
Transfers all nodes from other and inserts them before pos, taking ownership.
hxsize_t remove_if(callable_t_ &&callable_) noexcept
Removes all nodes for which predicate returns true, invoking the stored deleter on each removed node.
T T
Definition hxlist.hpp:81
T & back(void)
Returns a reference to the last node. The list must not be empty.
hxptr< T, deleter_t_ > pop_back(void)
pop_back - Returns an hxptr owning the last node.
const_iterator end(void) const
Returns a const iterator to the sentinel, representing one past the last node.
void reverse(void)
Reverses the order of nodes in the list in-place.
void for_each(callable_t_ &&callable_) const
Calls a function, lambda, or std::function on each node.
void clear(void)
Removes all nodes using the stored deleter.
Definition hxlist.hpp:205
hxptr<T, deleter_t> - A unique owning pointer.
Definition hxptr.hpp:30
A unique owning pointer.
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:89
A few utility functions and most standard C++ meta programming functions.
Provides core macros, memory management and feature detection.
#define hxassertmsg(x_,...)
hxassertmsg(bool x, ...) - Logs an error and terminates execution if x is false.
Definition libhatchet.h:101
#define hxnull
hxnull - The null pointer value for a given pointer type represented by the numeric constant 0.
Definition libhatchet.h:277
#define HX_HARDENING_MODE
HX_HARDENING_MODE - Library hardening level. See the README.md for levels.
Definition libhatchet.h:51
#define HX_HARDENING_MODE_DEBUG
HX_HARDENING_MODE_DEBUG - Provides comprehensive asserts and verbose output.
Definition libhatchet.h:64
ptrdiff_t hxsize_t
hxsize_t - A signed size type, same as ssize_t or ptrdiff_t.
Definition libhatchet.h:209