util/IntrusiveList: add option zero_initialized
This commit is contained in:
parent
f01793ad4a
commit
7065425927
@ -15,6 +15,14 @@
|
|||||||
|
|
||||||
struct IntrusiveListOptions {
|
struct IntrusiveListOptions {
|
||||||
bool constant_time_size = false;
|
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 {
|
struct IntrusiveListNode {
|
||||||
@ -143,7 +151,9 @@ template<typename T,
|
|||||||
class IntrusiveList {
|
class IntrusiveList {
|
||||||
static constexpr bool constant_time_size = options.constant_time_size;
|
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]]
|
[[no_unique_address]]
|
||||||
OptionalCounter<constant_time_size> counter;
|
OptionalCounter<constant_time_size> counter;
|
||||||
@ -240,6 +250,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool empty() const noexcept {
|
constexpr bool empty() const noexcept {
|
||||||
|
if constexpr (options.zero_initialized)
|
||||||
|
if (head.next == nullptr)
|
||||||
|
return true;
|
||||||
|
|
||||||
return head.next == &head;
|
return head.next == &head;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,6 +397,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
constexpr iterator begin() noexcept {
|
constexpr iterator begin() noexcept {
|
||||||
|
if constexpr (options.zero_initialized)
|
||||||
|
if (head.next == nullptr)
|
||||||
|
return end();
|
||||||
|
|
||||||
return {head.next};
|
return {head.next};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,6 +472,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
constexpr const_iterator begin() const noexcept {
|
constexpr const_iterator begin() const noexcept {
|
||||||
|
if constexpr (options.zero_initialized)
|
||||||
|
if (head.next == nullptr)
|
||||||
|
return end();
|
||||||
|
|
||||||
return {head.next};
|
return {head.next};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,6 +520,10 @@ public:
|
|||||||
GetHookMode() < IntrusiveHookMode::AUTO_UNLINK,
|
GetHookMode() < IntrusiveHookMode::AUTO_UNLINK,
|
||||||
"Can't use auto-unlink hooks with constant_time_size");
|
"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 &existing_node = *p.cursor;
|
||||||
auto &new_node = ToNode(t);
|
auto &new_node = ToNode(t);
|
||||||
|
|
||||||
@ -535,6 +561,10 @@ public:
|
|||||||
if (_begin == _end)
|
if (_begin == _end)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if constexpr (options.zero_initialized)
|
||||||
|
if (head.next == nullptr)
|
||||||
|
head = {&head, &head};
|
||||||
|
|
||||||
auto &next_node = *position.cursor;
|
auto &next_node = *position.cursor;
|
||||||
auto &prev_node = *std::prev(position).cursor;
|
auto &prev_node = *std::prev(position).cursor;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user