z3-z3-4.12.6.src.util.list.h Maven / Gradle / Ivy
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
list.h
Abstract:
Simple list data structure. It is meant to be used with region allocators.
Author:
Leonardo de Moura (leonardo) 2007-07-10.
Revision History:
--*/
#pragma once
#include "util/buffer.h"
#include "util/region.h"
template
class list {
T m_head;
list * m_tail;
public:
list(T const & h, list * t = nullptr):
m_head(h),
m_tail(t) {
}
T const & head() const { return m_head; }
list * tail() const { return m_tail; }
T & head() { return m_head; }
list * & tail() { return m_tail; }
class iterator {
list const * m_curr;
public:
iterator(list const * c = 0):m_curr(c) {}
T const & operator*() const { return m_curr->head(); }
iterator & operator++() { m_curr = m_curr->tail(); return *this; }
iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; }
bool operator==(iterator const & it) { return m_curr == it.m_curr; }
bool operator!=(iterator const & it) { return m_curr != it.m_curr; }
};
typedef iterator const_iterator;
iterator begin() const { return iterator(this); }
iterator end() const { return iterator(0); }
};
/**
\brief Return the list length.
*/
template
unsigned length(list * l) {
unsigned r = 0;
while(l) {
l = l->tail();
r++;
}
return r;
}
/**
\brief Non destructive append operation. The new nodes are allocated
using the given region allocator.
*/
template
list * append(region & r, list * l1, list * l2) {
if (l2 == nullptr) {
return l1;
}
ptr_buffer > buffer;
while (l1) {
buffer.push_back(l1);
l1 = l1->tail();
}
list * result = l2;
typename ptr_buffer >::const_iterator it = buffer.end();
typename ptr_buffer >::const_iterator begin = buffer.begin();
while (it != begin) {
--it;
list * curr = *it;
result = new (r) list(curr->head(), result);
}
return result;
}