70 lines
1.6 KiB
C++
70 lines
1.6 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <stdexcept>
|
|
#include <vector>
|
|
|
|
namespace mp
|
|
{
|
|
|
|
template <typename TElem, size_t MaxSize>
|
|
class ArrayContainer
|
|
{
|
|
public:
|
|
ArrayContainer() = default;
|
|
|
|
TElem& operator[](size_t idx) { return m_data[idx]; }
|
|
const TElem& operator[](size_t idx) const { return m_data[idx]; }
|
|
|
|
size_t size() const { return m_size; }
|
|
void clear() { m_size = 0; }
|
|
|
|
void resize(size_t new_size)
|
|
{
|
|
if (new_size > MaxSize)
|
|
throw std::out_of_range("New size exceeds maximum number of elements");
|
|
|
|
if (new_size > m_size)
|
|
std::fill(m_data.begin() + m_size, m_data.begin() + new_size, TElem{0});
|
|
|
|
m_size = new_size;
|
|
}
|
|
|
|
private:
|
|
size_t m_size = 0;
|
|
std::array<TElem, MaxSize> m_data;
|
|
};
|
|
|
|
template <typename TElem, size_t MaxSize>
|
|
class VectorContainer
|
|
{
|
|
public:
|
|
VectorContainer() = default;
|
|
|
|
TElem& operator[](size_t idx) { return m_data[idx]; }
|
|
const TElem& operator[](size_t idx) const { return m_data[idx]; }
|
|
|
|
size_t size() const { return m_data.size(); }
|
|
void clear() { m_data.clear(); }
|
|
|
|
void resize(size_t new_size)
|
|
{
|
|
if (new_size > MaxSize)
|
|
throw std::out_of_range("New size exceeds maximum number of elements");
|
|
|
|
m_data.resize(new_size, TElem{0});
|
|
}
|
|
|
|
private:
|
|
std::vector<TElem> m_data;
|
|
};
|
|
|
|
// threshold for self-contained storage
|
|
constexpr size_t MAX_ARRAY_BYTES = 128;
|
|
|
|
template <typename TElem, size_t MaxSize>
|
|
using Container =
|
|
std::conditional_t<(MaxSize > MAX_ARRAY_BYTES / sizeof(TElem)), VectorContainer<TElem, MaxSize>, ArrayContainer<TElem, MaxSize>>;
|
|
|
|
} // namespace mp
|