1

Cleanup container classes

This commit is contained in:
2022-12-08 22:13:14 +01:00
parent a9265107d9
commit 78a46fb6fd
4 changed files with 61 additions and 23 deletions

View File

@ -46,7 +46,7 @@ public:
} }
} }
// TODO: Rest of constructors ~Array() = default;
iterator begin() { return iterator(&buf[0]); } iterator begin() { return iterator(&buf[0]); }

View File

@ -3,20 +3,22 @@
namespace Container { namespace Container {
// This iterator works for structures where the elements are adjacent in memory. /**
* This class implements an iterator that works on continuous memory regions
* of uniform type.
*
* @tparam T The type of the elements contained in the memory region
*/
template<typename T> template<typename T>
class ContinuousIterator { class ContinuousIterator {
private:
T *ptr = nullptr;
public: public:
ContinuousIterator() = delete; ContinuousIterator() = delete;
// Use const_cast as the iterator has to increment the pointer // Use const_cast as the iterator has to increment the pointer
// Don't make this explicit: Want to write Container::Vector<int>::iterator = nullptr; // Don't make this explicit: Want to write Container::Vector<int>::iterator = nullptr;
ContinuousIterator(const T *ptr) : ptr(const_cast<T *>(ptr)) {} ContinuousIterator(const T *ptr) : ptr(const_cast<T *>(ptr)) {} // NOLINT(google-explicit-constructor)
// TODO: Rest of constructors ~ContinuousIterator() = default;
ContinuousIterator &operator++() { ContinuousIterator &operator++() {
++ptr; ++ptr;
@ -36,7 +38,7 @@ public:
return ContinuousIterator(ptr - sub); return ContinuousIterator(ptr - sub);
} }
// Convenience // Convenience operators
T *operator->() { return ptr; } T *operator->() { return ptr; }
const T *operator->() const { return ptr; } const T *operator->() const { return ptr; }
@ -57,8 +59,12 @@ public:
bool operator!=(const ContinuousIterator &other) const { return ptr != other.ptr; } bool operator!=(const ContinuousIterator &other) const { return ptr != other.ptr; }
// Convenience function
template<typename t> template<typename t>
friend unsigned int distance(const ContinuousIterator<t> &first, const ContinuousIterator<t> &last); friend unsigned int distance(const ContinuousIterator<t> &first, const ContinuousIterator<t> &last);
private:
T *ptr = nullptr;
}; };
template<typename T> template<typename T>

View File

@ -24,9 +24,7 @@ public:
Span() = delete; Span() = delete;
// Don't mark explicit to allow Span<uint32_t, 32> span = &int; // Don't mark explicit to allow Span<uint32_t, 32> span = &int;
Span(T *first) : ptr(first) {} Span(T *first) : ptr(first) {} // NOLINT(google-explicit-constructor)
// TODO: Rest of constructors
iterator begin() { return iterator(ptr); } iterator begin() { return iterator(ptr); }

View File

@ -1,10 +1,6 @@
#ifndef VECTOR_INCLUDE_H_ #ifndef VECTOR_INCLUDE_H_
#define VECTOR_INCLUDE_H_ #define VECTOR_INCLUDE_H_
// NOTE: I decided to implement this because I wanted some sort of dynamic array (for example for the keyeventmanager).
// Also I wanted to template the Queue (for the scheduler) but with this I can just replace the Queue and use the
// ArrayList instead
#include "Iterator.h" #include "Iterator.h"
#include <utility> #include <utility>
@ -118,8 +114,11 @@ public:
return iterator(&buf[size()]); return iterator(&buf[size()]);
} }
// Add elements /**
// https://en.cppreference.com/w/cpp/container/vector/push_back * Insert an element at the front of the vector by copying.
*
* @param copy The element that will be copied to the front of the vector
*/
void push_back(const T &copy) { void push_back(const T &copy) {
initIfNecessary(); initIfNecessary();
@ -128,6 +127,11 @@ public:
min_expand(); min_expand();
} }
/**
* Insert an element at the front of the vector by moving.
*
* @param move The element that will be moved to the front of the vector
*/
void push_back(T &&move) { void push_back(T &&move) {
initIfNecessary(); initIfNecessary();
@ -136,8 +140,14 @@ public:
min_expand(); min_expand();
} }
// https://en.cppreference.com/w/cpp/container/vector/insert /**
// The element will be inserted before the pos iterator, pos can be the end() iterator * Insert an element into the vector by copying it.
* The element will be inserted before pos, so pos can be the end() iterator.
*
* @param pos The position after the slot where the element will be inserted
* @param move The element that will be copied into the vector
* @return The iterator pointing to the inserted element
*/
iterator insert(iterator pos, const T &copy) { iterator insert(iterator pos, const T &copy) {
if (pos > end()) { if (pos > end()) {
// TODO: Exception // TODO: Exception
@ -152,6 +162,14 @@ public:
return iterator(&buf[idx]); return iterator(&buf[idx]);
} }
/**
* Insert an element into the vector by moving it.
* The element will be inserted before pos, so pos can be the end() iterator.
*
* @param pos The position after the slot where the element will be inserted
* @param move The element that will be moved into the vector
* @return The iterator pointing to the inserted element
*/
iterator insert(iterator pos, T &&move) { iterator insert(iterator pos, T &&move) {
if (pos > end()) { if (pos > end()) {
// TODO: Exception // TODO: Exception
@ -166,9 +184,13 @@ public:
return iterator(&buf[idx]); return iterator(&buf[idx]);
} }
// Remove elements /**
// https://en.cppreference.com/w/cpp/container/vector/erase * Remove an element from the vector.
// Returns the iterator after the removed element, pos can't be end() iterator * Returns the iterator after the removed element.
*
* @param pos The element to remove
* @return The next iterator
*/
iterator erase(iterator pos) { iterator erase(iterator pos) {
if (sz == 0 || pos >= end()) { if (sz == 0 || pos >= end()) {
// TODO: Exception // TODO: Exception
@ -242,6 +264,11 @@ public:
} }
} }
/**
* Allocate a number of slots in the vector.
*
* @param cap The minimal number of slots to allocate
*/
void reserve(std::size_t cap = Vector::default_cap) { void reserve(std::size_t cap = Vector::default_cap) {
// The first reserve could allocate double if cap != default_cap // The first reserve could allocate double if cap != default_cap
if (buf == nullptr) { if (buf == nullptr) {
@ -347,9 +374,16 @@ private:
} }
}; };
// Erase all elements that match a predicate
// NOTE: pred is no real predicate as one would need closures for this, but we don't have <functional> available // NOTE: pred is no real predicate as one would need closures for this, but we don't have <functional> available
// This means the result has to be passed separately and the function differs from the c++20 std::erase_if // This means the result has to be passed separately and the function differs from the c++20 std::erase_if
/**
* Erase all elements that match a condition.
*
* @param vec The vector to erase elements from
* @param pred The decider function
* @param result The result that will be compared to the passed functions return value
* @return The number of removed elements
*/
template<typename T, typename arg> template<typename T, typename arg>
std::size_t erase_if(Vector<T> &vec, arg (*pred)(const T &), arg result) { std::size_t erase_if(Vector<T> &vec, arg (*pred)(const T &), arg result) {
std::size_t erased_els = 0; std::size_t erased_els = 0;