From 25737d93772968c00664a5dc1efaa79db80f4c23 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Wed, 21 Jun 2023 16:28:19 -0700 Subject: [PATCH] [glacier] Add an IntrusiveList container --- lib/glacier/container/intrusive_list.h | 102 +++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 lib/glacier/container/intrusive_list.h diff --git a/lib/glacier/container/intrusive_list.h b/lib/glacier/container/intrusive_list.h new file mode 100644 index 0000000..8957a32 --- /dev/null +++ b/lib/glacier/container/intrusive_list.h @@ -0,0 +1,102 @@ +#pragma once + +#include +#include + +namespace glcr { + +template +class IntrusiveListNode { + public: + RefPtr next_; + RefPtr prev_; +}; + +template +class IntrusiveList { + public: + IntrusiveList() : front_(nullptr), back_(nullptr) {} + + void PushFront(const RefPtr& obj); + void PushBack(const RefPtr& obj); + + RefPtr PopFront(); + RefPtr PopBack(); + + RefPtr PeekFront() { return front_; } + RefPtr PeekBack() { return back_; } + + uint64_t size() { return size_; } + + private: + RefPtr front_; + RefPtr back_; + + uint64_t size_ = 0; +}; + +template +void IntrusiveList::PushFront(const RefPtr& obj) { + // FIXME: Check to make sure obj next and prev aren't set. + size_++; + obj->next_ = front_; + obj->prev_ = nullptr; + if (front_ == nullptr) { + front_ = obj; + back_ = obj; + return; + } + + front_->prev_ = obj; + front_ = obj; +} + +template +void IntrusiveList::PushBack(const RefPtr& obj) { + if (front_ == nullptr) { + PushFront(obj); + return; + } + size_++; + back_->next_ = obj; + obj->prev_ = back_; + obj->next_ = nullptr; + back_ = obj; +} + +template +RefPtr IntrusiveList::PopFront() { + if (front_ == nullptr) { + return nullptr; + } + size_--; + if (front_ == back_) { + RefPtr ptr = front_; + front_ = nullptr; + back_ = nullptr; + return ptr; + } + RefPtr ptr = front_; + front_ = front_->next_; + front_->prev_ = nullptr; + ptr->next_ = nullptr; + return ptr; +} + +template +RefPtr IntrusiveList::PopBack() { + if (back_ == nullptr) { + return nullptr; + } + if (front_ == back_) { + return PopFront(); + } + size_--; + RefPtr ptr = back_; + back_ = back_->prev_; + back_->next_ = nullptr; + ptr->prev_ = nullptr; + return ptr; +} + +} // namespace glcr