mirror of
https://github.com/Z3Prover/z3
synced 2025-04-07 01:54:08 +00:00
* na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * dbg Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * bv Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * drat and fresh Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * move ackerman functionality Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * debugability Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * towards debugability Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * missing file Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remove csp Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * replay variables created by solver Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remove old function Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * fix scoped-limit Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
189 lines
4.4 KiB
C++
189 lines
4.4 KiB
C++
/*++
|
|
Copyright (c) 2011 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dlist.h
|
|
|
|
Abstract:
|
|
|
|
Templates for manipulating doubly linked lists.
|
|
|
|
Author:
|
|
|
|
Leonardo de Moura (leonardo) 2011-01-25.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#pragma once
|
|
|
|
#if 0
|
|
-- unused
|
|
|
|
/**
|
|
Add element \c elem to the list headed by \c head.
|
|
NextProc and PrevProc must have the methods:
|
|
T * & operator()(T *);
|
|
T * & operator()(T *);
|
|
They should return the next and prev fields of the given object.
|
|
*/
|
|
template<typename T, typename NextProc, typename PrevProc>
|
|
void dlist_add(T * & head, T * elem, NextProc const & next = NextProc(), PrevProc const & prev = PrevProc()) {
|
|
SASSERT(prev(elem) == 0);
|
|
SASSERT(next(elem) == 0);
|
|
if (head == 0) {
|
|
head = elem;
|
|
}
|
|
else {
|
|
next(elem) = head;
|
|
prev(head) = elem;
|
|
head = elem;
|
|
}
|
|
}
|
|
|
|
template<typename T, typename NextProc, typename PrevProc>
|
|
void dlist_del(T * & head, T * elem, NextProc const & next = NextProc(), PrevProc const & prev = PrevProc()) {
|
|
T * & prev_elem = prev(elem);
|
|
T * & next_elem = next(elem);
|
|
if (head == elem) {
|
|
SASSERT(prev_elem == 0);
|
|
if (next_elem != 0)
|
|
prev(next_elem) = 0;
|
|
head = next_elem;
|
|
}
|
|
else {
|
|
SASSERT(prev_elem != 0);
|
|
next(prev_elem) = next_elem;
|
|
if (next_elem != 0)
|
|
prev(next_elem) = prev_elem;
|
|
}
|
|
prev_elem = 0;
|
|
next_elem = 0;
|
|
}
|
|
|
|
/**
|
|
\brief Remove the head of the list. Return the old head.
|
|
*/
|
|
template<typename T, typename NextProc, typename PrevProc>
|
|
T * dlist_pop(T * & head, NextProc const & next = NextProc(), PrevProc const & prev = PrevProc()) {
|
|
if (head == 0) {
|
|
return 0;
|
|
}
|
|
else {
|
|
SASSERT(prev(head) == 0);
|
|
T * r = head;
|
|
head = next(head);
|
|
if (head)
|
|
prev(head) = 0;
|
|
next(r) = 0;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\brief Insert new element after elem.
|
|
*/
|
|
template<typename T, typename NextProc, typename PrevProc>
|
|
void dlist_insert_after(T * elem, T * new_elem, NextProc const & next = NextProc(), PrevProc const & prev = PrevProc()) {
|
|
SASSERT(elem);
|
|
SASSERT(new_elem);
|
|
T * & old_next_elem = next(elem);
|
|
prev(new_elem) = elem;
|
|
next(new_elem) = old_next_elem;
|
|
if (old_next_elem)
|
|
prev(old_next_elem) = new_elem;
|
|
// next(elem) = new_elem;
|
|
old_next_elem = new_elem;
|
|
}
|
|
|
|
template<typename T, typename NextProc>
|
|
bool dlist_contains(T * head, T const * elem, NextProc const & next = NextProc()) {
|
|
T * curr = head;
|
|
while (curr != 0) {
|
|
if (curr == elem)
|
|
return true;
|
|
curr = next(curr);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template<typename T, typename NextProc>
|
|
unsigned dlist_length(T * head, NextProc const & next = NextProc()) {
|
|
unsigned r = 0;
|
|
T * curr = head;
|
|
while (curr != 0) {
|
|
r++;
|
|
curr = next(curr);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
template<typename T, typename NextProc, typename PrevProc>
|
|
bool dlist_check_invariant(T * head, NextProc const & next = NextProc(), PrevProc const & prev = PrevProc()) {
|
|
if (head == 0)
|
|
return true;
|
|
SASSERT(prev(head) == 0);
|
|
T * old = head;
|
|
T * curr = next(head);
|
|
while (curr != 0) {
|
|
SASSERT(prev(curr) == old);
|
|
old = curr;
|
|
curr = next(curr);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#endif
|
|
|
|
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 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;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
|