2021-09-17 22:01:53 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <util/types.hpp>
|
|
|
|
|
|
|
|
|
|
namespace rsx
|
|
|
|
|
{
|
|
|
|
|
template <typename Ty>
|
|
|
|
|
struct simple_array
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
using iterator = Ty*;
|
|
|
|
|
using const_iterator = const Ty*;
|
|
|
|
|
using value_type = Ty;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
u32 _capacity = 0;
|
|
|
|
|
u32 _size = 0;
|
|
|
|
|
Ty* _data = nullptr;
|
|
|
|
|
|
|
|
|
|
inline u64 offset(const_iterator pos)
|
|
|
|
|
{
|
|
|
|
|
return (_data) ? u64(pos - _data) : 0ull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
simple_array() = default;
|
|
|
|
|
|
2022-05-26 22:04:15 +02:00
|
|
|
simple_array(u32 initial_size)
|
|
|
|
|
{
|
|
|
|
|
reserve(initial_size);
|
|
|
|
|
_size = initial_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
simple_array(u32 initial_size, const Ty val)
|
2021-09-17 22:01:53 +02:00
|
|
|
{
|
|
|
|
|
reserve(initial_size);
|
|
|
|
|
_size = initial_size;
|
|
|
|
|
|
|
|
|
|
for (u32 n = 0; n < initial_size; ++n)
|
|
|
|
|
{
|
|
|
|
|
_data[n] = val;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
simple_array(const std::initializer_list<Ty>& args)
|
|
|
|
|
{
|
|
|
|
|
reserve(::size32(args));
|
|
|
|
|
|
|
|
|
|
for (const auto& arg : args)
|
|
|
|
|
{
|
|
|
|
|
push_back(arg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
simple_array(const simple_array& other)
|
|
|
|
|
{
|
|
|
|
|
_capacity = other._capacity;
|
|
|
|
|
_size = other._size;
|
|
|
|
|
|
|
|
|
|
const auto size_bytes = sizeof(Ty) * _capacity;
|
|
|
|
|
_data = static_cast<Ty*>(malloc(size_bytes));
|
|
|
|
|
std::memcpy(_data, other._data, size_bytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
simple_array(simple_array&& other) noexcept
|
|
|
|
|
{
|
|
|
|
|
swap(other);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
simple_array& operator=(const simple_array& other)
|
|
|
|
|
{
|
|
|
|
|
if (&other != this)
|
|
|
|
|
{
|
|
|
|
|
simple_array{ other }.swap(*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
simple_array& operator=(simple_array&& other) noexcept
|
|
|
|
|
{
|
|
|
|
|
swap(other);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~simple_array()
|
|
|
|
|
{
|
|
|
|
|
if (_data)
|
|
|
|
|
{
|
|
|
|
|
free(_data);
|
|
|
|
|
_data = nullptr;
|
|
|
|
|
_size = _capacity = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void swap(simple_array<Ty>& other) noexcept
|
|
|
|
|
{
|
|
|
|
|
std::swap(_capacity, other._capacity);
|
|
|
|
|
std::swap(_size, other._size);
|
|
|
|
|
std::swap(_data, other._data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reserve(u32 size)
|
|
|
|
|
{
|
|
|
|
|
if (_capacity >= size)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ensure(_data = static_cast<Ty*>(std::realloc(_data, sizeof(Ty) * size))); // "realloc() failed!"
|
|
|
|
|
_capacity = size;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-27 19:34:11 +02:00
|
|
|
template <typename T> requires UnsignedInt<T>
|
|
|
|
|
void resize(T size)
|
2021-09-17 22:01:53 +02:00
|
|
|
{
|
2022-09-27 19:34:11 +02:00
|
|
|
const auto new_size = static_cast<u32>(size);
|
|
|
|
|
reserve(new_size);
|
|
|
|
|
_size = new_size;
|
2021-09-17 22:01:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void push_back(const Ty& val)
|
|
|
|
|
{
|
|
|
|
|
if (_size >= _capacity)
|
|
|
|
|
{
|
|
|
|
|
reserve(_capacity + 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_data[_size++] = val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void push_back(Ty&& val)
|
|
|
|
|
{
|
|
|
|
|
if (_size >= _capacity)
|
|
|
|
|
{
|
|
|
|
|
reserve(_capacity + 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_data[_size++] = val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ty pop_back()
|
|
|
|
|
{
|
|
|
|
|
return _data[--_size];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator insert(iterator pos, const Ty& val)
|
|
|
|
|
{
|
|
|
|
|
ensure(pos >= _data);
|
|
|
|
|
const auto _loc = offset(pos);
|
|
|
|
|
|
|
|
|
|
if (_size >= _capacity)
|
|
|
|
|
{
|
|
|
|
|
reserve(_capacity + 16);
|
|
|
|
|
pos = _data + _loc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_loc >= _size)
|
|
|
|
|
{
|
|
|
|
|
_data[_size++] = val;
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ensure(_loc < _size);
|
|
|
|
|
|
|
|
|
|
const auto remaining = (_size - _loc);
|
|
|
|
|
memmove(pos + 1, pos, remaining * sizeof(Ty));
|
|
|
|
|
|
|
|
|
|
*pos = val;
|
|
|
|
|
_size++;
|
|
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator insert(iterator pos, Ty&& val)
|
|
|
|
|
{
|
|
|
|
|
ensure(pos >= _data);
|
|
|
|
|
const auto _loc = offset(pos);
|
|
|
|
|
|
|
|
|
|
if (_size >= _capacity)
|
|
|
|
|
{
|
|
|
|
|
reserve(_capacity + 16);
|
|
|
|
|
pos = _data + _loc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_loc >= _size)
|
|
|
|
|
{
|
|
|
|
|
_data[_size++] = val;
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ensure(_loc < _size);
|
|
|
|
|
|
|
|
|
|
const u32 remaining = (_size - _loc);
|
|
|
|
|
memmove(pos + 1, pos, remaining * sizeof(Ty));
|
|
|
|
|
|
|
|
|
|
*pos = val;
|
|
|
|
|
_size++;
|
|
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clear()
|
|
|
|
|
{
|
|
|
|
|
_size = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool empty() const
|
|
|
|
|
{
|
|
|
|
|
return _size == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u32 size() const
|
|
|
|
|
{
|
|
|
|
|
return _size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u64 size_bytes() const
|
|
|
|
|
{
|
|
|
|
|
return _size * sizeof(Ty);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u32 capacity() const
|
|
|
|
|
{
|
|
|
|
|
return _capacity;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ty& operator[] (u32 index)
|
|
|
|
|
{
|
|
|
|
|
return _data[index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Ty& operator[] (u32 index) const
|
|
|
|
|
{
|
|
|
|
|
return _data[index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ty* data()
|
|
|
|
|
{
|
|
|
|
|
return _data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Ty* data() const
|
|
|
|
|
{
|
|
|
|
|
return _data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ty& back()
|
|
|
|
|
{
|
|
|
|
|
return _data[_size - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Ty& back() const
|
|
|
|
|
{
|
|
|
|
|
return _data[_size - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ty& front()
|
|
|
|
|
{
|
|
|
|
|
return _data[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Ty& front() const
|
|
|
|
|
{
|
|
|
|
|
return _data[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator begin()
|
|
|
|
|
{
|
|
|
|
|
return _data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator end()
|
|
|
|
|
{
|
|
|
|
|
return _data ? _data + _size : nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_iterator begin() const
|
|
|
|
|
{
|
|
|
|
|
return _data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_iterator end() const
|
|
|
|
|
{
|
|
|
|
|
return _data ? _data + _size : nullptr;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|