#ifndef CLASS_LIST #define CLASS_LIST #include #include #include #include #include #include #include template 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) { 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) { free(data); } else { delete[] data; } } }; #endif