[glacier] Add an IntrusiveList container
This commit is contained in:
parent
e1af79b975
commit
25737d9377
|
@ -0,0 +1,102 @@
|
|||
#pragma once
|
||||
|
||||
#include <glacier/memory/ref_ptr.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace glcr {
|
||||
|
||||
template <typename T>
|
||||
class IntrusiveListNode {
|
||||
public:
|
||||
RefPtr<T> next_;
|
||||
RefPtr<T> prev_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class IntrusiveList {
|
||||
public:
|
||||
IntrusiveList() : front_(nullptr), back_(nullptr) {}
|
||||
|
||||
void PushFront(const RefPtr<T>& obj);
|
||||
void PushBack(const RefPtr<T>& obj);
|
||||
|
||||
RefPtr<T> PopFront();
|
||||
RefPtr<T> PopBack();
|
||||
|
||||
RefPtr<T> PeekFront() { return front_; }
|
||||
RefPtr<T> PeekBack() { return back_; }
|
||||
|
||||
uint64_t size() { return size_; }
|
||||
|
||||
private:
|
||||
RefPtr<T> front_;
|
||||
RefPtr<T> back_;
|
||||
|
||||
uint64_t size_ = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void IntrusiveList<T>::PushFront(const RefPtr<T>& 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 <typename T>
|
||||
void IntrusiveList<T>::PushBack(const RefPtr<T>& obj) {
|
||||
if (front_ == nullptr) {
|
||||
PushFront(obj);
|
||||
return;
|
||||
}
|
||||
size_++;
|
||||
back_->next_ = obj;
|
||||
obj->prev_ = back_;
|
||||
obj->next_ = nullptr;
|
||||
back_ = obj;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
RefPtr<T> IntrusiveList<T>::PopFront() {
|
||||
if (front_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
size_--;
|
||||
if (front_ == back_) {
|
||||
RefPtr<T> ptr = front_;
|
||||
front_ = nullptr;
|
||||
back_ = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
RefPtr<T> ptr = front_;
|
||||
front_ = front_->next_;
|
||||
front_->prev_ = nullptr;
|
||||
ptr->next_ = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
RefPtr<T> IntrusiveList<T>::PopBack() {
|
||||
if (back_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (front_ == back_) {
|
||||
return PopFront();
|
||||
}
|
||||
size_--;
|
||||
RefPtr<T> ptr = back_;
|
||||
back_ = back_->prev_;
|
||||
back_->next_ = nullptr;
|
||||
ptr->prev_ = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
} // namespace glcr
|
Loading…
Reference in New Issue