103 lines
1.8 KiB
C++
103 lines
1.8 KiB
C++
#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
|