建档
This commit is contained in:
459
source/Tool/IntrusiveList.hpp
Normal file
459
source/Tool/IntrusiveList.hpp
Normal file
@@ -0,0 +1,459 @@
|
||||
#pragma once
|
||||
#include <type_traits>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 侵入式链表
|
||||
template <typename _PtrTy>
|
||||
class IntrusiveList
|
||||
{
|
||||
public:
|
||||
using value_type = typename std::pointer_traits<_PtrTy>::pointer;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
|
||||
IntrusiveList()
|
||||
: first_(), last_()
|
||||
{
|
||||
}
|
||||
|
||||
~IntrusiveList()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取首元素
|
||||
const value_type &GetFirst() const
|
||||
{
|
||||
return first_;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取首元素
|
||||
value_type &GetFirst()
|
||||
{
|
||||
return first_;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取尾元素
|
||||
const value_type &GetLast() const
|
||||
{
|
||||
return last_;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取尾元素
|
||||
value_type &GetLast()
|
||||
{
|
||||
return last_;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 链表是否为空
|
||||
inline bool IsEmpty() const
|
||||
{
|
||||
return first_ == nullptr;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 在链表尾部添加对象
|
||||
void PushBack(reference child)
|
||||
{
|
||||
if (child->GetPrev())
|
||||
child->GetPrev()->GetNext() = child->GetNext();
|
||||
if (child->GetNext())
|
||||
child->GetNext()->GetPrev() = child->GetPrev();
|
||||
|
||||
child->GetPrev() = last_;
|
||||
child->GetNext() = nullptr;
|
||||
|
||||
if (first_)
|
||||
{
|
||||
last_->GetNext() = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_ = child;
|
||||
}
|
||||
|
||||
last_ = child;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 在链表头部添加对象
|
||||
void PushFront(reference child)
|
||||
{
|
||||
if (child->GetPrev())
|
||||
child->GetPrev()->GetNext() = child->GetNext();
|
||||
if (child->GetNext())
|
||||
child->GetNext()->GetPrev() = child->GetPrev();
|
||||
|
||||
child->GetPrev() = nullptr;
|
||||
child->GetNext() = first_;
|
||||
|
||||
if (first_)
|
||||
{
|
||||
first_->GetPrev() = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_ = child;
|
||||
}
|
||||
|
||||
first_ = child;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 在链表的对象前插入新对象
|
||||
void InsertBefore(reference child, reference before)
|
||||
{
|
||||
if (child->GetPrev())
|
||||
child->GetPrev()->GetNext() = child->GetNext();
|
||||
if (child->GetNext())
|
||||
child->GetNext()->GetPrev() = child->GetPrev();
|
||||
|
||||
if (before->GetPrev())
|
||||
before->GetPrev()->GetNext() = child;
|
||||
else
|
||||
first_ = child;
|
||||
|
||||
child->GetPrev() = before->GetPrev();
|
||||
child->GetNext() = before;
|
||||
before->GetPrev() = child;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 在链表的对象后插入新对象
|
||||
void InsertAfter(reference child, reference after)
|
||||
{
|
||||
if (child->GetPrev())
|
||||
child->GetPrev()->GetNext() = child->GetNext();
|
||||
if (child->GetNext())
|
||||
child->GetNext()->GetPrev() = child->GetPrev();
|
||||
|
||||
if (after->GetNext())
|
||||
after->GetNext()->GetPrev() = child;
|
||||
else
|
||||
last_ = child;
|
||||
|
||||
child->GetNext() = after->GetNext();
|
||||
child->GetPrev() = after;
|
||||
after->GetNext() = child;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 移除对象
|
||||
void Remove(reference child)
|
||||
{
|
||||
if (child->GetNext())
|
||||
{
|
||||
child->GetNext()->GetPrev() = child->GetPrev();
|
||||
}
|
||||
else
|
||||
{
|
||||
last_ = child->GetPrev();
|
||||
}
|
||||
|
||||
if (child->GetPrev())
|
||||
{
|
||||
child->GetPrev()->GetNext() = child->GetNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
first_ = child->GetNext();
|
||||
}
|
||||
|
||||
child->GetPrev() = nullptr;
|
||||
child->GetNext() = nullptr;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 清空所有对象
|
||||
void Clear()
|
||||
{
|
||||
value_type p = first_;
|
||||
while (p)
|
||||
{
|
||||
value_type tmp = p;
|
||||
p = p->GetNext();
|
||||
if (tmp)
|
||||
{
|
||||
tmp->GetNext() = nullptr;
|
||||
tmp->GetPrev() = nullptr;
|
||||
}
|
||||
}
|
||||
first_ = nullptr;
|
||||
last_ = nullptr;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 检查链表是否有效
|
||||
bool CheckValid()
|
||||
{
|
||||
if (!first_)
|
||||
return true;
|
||||
|
||||
int pos = 0;
|
||||
|
||||
value_type p = first_;
|
||||
value_type tmp = p;
|
||||
do
|
||||
{
|
||||
tmp = p;
|
||||
p = p->GetNext();
|
||||
++pos;
|
||||
|
||||
if (p)
|
||||
{
|
||||
if (p->GetPrev() != tmp)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmp != last_)
|
||||
return false;
|
||||
}
|
||||
} while (p);
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename _IterPtrTy>
|
||||
struct Iterator
|
||||
{
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = _IterPtrTy;
|
||||
using pointer = _IterPtrTy *;
|
||||
using reference = _IterPtrTy &;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
inline Iterator(value_type ptr = nullptr, bool is_end = false)
|
||||
: base_(ptr), is_end_(is_end)
|
||||
{
|
||||
}
|
||||
|
||||
inline reference operator*() const
|
||||
{
|
||||
return const_cast<reference>(base_);
|
||||
}
|
||||
|
||||
inline pointer operator->() const
|
||||
{
|
||||
return std::pointer_traits<pointer>::pointer_to(**this);
|
||||
}
|
||||
|
||||
inline Iterator &operator++()
|
||||
{
|
||||
value_type next = base_->GetNext();
|
||||
if (next)
|
||||
base_ = next;
|
||||
else
|
||||
is_end_ = true;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline Iterator operator++(int)
|
||||
{
|
||||
Iterator old = (*this);
|
||||
++(*this);
|
||||
return old;
|
||||
}
|
||||
|
||||
inline Iterator &operator--()
|
||||
{
|
||||
if (is_end_)
|
||||
is_end_ = false;
|
||||
else
|
||||
base_ = base_->GetPrev();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline Iterator operator--(int)
|
||||
{
|
||||
Iterator old = (*this);
|
||||
--(*this);
|
||||
return old;
|
||||
}
|
||||
|
||||
inline bool operator==(const Iterator &other) const
|
||||
{
|
||||
return base_ == other.base_ && is_end_ == other.is_end_;
|
||||
}
|
||||
|
||||
inline bool operator!=(const Iterator &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
inline operator bool() const
|
||||
{
|
||||
return base_ != nullptr && !is_end_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_end_;
|
||||
|
||||
typename std::remove_const<value_type>::type base_;
|
||||
};
|
||||
|
||||
public:
|
||||
using iterator = Iterator<value_type>;
|
||||
using const_iterator = Iterator<const value_type>;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
inline iterator begin()
|
||||
{
|
||||
return iterator(first_, first_ == nullptr);
|
||||
}
|
||||
|
||||
inline const_iterator begin() const
|
||||
{
|
||||
return const_iterator(first_, first_ == nullptr);
|
||||
}
|
||||
|
||||
inline const_iterator cbegin() const
|
||||
{
|
||||
return begin();
|
||||
}
|
||||
|
||||
inline iterator end()
|
||||
{
|
||||
return iterator(last_, true);
|
||||
}
|
||||
|
||||
inline const_iterator end() const
|
||||
{
|
||||
return const_iterator(last_, true);
|
||||
}
|
||||
|
||||
inline const_iterator cend() const
|
||||
{
|
||||
return end();
|
||||
}
|
||||
|
||||
inline reverse_iterator rbegin()
|
||||
{
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
|
||||
inline const_reverse_iterator rbegin() const
|
||||
{
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
inline const_reverse_iterator crbegin() const
|
||||
{
|
||||
return rbegin();
|
||||
}
|
||||
|
||||
inline reverse_iterator rend()
|
||||
{
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
|
||||
inline const_reverse_iterator rend() const
|
||||
{
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
inline const_reverse_iterator crend() const
|
||||
{
|
||||
return rend();
|
||||
}
|
||||
|
||||
inline value_type &front()
|
||||
{
|
||||
if (IsEmpty())
|
||||
throw std::out_of_range("front() called on empty list");
|
||||
return first_;
|
||||
}
|
||||
|
||||
inline const value_type &front() const
|
||||
{
|
||||
if (IsEmpty())
|
||||
throw std::out_of_range("front() called on empty list");
|
||||
return first_;
|
||||
}
|
||||
|
||||
inline value_type &back()
|
||||
{
|
||||
if (IsEmpty())
|
||||
throw std::out_of_range("back() called on empty list");
|
||||
return last_;
|
||||
}
|
||||
|
||||
inline const value_type &back() const
|
||||
{
|
||||
if (IsEmpty())
|
||||
throw std::out_of_range("back() called on empty list");
|
||||
return last_;
|
||||
}
|
||||
|
||||
private:
|
||||
value_type first_;
|
||||
value_type last_;
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 侵入式链表元素
|
||||
template <typename _PtrTy>
|
||||
class IntrusiveListValue
|
||||
{
|
||||
public:
|
||||
using value_type = typename std::pointer_traits<_PtrTy>::pointer;
|
||||
using reference = value_type &;
|
||||
using pointer = value_type *;
|
||||
|
||||
IntrusiveListValue()
|
||||
: prev_(nullptr), next_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
IntrusiveListValue(value_type rhs)
|
||||
: prev_(nullptr), next_(nullptr)
|
||||
{
|
||||
if (rhs)
|
||||
{
|
||||
prev_ = rhs->GetPrev();
|
||||
next_ = rhs->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取前一元素
|
||||
const value_type &GetPrev() const
|
||||
{
|
||||
return prev_;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取前一元素
|
||||
value_type &GetPrev()
|
||||
{
|
||||
return prev_;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取下一元素
|
||||
const value_type &GetNext() const
|
||||
{
|
||||
return next_;
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取下一元素
|
||||
value_type &GetNext()
|
||||
{
|
||||
return next_;
|
||||
}
|
||||
|
||||
private:
|
||||
value_type prev_;
|
||||
value_type next_;
|
||||
|
||||
friend class IntrusiveList<_PtrTy>;
|
||||
};
|
||||
Reference in New Issue
Block a user