blob: 096f3d045db4e49d98427363dcaaba960a0c0750 [file]
/*
* Copyright 2024 Rive
*/
#pragma once
#include "rive/math/math_types.hpp"
namespace rive
{
template <typename T, uint32_t MAX_CAPACITY> class StackVector
{
public:
void clear() { m_size = 0; }
const T& operator[](uint32_t index) const
{
assert(index < m_size);
return m_data[index];
}
T& operator[](uint32_t index)
{
assert(index < m_size);
return m_data[index];
}
const T& front() const
{
assert(m_size > 0);
return m_data[0];
}
T& front()
{
assert(m_size > 0);
return m_data[0];
}
const T& back() const
{
assert(m_size > 0);
return m_data[m_size - 1];
}
T& back()
{
assert(m_size > 0);
return m_data[m_size - 1];
}
T& push_back(const T& ele)
{
T* ret = push(1);
*ret = ele;
return *ret;
}
T* push_back_n(uint32_t numEles, const T* srcData)
{
T* dst = push(numEles);
if (srcData != nullptr)
{
memcpy(dst, srcData, numEles * sizeof(T));
}
return dst;
}
T* push_back_n(uint32_t numEles, const T& repeat)
{
T* dst = push(numEles);
for (uint32_t i = 0; i < numEles; ++i)
{
dst[i] = repeat;
}
return dst;
}
// Insert 'ele' at 'index', shifting subsequent elements up. 'index' may
// equal size() (equivalent to push_back). Returns a reference to the newly
// inserted element.
T& insert(uint32_t index, const T& ele)
{
assert(index <= m_size);
push(1);
memmove(&m_data[index + 1],
&m_data[index],
(m_size - 1 - index) * sizeof(T));
m_data[index] = ele;
return m_data[index];
}
const T* data() const { return m_data; }
T* data() { return m_data; }
const T* dataOrNull() const { return m_size != 0 ? m_data : nullptr; }
T* dataOrNull() { return m_size != 0 ? m_data : nullptr; }
uint32_t size() const { return m_size; }
bool empty() const { return m_size == 0; }
T* begin() { return m_data; }
T* end() { return m_data + m_size; }
const T* begin() const { return m_data; }
const T* end() const { return m_data + m_size; }
private:
uint32_t m_size = 0;
T m_data[MAX_CAPACITY];
bool hasRoomFor(size_t itemCount)
{
return m_size + itemCount <= MAX_CAPACITY;
}
T* push(size_t count)
{
assert(hasRoomFor(count));
T* ret = &m_data[m_size];
m_size += count;
return ret;
}
// Currently only supports POD types.
static_assert(std::is_trivial<T>() && std::is_standard_layout<T>(),
"StackVector only supports trivial types.");
};
} // namespace rive