libhatchet
Loading...
Searching...
No Matches
hxconstexpr_list.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
11
12#include "libhatchet.h"
13
14// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
15#if HX_USE_MACROS_WITH_MODULE
16#error Header does not provide macros alone.
17#endif
18
19#include "hxrange.hpp"
20#include "hxptr.hpp"
21#include "hxutility.h"
22
23HX_NS_BEGIN_
24
25#if HX_CPLUSPLUS >= 202002L
28
29template<typename T_>
30concept hxconstexpr_list_concept_ = requires(T_& x_, T_* ptr_) {
31 sizeof(T_);
32 x_.~T_();
33 { ptr_ } -> hxconvertible_to<hxconstexpr_list_node*>; // T must derive from hxconstexpr_list_node
34};
36#else
37#define hxconstexpr_list_concept_ typename
38#endif
39
46public:
48 hxconstexpr hxconstexpr_list_node(void) : m_list_prev_(hxnull), m_list_next_(hxnull) { }
49
52
55 hxassertf(this != &x_, "self_assignment"); (void)x_;
56 return *this;
57 }
58
59private:
61 template<hxconstexpr_list_concept_, typename> friend class hxconstexpr_list;
62 hxconstexpr_list_node* m_list_prev_;
63 hxconstexpr_list_node* m_list_next_;
65};
66
94template<hxconstexpr_list_concept_ T_, typename deleter_t_=hxdefault_delete>
95class hxconstexpr_list : private deleter_t_ {
96public:
99 using node_t = T_;
100
103 public:
104 // GCOVR_EXCL_START
106 hxconstexpr const_iterator(void) : m_current_node_(hxnull)
108 , m_sentinel_(hxnull)
109#endif
110 { }
111 // GCOVR_EXCL_STOP
124 hxconstexpr bool operator==(const const_iterator& x_) const;
125#if HX_CPLUSPLUS < 202002L // C++20 defaults != from ==.
128 hxconstexpr bool operator!=(const const_iterator& x_) const { return !(*this == x_); }
129#endif
131 hxconstexpr const T_& operator*(void) const {
132 hxassertf(this->m_current_node_ != hxnull
133 && this->m_current_node_ != this->m_sentinel_, "bad_iter");
134 return *static_cast<const T_*>(m_current_node_);
135 }
136
137 hxconstexpr const T_* operator->(void) const {
138 hxassertf(this->m_current_node_ != hxnull
139 && this->m_current_node_ != this->m_sentinel_, "bad_iter");
140 return static_cast<const T_*>(m_current_node_);
141 }
142 protected:
144 template<hxconstexpr_list_concept_, typename> friend class hxconstexpr_list;
146 : m_current_node_(current_)
148 , m_sentinel_(sentinel_)
149#endif
150 { (void)sentinel_; }
151 hxconstexpr_list_node* m_current_node_;
152#if (HX_HARDENING_MODE) == HX_HARDENING_MODE_DEBUG
153 const hxconstexpr_list_node* m_sentinel_;
154#endif
156 };
157
159 class iterator : public const_iterator {
160 public:
161 // GCOVR_EXCL_START
164 // GCOVR_EXCL_STOP
176 hxconstexpr T_& operator*(void) const {
177 hxassertf(this->m_current_node_ != hxnull
178 && this->m_current_node_ != this->m_sentinel_, "bad_iter");
179 return *static_cast<T_*>(this->m_current_node_);
180 }
181
182 hxconstexpr T_* operator->(void) const {
183 hxassertf(this->m_current_node_ != hxnull
184 && this->m_current_node_ != this->m_sentinel_, "bad_iter");
185 return static_cast<T_*>(this->m_current_node_);
186 }
187 private:
189 template<hxconstexpr_list_concept_, typename> friend class hxconstexpr_list;
191 : const_iterator(current_, sentinel_) { }
194 };
195
198 hxconstexpr explicit hxconstexpr_list(deleter_t_ deleter_=deleter_t_());
199
202 hxconstexpr ~hxconstexpr_list(void) { this->clear(this->deleter()); }
203
208
213
219 template<hxrange_concept_ range_t_,
220 hxenable_if_t<!hxis_lvalue_reference<range_t_>(), int> = 0>
221 hxconstexpr void add_range(range_t_&& range_) noexcept;
222
224 hxattr_nodiscard hxconstexpr const T_& back(void) const;
225
227
229 hxconstexpr iterator begin(void) { return iterator(m_sentinel_.m_list_next_, &m_sentinel_); }
230
234
237 hxconstexpr const_iterator cbegin(void) const { return this->begin(); }
238
241 hxconstexpr const_iterator cend(void) const { return this->end(); }
242
246 template<typename deleter_u_>
247 hxconstexpr void clear(deleter_u_&& deleter_) noexcept;
248
250 hxinline hxconstexpr void clear(void) { this->clear(this->deleter()); }
251
254
257 hxconstexpr iterator end(void) { return iterator(&m_sentinel_, &m_sentinel_); }
258
262
267 template<typename deleter_u_>
268 hxconstexpr void erase(const_iterator it_, deleter_u_&& deleter_) noexcept;
269
273 hxconstexpr void erase(const_iterator it_) noexcept;
274
279
283 template<typename callable_t_>
284 hxattr_nodiscard hxconstexpr const_iterator find_if(callable_t_&& callable_) const;
285
286 template<typename callable_t_>
288
291 template<typename callable_t_>
292 hxconstexpr void for_each(callable_t_&& callable_) const;
293
294 template<typename callable_t_>
295 hxconstexpr void for_each(callable_t_&& callable_);
296
298 hxattr_nodiscard hxconstexpr const deleter_t_& deleter(void) const;
299
301
303 hxattr_nodiscard hxconstexpr const T_& front(void) const;
304
306
311 template<typename deleter_u_>
313
319
325 template<typename deleter_u_>
327
333
337
341
345 template<typename deleter_u_>
347
352
356 template<typename deleter_u_>
358
363
368
374 template<typename callable_t_, typename deleter_u_>
375 hxconstexpr hxsize_t remove_if(callable_t_&& callable_, deleter_u_&& deleter_) noexcept;
376
381 template<typename callable_t_>
382 hxconstexpr hxsize_t remove_if(callable_t_&& callable_) noexcept;
383
386
388 hxattr_nodiscard hxconstexpr hxsize_t size(void) const { return m_size_; }
389
395
396private:
397 hxconstexpr_list(const hxconstexpr_list&) = delete;
399 hxconstexpr_list& operator=(const hxconstexpr_list&) = delete;
400 hxconstexpr_list& operator=(hxconstexpr_list&&) = delete;
401
402 hxconstexpr void insert_(hxconstexpr_list_node* prev_, hxconstexpr_list_node* next_,
404 hxconstexpr void extract_(hxconstexpr_list_node* ptr_);
405
406 hxsize_t m_size_;
407 hxconstexpr_list_node m_sentinel_;
408};
409
410#include "detail/hxconstexpr_list.inl"
411HX_NS_END_
const_iterator - Bidirectional iterator over const nodes.
Definition hxconstexpr_list.hpp:102
constexpr bool operator==(const const_iterator &x_) const
Returns true if both iterators point to the same node.
constexpr const_iterator(void)
Constructs an iterator that must not be incremented or dereferenced.
Definition hxconstexpr_list.hpp:106
constexpr const_iterator & operator--(void)
Retreats to the previous node and returns this iterator.
constexpr const_iterator & operator++(void)
Advances to the next node and returns this iterator.
constexpr const T & operator*(void) const
Returns a const reference to the current node.
Definition hxconstexpr_list.hpp:131
constexpr const_iterator operator--(int)
Post-decrement: retreats to the previous node and returns the prior position.
constexpr const T * operator->(void) const
Returns a const pointer to the current node.
Definition hxconstexpr_list.hpp:137
constexpr const_iterator operator++(int)
Post-increment: advances to the next node and returns the prior position.
iterator - Bidirectional iterator over mutable nodes.
Definition hxconstexpr_list.hpp:159
constexpr iterator operator--(int)
Post-decrement: retreats to the previous node and returns the prior position.
constexpr iterator & operator++(void)
Advances to the next node and returns this iterator.
Definition hxconstexpr_list.hpp:166
constexpr iterator & operator--(void)
Retreats to the previous node and returns this iterator.
Definition hxconstexpr_list.hpp:171
constexpr T & operator*(void) const
Returns a mutable reference to the current node.
Definition hxconstexpr_list.hpp:176
constexpr iterator operator++(int)
Post-increment: advances to the next node and returns the prior position.
constexpr iterator(void)
Constructs an iterator that must not be incremented or dereferenced.
Definition hxconstexpr_list.hpp:163
constexpr T * operator->(void) const
Returns a mutable pointer to the current node.
Definition hxconstexpr_list.hpp:182
hxconstexpr_list_node - Intrusive doubly linked list node base.
Definition hxconstexpr_list.hpp:45
constexpr hxconstexpr_list_node(void)
Constructs an unlinked node.
Definition hxconstexpr_list.hpp:48
constexpr hxconstexpr_list_node & operator=(const hxconstexpr_list_node &x_)
Assigns nothing. List linkage of either node is not affected.
Definition hxconstexpr_list.hpp:54
constexpr hxconstexpr_list_node(const hxconstexpr_list_node &)
Constructs an unlinked node.
Definition hxconstexpr_list.hpp:51
hxconstexpr_list - An intrusive doubly linked list that takes ownership of nodes via a deleter_t call...
Definition hxconstexpr_list.hpp:95
constexpr const_iterator find_if(callable_t_ &&callable_) const
Finds the first node for which the predicate returns true.
constexpr iterator insert_after(const_iterator it_, T *ptr_)
insert_after - Inserts ptr immediately after it.
constexpr void erase(const_iterator it_, deleter_u_ &&deleter_) noexcept
Unlinks the node at it and if deleter is true then calls deleter on it.
constexpr void erase(const_iterator it_) noexcept
Unlinks the node at it and calls the stored deleter on it if it evaluates to true.
constexpr hxsize_t remove_if(callable_t_ &&callable_) noexcept
Removes all nodes for which predicate returns true, invoking the stored deleter on each removed node.
constexpr bool operator<(const hxconstexpr_list &x_) const
Returns true if this list compares less than x lexicographically, using T's operator== and operator<.
constexpr hxconstexpr_list(deleter_t_ deleter_=deleter_t_())
Constructs an empty list with an optional deleter instance.
constexpr 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.
constexpr void for_each(callable_t_ &&callable_) const
Calls a function, lambda, or std::function on each node.
constexpr const T & front(void) const
Returns a const reference to the first node. The list must not be empty.
constexpr bool empty(void) const
Returns true if the list contains no nodes.
constexpr const_iterator begin(void) const
Returns a const iterator to the first node, or end() if the list is empty.
constexpr void reverse(void)
Reverses the order of nodes in the list in-place.
constexpr bool operator==(const hxconstexpr_list &x_) const
Returns true if this list and x contain the same nodes in the same order, using T's operator==.
constexpr const_iterator cbegin(void) const
Returns a const iterator to the first node, or cend() if the list is empty.
Definition hxconstexpr_list.hpp:237
constexpr hxptr< T, deleter_t_ > extract(const_iterator it_)
extract - Returns an hxptr owning the node at it after unlinking it from the list.
constexpr iterator insert(const_iterator it_, T *ptr_)
insert - Inserts ptr immediately before it.
constexpr deleter_t_ & deleter(void)
constexpr iterator find_if(callable_t_ &&callable_)
constexpr void for_each(callable_t_ &&callable_)
constexpr iterator end(void)
Returns an iterator to the sentinel, representing one past the last node.
Definition hxconstexpr_list.hpp:257
constexpr void release_all(void)
Resets the list to empty without invoking the deleter on any node.
constexpr iterator push_front(T *ptr_)
push_front - Inserts ptr at the front of the list.
constexpr ~hxconstexpr_list(void)
Destroys the list by calling clear(), which invokes the deleter on every remaining node.
Definition hxconstexpr_list.hpp:202
constexpr hxsize_t size(void) const
Returns the number of nodes currently in the list.
Definition hxconstexpr_list.hpp:388
constexpr void clear(void)
Removes all nodes using the stored deleter.
Definition hxconstexpr_list.hpp:250
constexpr const_iterator cend(void) const
Returns a const iterator to the sentinel, representing one past the last node.
Definition hxconstexpr_list.hpp:241
constexpr void clear(deleter_u_ &&deleter_) noexcept
Removes all nodes, invoking deleter on each.
constexpr iterator push_back(hxptr< T, deleter_u_ > &&ptr_)
push_back - Inserts the node owned by ptr at the back of the list.
T node_t
T - The node type stored in the list.
Definition hxconstexpr_list.hpp:99
constexpr const_iterator end(void) const
Returns a const iterator to the sentinel, representing one past the last node.
constexpr iterator push_front(hxptr< T, deleter_u_ > &&ptr_)
push_front - Inserts the node owned by ptr at the front of the list.
constexpr T & back(void)
constexpr const deleter_t_ & deleter(void) const
Returns a const reference to the stored deleter.
constexpr void splice(const_iterator it_, hxconstexpr_list &x_)
Transfers all nodes from x and inserts them before it, taking ownership.
constexpr iterator push_back(T *ptr_)
push_back - Inserts ptr at the back of the list.
constexpr hxptr< T, deleter_t_ > pop_back(void)
pop_back - Returns an hxptr owning the last node.
constexpr const T & back(void) const
Returns a const reference to the last node. The list must not be empty.
constexpr void add_range(range_t_ &&range_) noexcept
Links each T from a temporary range into this list by address, exactly as push_back(T*) would.
constexpr iterator insert(const_iterator it_, hxptr< T, deleter_u_ > &&ptr_)
insert - Inserts the node owned by ptr immediately before it.
constexpr iterator begin(void)
Returns an iterator to the first node, or end() if the list is empty.
Definition hxconstexpr_list.hpp:229
constexpr hxptr< T, deleter_t_ > pop_front(void)
pop_front - Returns an hxptr owning the first node.
constexpr T & front(void)
constexpr iterator insert_after(const_iterator it_, hxptr< T, deleter_u_ > &&ptr_)
insert_after - Inserts the node owned by ptr immediately after it.
hxptr<T, deleter_t> - A unique owning pointer.
Definition hxptr.hpp:30
hxconvertible_to - A concept that requires one type to be convertible to another.
Definition hxutility.h:255
A unique owning pointer.
Read-only range utilities for libhatchet.
#define hxinline
hxinline - Force a function to be inlined into its callers.
Definition hxsettings.h:125
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:98
#define hxconstexpr
hxconstexpr - Enables C++23 compatable constexpr usage for functions as that has support for destruct...
Definition hxsettings.h:266
A few utility functions and most standard C++ meta programming functions.
Provides core macros, memory management and feature detection.
#define hxassertf(x_,...)
hxassertf(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 literal 0.
Definition libhatchet.h:280
#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:207