3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-16 05:48:44 +00:00
z3/src/util/dlist.h
2022-08-01 18:37:11 +03:00

125 lines
2.5 KiB
C++

/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
dlist.h
Abstract:
Templates for manipulating circular doubly linked lists.
Author:
Leonardo de Moura (leonardo) 2011-01-25.
Revision History:
--*/
#pragma once
template<typename T>
class dll_base {
T* m_next { nullptr };
T* m_prev { nullptr };
public:
T* prev() { return m_prev; }
T* next() { return m_next; }
void init(T* t) {
m_next = t;
m_prev = t;
}
static T* pop(T*& list) {
if (!list)
return list;
T* head = list;
remove_from(list, head);
return head;
}
void insert_after(T* elem) {
T* next = this->m_next;
elem->m_prev = next->m_prev;
elem->m_next = next;
this->m_next = elem;
next->m_prev = elem;
}
void insert_before(T* elem) {
T* prev = this->m_prev;
elem->m_next = prev->m_next;
elem->m_prev = prev;
prev->m_next = elem;
this->m_prev = elem;
}
static void remove_from(T*& list, T* elem) {
if (list->m_next == list) {
SASSERT(elem == list);
list = nullptr;
return;
}
if (list == elem)
list = elem->m_next;
auto* next = elem->m_next;
auto* prev = elem->m_prev;
prev->m_next = next;
next->m_prev = prev;
}
static void push_to_front(T*& list, T* elem) {
if (!list) {
list = elem;
elem->m_next = elem;
elem->m_prev = elem;
}
else if (list != elem) {
auto* next = elem->m_next;
auto* prev = elem->m_prev;
prev->m_next = next;
next->m_prev = prev;
list->m_prev->m_next = elem;
elem->m_prev = list->m_prev;
elem->m_next = list;
list->m_prev = elem;
list = elem;
}
}
static void detach(T* elem) {
elem->init(elem);
}
bool invariant() const {
auto* e = this;
do {
if (e->m_next->m_prev != e)
return false;
e = e->m_next;
}
while (e != this);
return true;
}
static bool contains(T* list, T* elem) {
if (!list)
return false;
T* first = list;
do {
if (list == elem)
return true;
list = list->m_next;
}
while (list != first);
return false;
}
};