sat-solver/list.hpp
2025-03-07 09:45:39 -06:00

210 lines
4.4 KiB
C++

#ifndef CLASS_LIST
#define CLASS_LIST
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#include <valgrind/memcheck.h>
#include <type_traits>
#include <new>
#include <utility>
template<typename T> class list
{
public:
class iterable
{
private:
list* owner;
size_t index;
public:
iterable(
list* _owner, size_t _index):
owner(_owner), index(_index)
{
;
}
T operator *()
{
assert(index <= owner->n);
VALGRIND_CHECK_VALUE_IS_DEFINED(owner->data[index]);
T retval = owner->data[index];
return retval;
}
void operator ++()
{
index++;
}
bool operator != (const iterable& other)
{
bool retval = false
|| this->owner != other.owner
|| this->index != other.index;
return retval;
}
};
class const_iterable
{
private:
const list* owner;
size_t index;
public:
const_iterable(
const list* _owner, size_t _index):
owner(_owner), index(_index)
{
;
}
const T operator *()
{
assert(index <= owner->n);
VALGRIND_CHECK_VALUE_IS_DEFINED(owner->data[index]);
const T retval = owner->data[index];
return retval;
}
void operator ++()
{
index++;
}
bool operator != (const const_iterable& other)
{
bool retval = false
|| this->owner != other.owner
|| this->index != other.index;
return retval;
}
};
public:
T* data;
size_t n, cap;
public:
list(): data(NULL), n(0), cap(0)
{
;
}
iterable begin()
{
return iterable(this, 0);
}
iterable end()
{
return iterable(this, n);
}
const_iterable begin() const
{
return const_iterable(this, 0);
}
const_iterable end() const
{
return const_iterable(this, n);
}
void append(T appendme)
{
if constexpr (std::is_trivially_copyable_v<T>)
{
if (n == cap)
{
cap = cap << 1 ?: 1;
data = (T*) realloc((void*) data, sizeof(*data) * cap);
}
data[n++] = appendme;
}
else
{
if (n == cap)
{
cap = cap << 1 ?: 1;
T* new_data = new T[cap]();
for (size_t i = 0; i < n; i++)
{
new_data[i] = std::move(data[i]);
}
delete[] data;
data = new_data;
}
new (&data[n]) T(appendme);
VALGRIND_CHECK_VALUE_IS_DEFINED(data[n]);
n++;
}
}
~list()
{
if constexpr (std::is_trivially_copyable_v<T>)
{
free(data);
}
else
{
delete[] data;
}
}
};
#endif