diff options
Diffstat (limited to 'src/Common/FlexArray.hpp')
| -rw-r--r-- | src/Common/FlexArray.hpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/Common/FlexArray.hpp b/src/Common/FlexArray.hpp new file mode 100644 index 0000000..4a648b6 --- /dev/null +++ b/src/Common/FlexArray.hpp @@ -0,0 +1,85 @@ +#pragma once + +#include <array> +#include "Sizes.hpp" + +template <typename T, uint S> +class FlexArray { +public: + FlexArray() = default; + + FlexArray& operator=(const FlexArray& other) { + m_count = other.m_count; + m_array = other.m_array; + return *this; + } + + T& at(USize index) { + assure_in_bounds(index); + return m_array.at(index); + } + const T& at(USize index) const { + assure_in_bounds(index); + return m_array.at(index); + } + + T& operator[](USize index) { + assure_in_bounds(index); // STL doesn't do bounds-checks here, and it led to many headaches :( + return m_array[index]; + } + const T& operator[](USize index) const { + assure_in_bounds(index); + return m_array[index]; + } + + T& front() { return at(0); } + const T& front() const { return at(0); } + + T& back() { return at(m_count - 1); } + const T& back() const { return at(m_count - 1); } + + const T* data() const { return m_array.data(); } + T* data() { return m_array.data(); } + + std::array<T, S>& array() { return m_array; } + const std::array<T, S>& array() const { return m_array; } + + T* begin() { return m_array.begin(); } + T* end() { return m_array.begin() + m_count; } + + Bool empty() const { return m_count == 0; } + Bool full() const { return m_count == S; } + + USize size() const { return m_count; } + USize max_size() const { return S; } + + void clear() { m_count = 0; m_array = {}; } + + void push_back(const T& value) { + if (m_count >= S) throw std::out_of_range("flex array is full"); + m_array[m_count] = value; + m_count++; + } + + template <typename... Args> + void emplace_back(Args&&... args) { + if (full()) throw std::out_of_range("flex array is full"); + m_array[m_count] = T{std::forward<Args>(args)...}; + m_count++; + } + + void pop_back() { + if (empty()) throw std::out_of_range("flex array is empty"); + m_array[m_count - 1] = {}; + m_count--; + } + +private: + void assure_in_bounds(USize index) const { + if (index >= m_count) throw std::out_of_range("flex array index out of range"); + } + + USize m_count = 0; + std::array<T, S> m_array{}; +}; + |
