3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

Add dll_iterator

This commit is contained in:
Jakob Rath 2022-10-03 10:54:24 +02:00
parent 05442e8788
commit 0bea276e82

View file

@ -17,9 +17,11 @@ Revision History:
--*/
#pragma once
#include <type_traits>
template <typename T> class dll_iterator;
template<typename T>
template <typename T>
class dll_base {
T* m_next { nullptr };
T* m_prev { nullptr };
@ -27,6 +29,8 @@ public:
T* prev() { return m_prev; }
T* next() { return m_next; }
T const* prev() const { return m_prev; }
T const* next() const { return m_next; }
void init(T* t) {
m_next = t;
@ -105,11 +109,10 @@ public:
return true;
}
static bool contains(T* list, T* elem) {
static bool contains(T const* list, T const* elem) {
if (!list)
return false;
T* first = list;
T const* first = list;
do {
if (list == elem)
return true;
@ -120,5 +123,59 @@ public:
}
};
template <typename T>
class dll_iterator {
T const* m_elem;
bool m_first;
dll_iterator(T const* elem, bool first): m_elem(elem), m_first(first) { }
public:
static dll_iterator mk_begin(T const* elem) {
// Setting first==(bool)elem makes this also work for elem==nullptr;
// but we can't implement top-level begin/end for pointers because it clashes with the definition for arrays.
return {elem, (bool)elem};
}
static dll_iterator mk_end(T const* elem) {
return {elem, false};
}
// using value_type = T;
// using pointer = T const*;
// using reference = T const&;
// using iterator_category = std::input_iterator_tag;
dll_iterator& operator++() {
m_elem = m_elem->next();
m_first = false;
return *this;
}
T const& operator*() const {
return *m_elem;
}
bool operator==(dll_iterator const& other) const {
return m_elem == other.m_elem && m_first == other.m_first;
}
bool operator!=(dll_iterator const& other) const {
return !operator==(other);
}
};
template < typename T
, typename U = std::enable_if_t<std::is_base_of_v<dll_base<T>, T>> // should only match if T actually inherits from dll_base<T>
>
dll_iterator<T> begin(T const& elem) {
return dll_iterator<T>::mk_begin(&elem);
}
template < typename T
, typename U = std::enable_if_t<std::is_base_of_v<dll_base<T>, T>> // should only match if T actually inherits from dll_base<T>
>
dll_iterator<T> end(T const& elem)
{
return dll_iterator<T>::mk_end(&elem);
}