#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