util/IntrusiveList: add option `zero_initialized`
This commit is contained in:
parent
f01793ad4a
commit
7065425927
|
@ -15,6 +15,14 @@
|
|||
|
||||
struct IntrusiveListOptions {
|
||||
bool constant_time_size = false;
|
||||
|
||||
/**
|
||||
* Initialize the list head with nullptr (all zeroes) which
|
||||
* adds some code for checking nullptr, but may reduce the
|
||||
* data section for statically allocated lists. It's a
|
||||
* trade-off.
|
||||
*/
|
||||
bool zero_initialized = false;
|
||||
};
|
||||
|
||||
struct IntrusiveListNode {
|
||||
|
@ -143,7 +151,9 @@ template<typename T,
|
|||
class IntrusiveList {
|
||||
static constexpr bool constant_time_size = options.constant_time_size;
|
||||
|
||||
IntrusiveListNode head{&head, &head};
|
||||
IntrusiveListNode head = options.zero_initialized
|
||||
? IntrusiveListNode{nullptr, nullptr}
|
||||
: IntrusiveListNode{&head, &head};
|
||||
|
||||
[[no_unique_address]]
|
||||
OptionalCounter<constant_time_size> counter;
|
||||
|
@ -240,6 +250,10 @@ public:
|
|||
}
|
||||
|
||||
constexpr bool empty() const noexcept {
|
||||
if constexpr (options.zero_initialized)
|
||||
if (head.next == nullptr)
|
||||
return true;
|
||||
|
||||
return head.next == &head;
|
||||
}
|
||||
|
||||
|
@ -383,6 +397,10 @@ public:
|
|||
};
|
||||
|
||||
constexpr iterator begin() noexcept {
|
||||
if constexpr (options.zero_initialized)
|
||||
if (head.next == nullptr)
|
||||
return end();
|
||||
|
||||
return {head.next};
|
||||
}
|
||||
|
||||
|
@ -454,6 +472,10 @@ public:
|
|||
};
|
||||
|
||||
constexpr const_iterator begin() const noexcept {
|
||||
if constexpr (options.zero_initialized)
|
||||
if (head.next == nullptr)
|
||||
return end();
|
||||
|
||||
return {head.next};
|
||||
}
|
||||
|
||||
|
@ -498,6 +520,10 @@ public:
|
|||
GetHookMode() < IntrusiveHookMode::AUTO_UNLINK,
|
||||
"Can't use auto-unlink hooks with constant_time_size");
|
||||
|
||||
if constexpr (options.zero_initialized)
|
||||
if (head.next == nullptr)
|
||||
head = {&head, &head};
|
||||
|
||||
auto &existing_node = *p.cursor;
|
||||
auto &new_node = ToNode(t);
|
||||
|
||||
|
@ -535,6 +561,10 @@ public:
|
|||
if (_begin == _end)
|
||||
return;
|
||||
|
||||
if constexpr (options.zero_initialized)
|
||||
if (head.next == nullptr)
|
||||
head = {&head, &head};
|
||||
|
||||
auto &next_node = *position.cursor;
|
||||
auto &prev_node = *std::prev(position).cursor;
|
||||
|
||||
|
|
Loading…
Reference in New Issue