Make LinkedList a lot better
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
09e447d9d2
commit
b5c6ae253d
@ -12,10 +12,31 @@ template <typename T> class DoublyLinkedList;
|
|||||||
|
|
||||||
template <typename T> class DoublyLinkedListNode
|
template <typename T> class DoublyLinkedListNode
|
||||||
{
|
{
|
||||||
|
using SelfType = DoublyLinkedListNode<T>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DoublyLinkedListNode<T>* m_next_node;
|
SelfType* m_next_node;
|
||||||
DoublyLinkedListNode<T>* m_last_node;
|
SelfType* m_last_node;
|
||||||
|
|
||||||
|
void set_next(SelfType* next)
|
||||||
|
{
|
||||||
|
m_next_node = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_last(SelfType* last)
|
||||||
|
{
|
||||||
|
m_last_node = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelfType* get_next()
|
||||||
|
{
|
||||||
|
return m_next_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelfType* get_last()
|
||||||
|
{
|
||||||
|
return m_last_node;
|
||||||
|
}
|
||||||
|
|
||||||
void detach_from_list()
|
void detach_from_list()
|
||||||
{
|
{
|
||||||
@ -23,7 +44,7 @@ template <typename T> class DoublyLinkedListNode
|
|||||||
m_last_node->m_next_node = m_next_node;
|
m_last_node->m_next_node = m_next_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_to_list(DoublyLinkedListNode<T>* end_node)
|
void add_to_list(SelfType* end_node)
|
||||||
{
|
{
|
||||||
end_node->m_next_node = this;
|
end_node->m_next_node = this;
|
||||||
this->m_last_node = end_node;
|
this->m_last_node = end_node;
|
||||||
@ -34,14 +55,19 @@ template <typename T> class DoublyLinkedListNode
|
|||||||
|
|
||||||
template <typename T> class DoublyLinkedList
|
template <typename T> class DoublyLinkedList
|
||||||
{
|
{
|
||||||
|
using Node = DoublyLinkedListNode<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void append(T* ptr)
|
void append(T* ptr)
|
||||||
{
|
{
|
||||||
DoublyLinkedListNode<T>* node = (DoublyLinkedListNode<T>*)ptr;
|
Node* const node = extract_node(ptr);
|
||||||
if (!m_start_node) m_start_node = node;
|
if (!m_start_node) m_start_node = node;
|
||||||
if (m_end_node) node->add_to_list(m_end_node);
|
if (m_end_node) node->add_to_list(m_end_node);
|
||||||
else
|
else
|
||||||
node->m_next_node = node->m_last_node = nullptr;
|
{
|
||||||
|
node->set_next(nullptr);
|
||||||
|
node->set_last(nullptr);
|
||||||
|
}
|
||||||
m_end_node = node;
|
m_end_node = node;
|
||||||
|
|
||||||
m_count++;
|
m_count++;
|
||||||
@ -49,24 +75,24 @@ template <typename T> class DoublyLinkedList
|
|||||||
|
|
||||||
void append_after(T* base, T* ptr)
|
void append_after(T* base, T* ptr)
|
||||||
{
|
{
|
||||||
DoublyLinkedListNode<T>* new_node = (DoublyLinkedListNode<T>*)ptr;
|
Node* const new_node = extract_node(ptr);
|
||||||
DoublyLinkedListNode<T>* base_node = (DoublyLinkedListNode<T>*)base;
|
Node* const base_node = extract_node(base);
|
||||||
|
|
||||||
if (m_end_node == base_node) m_end_node = new_node;
|
if (m_end_node == base_node) m_end_node = new_node;
|
||||||
|
|
||||||
new_node->m_next_node = base_node->m_next_node;
|
new_node->set_next(base_node->get_next());
|
||||||
base_node->m_next_node = new_node;
|
base_node->set_next(new_node);
|
||||||
new_node->m_last_node = base_node;
|
new_node->set_last(base_node);
|
||||||
|
|
||||||
m_count++;
|
m_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* remove(T* ptr)
|
T* remove(T* ptr)
|
||||||
{
|
{
|
||||||
DoublyLinkedListNode<T>* node = (DoublyLinkedListNode<T>*)ptr;
|
Node* const node = extract_node(ptr);
|
||||||
|
|
||||||
if (node == m_end_node) m_end_node = node->m_last_node;
|
if (node == m_end_node) m_end_node = node->get_last();
|
||||||
if (node == m_start_node) m_start_node = node->m_next_node;
|
if (node == m_start_node) m_start_node = node->get_next();
|
||||||
|
|
||||||
node->detach_from_list();
|
node->detach_from_list();
|
||||||
|
|
||||||
@ -87,40 +113,32 @@ template <typename T> class DoublyLinkedList
|
|||||||
|
|
||||||
Result<T*> next(T* item)
|
Result<T*> next(T* item)
|
||||||
{
|
{
|
||||||
return nonnull_or_error((T*)((DoublyLinkedListNode<T>*)item)->m_next_node);
|
return nonnull_or_error((T*)extract_node(item)->get_next());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<T*> previous(T* item)
|
Result<T*> previous(T* item)
|
||||||
{
|
{
|
||||||
return nonnull_or_error((T*)((DoublyLinkedListNode<T>*)item)->m_last_node);
|
return nonnull_or_error((T*)extract_node(item)->get_last());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Callback> void for_each(Callback callback)
|
template <typename Callback> void for_each(Callback callback)
|
||||||
{
|
{
|
||||||
for (DoublyLinkedListNode<T>* node = m_start_node; node; node = node->m_next_node) { callback((T*)node); }
|
for (Node* node = m_start_node; node; node = node->get_next()) { callback((T*)node); }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Callback> void for_each_reversed(Callback callback)
|
template <typename Callback> void for_each_reversed(Callback callback)
|
||||||
{
|
{
|
||||||
for (DoublyLinkedListNode<T>* node = m_end_node; node; node = node->m_last_node) { callback((T*)node); }
|
for (Node* node = m_end_node; node; node = node->get_last()) { callback((T*)node); }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Callback> void for_each_after(T* start, Callback callback)
|
template <typename Callback> void for_each_after(T* start, Callback callback)
|
||||||
{
|
{
|
||||||
for (DoublyLinkedListNode<T>* node = ((DoublyLinkedListNode<T>*)start)->m_next_node; node;
|
for (Node* node = extract_node(start)->m_next_node; node; node = node->get_next()) { callback((T*)node); }
|
||||||
node = node->m_next_node)
|
|
||||||
{
|
|
||||||
callback((T*)node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Callback> void for_each_before(T* end, Callback callback)
|
template <typename Callback> void for_each_before(T* end, Callback callback)
|
||||||
{
|
{
|
||||||
for (DoublyLinkedListNode<T>* node = ((DoublyLinkedListNode<T>*)end)->m_last_node; node;
|
for (Node* node = extract_node(end)->m_last_node; node; node = node->get_last()) { callback((T*)node); }
|
||||||
node = node->m_last_node)
|
|
||||||
{
|
|
||||||
callback((T*)node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usize count()
|
usize count()
|
||||||
@ -129,8 +147,13 @@ template <typename T> class DoublyLinkedList
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DoublyLinkedListNode<T>* m_start_node = nullptr;
|
Node* m_start_node = nullptr;
|
||||||
DoublyLinkedListNode<T>* m_end_node = nullptr;
|
Node* m_end_node = nullptr;
|
||||||
|
|
||||||
|
Node* extract_node(T* item)
|
||||||
|
{
|
||||||
|
return (Node*)item;
|
||||||
|
}
|
||||||
|
|
||||||
usize m_count = 0;
|
usize m_count = 0;
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user