2020-02-25 00:44:40 +01:00
|
|
|
#pragma once
|
2020-04-01 02:17:49 +02:00
|
|
|
#include "EngineTypes.h"
|
|
|
|
|
#include <initializer_list>
|
|
|
|
|
#include <iterator>
|
2020-02-25 00:44:40 +01:00
|
|
|
#include <assert.h>
|
2020-08-06 00:54:43 +02:00
|
|
|
#include <memory_resource>
|
|
|
|
|
#include <boost/serialization/serialization.hpp>
|
2020-02-25 00:44:40 +01:00
|
|
|
|
|
|
|
|
#ifndef DEFAULT_ALLOC_SIZE
|
|
|
|
|
#define DEFAULT_ALLOC_SIZE 16
|
|
|
|
|
#endif
|
|
|
|
|
|
2020-04-12 15:47:19 +02:00
|
|
|
namespace Seele
|
2020-02-25 00:44:40 +01:00
|
|
|
{
|
2021-04-13 23:09:16 +02:00
|
|
|
enum class Init_t {
|
|
|
|
|
NO_INIT
|
|
|
|
|
};
|
2020-06-08 01:44:47 +02:00
|
|
|
template <typename T>
|
|
|
|
|
struct Array
|
2020-02-25 00:44:40 +01:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
public:
|
2021-04-13 23:09:16 +02:00
|
|
|
|
2020-06-08 01:44:47 +02:00
|
|
|
Array()
|
2021-04-01 16:40:14 +02:00
|
|
|
: arraySize(0)
|
|
|
|
|
, allocated(DEFAULT_ALLOC_SIZE)
|
2020-02-25 00:44:40 +01:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
_data = new T[DEFAULT_ALLOC_SIZE];
|
|
|
|
|
assert(_data != nullptr);
|
|
|
|
|
//std::memset(_data, 0, sizeof(T) * DEFAULT_ALLOC_SIZE);
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
|
|
|
|
}
|
|
|
|
|
Array(Init_t)
|
|
|
|
|
: arraySize(0)
|
|
|
|
|
, allocated(0)
|
|
|
|
|
, _data(nullptr)
|
|
|
|
|
, beginIt(Iterator(nullptr))
|
|
|
|
|
, endIt(Iterator(nullptr))
|
|
|
|
|
{
|
2020-02-25 00:44:40 +01:00
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
Array(size_t size, T value = T())
|
2021-04-01 16:40:14 +02:00
|
|
|
: arraySize(size)
|
|
|
|
|
, allocated(size)
|
2020-02-25 00:44:40 +01:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
_data = new T[size];
|
|
|
|
|
assert(_data != nullptr);
|
2021-03-31 12:18:16 +02:00
|
|
|
for (size_t i = 0; i < size; ++i)
|
2020-02-25 00:44:40 +01:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
assert(i < size);
|
|
|
|
|
_data[i] = value;
|
2020-02-25 00:44:40 +01:00
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
Array(std::initializer_list<T> init)
|
2021-04-01 16:40:14 +02:00
|
|
|
: arraySize(init.size())
|
|
|
|
|
, allocated(init.size())
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
_data = new T[init.size()];
|
|
|
|
|
auto it = init.begin();
|
|
|
|
|
for (size_t i = 0; it != init.end(); i++, it++)
|
|
|
|
|
{
|
|
|
|
|
assert(i < init.size());
|
|
|
|
|
_data[i] = *it;
|
|
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
Array(const Array &other)
|
2021-04-01 16:40:14 +02:00
|
|
|
: arraySize(other.arraySize)
|
|
|
|
|
, allocated(other.allocated)
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
2020-04-12 15:47:19 +02:00
|
|
|
_data = new T[other.allocated];
|
2020-06-08 01:44:47 +02:00
|
|
|
assert(_data != nullptr);
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2021-05-10 23:57:55 +02:00
|
|
|
std::copy(other.begin(), other.end(), begin());
|
2020-03-13 12:44:33 +01:00
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
Array(Array &&other) noexcept
|
2021-04-01 16:40:14 +02:00
|
|
|
: arraySize(std::move(other.arraySize))
|
|
|
|
|
, allocated(std::move(other.allocated))
|
2020-03-13 12:44:33 +01:00
|
|
|
{
|
|
|
|
|
_data = other._data;
|
|
|
|
|
other._data = nullptr;
|
2020-06-08 01:44:47 +02:00
|
|
|
other.allocated = 0;
|
|
|
|
|
other.arraySize = 0;
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-03-13 12:44:33 +01:00
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
Array &operator=(const Array &other) noexcept
|
|
|
|
|
{
|
2020-10-14 01:49:43 +02:00
|
|
|
if (this != &other)
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
if (_data != nullptr)
|
|
|
|
|
{
|
2021-04-13 23:09:16 +02:00
|
|
|
if(other.arraySize > allocated)
|
|
|
|
|
{
|
|
|
|
|
delete[] _data;
|
|
|
|
|
_data = new T[other.allocated];
|
|
|
|
|
allocated = other.allocated;
|
|
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
arraySize = other.arraySize;
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2021-05-10 23:57:55 +02:00
|
|
|
std::copy(other.begin(), other.end(), begin());
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
Array &operator=(Array &&other) noexcept
|
|
|
|
|
{
|
2020-10-14 01:49:43 +02:00
|
|
|
if (this != &other)
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
if (_data != nullptr)
|
|
|
|
|
{
|
|
|
|
|
delete[] _data;
|
2021-04-13 23:09:16 +02:00
|
|
|
_data = nullptr;
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
allocated = std::move(other.allocated);
|
|
|
|
|
arraySize = std::move(other.arraySize);
|
|
|
|
|
_data = other._data;
|
|
|
|
|
other._data = nullptr;
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
~Array()
|
|
|
|
|
{
|
|
|
|
|
if (_data)
|
|
|
|
|
{
|
|
|
|
|
delete[] _data;
|
|
|
|
|
_data = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
template <typename X>
|
|
|
|
|
class IteratorBase
|
|
|
|
|
{
|
|
|
|
|
public:
|
2021-04-01 16:40:14 +02:00
|
|
|
using iterator_category = std::random_access_iterator_tag;
|
|
|
|
|
using value_type = X;
|
|
|
|
|
using difference_type = std::ptrdiff_t;
|
|
|
|
|
using reference = X&;
|
|
|
|
|
using pointer = X*;
|
2020-06-08 01:44:47 +02:00
|
|
|
|
|
|
|
|
IteratorBase(X *x = nullptr)
|
|
|
|
|
: p(x)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
reference operator*() const
|
|
|
|
|
{
|
|
|
|
|
return *p;
|
|
|
|
|
}
|
|
|
|
|
pointer operator->() const
|
|
|
|
|
{
|
|
|
|
|
return p;
|
|
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
inline bool operator!=(const IteratorBase &other) const
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
return p != other.p;
|
|
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
inline bool operator==(const IteratorBase &other) const
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
return p == other.p;
|
|
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
inline int operator-(const IteratorBase &other) const
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
return (int)(p - other.p);
|
|
|
|
|
}
|
|
|
|
|
IteratorBase &operator++()
|
|
|
|
|
{
|
|
|
|
|
p++;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
IteratorBase &operator--()
|
|
|
|
|
{
|
|
|
|
|
p--;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
IteratorBase operator++(int)
|
|
|
|
|
{
|
|
|
|
|
IteratorBase tmp(*this);
|
|
|
|
|
++*this;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
IteratorBase operator--(int)
|
|
|
|
|
{
|
|
|
|
|
IteratorBase tmp(*this);
|
|
|
|
|
--*this;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
X *p;
|
|
|
|
|
};
|
|
|
|
|
typedef IteratorBase<T> Iterator;
|
|
|
|
|
typedef IteratorBase<const T> ConstIterator;
|
|
|
|
|
|
|
|
|
|
bool operator==(const Array &other)
|
|
|
|
|
{
|
|
|
|
|
return _data == other._data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator!=(const Array &other)
|
|
|
|
|
{
|
|
|
|
|
return !(*this == other);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Iterator find(const T &item)
|
|
|
|
|
{
|
|
|
|
|
for (uint32 i = 0; i < arraySize; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (_data[i] == item)
|
|
|
|
|
{
|
|
|
|
|
return Iterator(&_data[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return endIt;
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
Iterator find(T&& item)
|
|
|
|
|
{
|
|
|
|
|
for (uint32 i = 0; i < arraySize; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (_data[i] == item)
|
|
|
|
|
{
|
|
|
|
|
return Iterator(&_data[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return endIt;
|
|
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
Iterator begin() const
|
|
|
|
|
{
|
|
|
|
|
return beginIt;
|
|
|
|
|
}
|
|
|
|
|
Iterator end() const
|
|
|
|
|
{
|
|
|
|
|
return endIt;
|
|
|
|
|
}
|
|
|
|
|
ConstIterator cbegin() const
|
|
|
|
|
{
|
|
|
|
|
return beginIt;
|
|
|
|
|
}
|
|
|
|
|
ConstIterator cend() const
|
|
|
|
|
{
|
|
|
|
|
return endIt;
|
|
|
|
|
}
|
|
|
|
|
T &add(const T &item = T())
|
|
|
|
|
{
|
2021-09-29 22:12:56 +02:00
|
|
|
return addInternal(item);
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
T &add(T&& item)
|
|
|
|
|
{
|
2021-09-29 22:12:56 +02:00
|
|
|
return addInternal(std::forward<T>(item));
|
2021-03-31 12:18:16 +02:00
|
|
|
}
|
2020-10-03 11:00:10 +02:00
|
|
|
T &addUnique(const T &item = T())
|
|
|
|
|
{
|
|
|
|
|
Iterator it;
|
2021-04-01 16:40:14 +02:00
|
|
|
if((it = std::move(find(item))) != endIt)
|
2020-10-03 11:00:10 +02:00
|
|
|
{
|
|
|
|
|
return *it;
|
|
|
|
|
}
|
2021-09-29 22:12:56 +02:00
|
|
|
return addInternal(item);
|
2020-10-03 11:00:10 +02:00
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
template<typename... args>
|
2021-03-31 12:18:16 +02:00
|
|
|
T &emplace(args... arguments)
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
if (arraySize == allocated)
|
|
|
|
|
{
|
2021-03-31 12:18:16 +02:00
|
|
|
size_t newSize = arraySize + 1;
|
2020-06-08 01:44:47 +02:00
|
|
|
allocated = calculateGrowth(newSize);
|
|
|
|
|
T *tempArray = new T[allocated];
|
|
|
|
|
assert(tempArray != nullptr);
|
2021-03-31 12:18:16 +02:00
|
|
|
for (size_t i = 0; i < arraySize; ++i)
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
tempArray[i] = _data[i];
|
|
|
|
|
}
|
|
|
|
|
delete[] _data;
|
|
|
|
|
_data = tempArray;
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
_data[arraySize++] = T(arguments...);
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-06-08 01:44:47 +02:00
|
|
|
return _data[arraySize - 1];
|
|
|
|
|
}
|
|
|
|
|
void remove(Iterator it, bool keepOrder = true)
|
|
|
|
|
{
|
|
|
|
|
remove(it - beginIt, keepOrder);
|
|
|
|
|
}
|
|
|
|
|
void remove(int index, bool keepOrder = true)
|
|
|
|
|
{
|
|
|
|
|
if (keepOrder)
|
|
|
|
|
{
|
2021-04-01 16:40:14 +02:00
|
|
|
for(uint32 i = index; i < arraySize-1; ++i)
|
|
|
|
|
{
|
|
|
|
|
_data[i] = std::move(_data[i+1]);
|
|
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2021-03-31 12:18:16 +02:00
|
|
|
_data[index] = std::move(_data[arraySize - 1]);
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
arraySize--;
|
2021-06-12 18:51:29 +02:00
|
|
|
markIteratorDirty();
|
2020-06-08 01:44:47 +02:00
|
|
|
}
|
|
|
|
|
void clear()
|
2020-03-13 12:44:33 +01:00
|
|
|
{
|
2020-04-12 15:47:19 +02:00
|
|
|
delete[] _data;
|
|
|
|
|
_data = nullptr;
|
2020-06-08 01:44:47 +02:00
|
|
|
arraySize = 0;
|
|
|
|
|
allocated = 0;
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-03-13 12:44:33 +01:00
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
void resize(size_t newSize)
|
2020-02-25 00:44:40 +01:00
|
|
|
{
|
2021-05-06 17:02:10 +02:00
|
|
|
if (newSize <= allocated)
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
arraySize = newSize;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
T *newData = new T[newSize];
|
|
|
|
|
assert(newData != nullptr);
|
|
|
|
|
allocated = newSize;
|
2021-04-01 16:40:14 +02:00
|
|
|
for(uint32 i = 0; i < arraySize; ++i)
|
|
|
|
|
{
|
|
|
|
|
newData[i] = std::move(_data[i]);
|
|
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
arraySize = newSize;
|
|
|
|
|
delete _data;
|
|
|
|
|
_data = newData;
|
|
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-02-25 00:44:40 +01:00
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
inline size_t indexOf(Iterator iterator)
|
2020-10-03 11:00:10 +02:00
|
|
|
{
|
|
|
|
|
return iterator - beginIt;
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
inline size_t indexOf(ConstIterator iterator) const
|
2020-10-03 11:00:10 +02:00
|
|
|
{
|
|
|
|
|
return iterator.p - beginIt.p;
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
inline size_t indexOf(T& t)
|
2020-10-03 11:00:10 +02:00
|
|
|
{
|
|
|
|
|
return indexOf(find(t));
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
inline size_t indexOf(const T& t) const
|
2020-10-03 11:00:10 +02:00
|
|
|
{
|
|
|
|
|
return indexOf(find(t));
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
inline size_t size() const
|
2020-02-25 00:44:40 +01:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
return arraySize;
|
2020-02-25 00:44:40 +01:00
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
inline size_t empty() const
|
|
|
|
|
{
|
|
|
|
|
return arraySize == 0;
|
|
|
|
|
}
|
|
|
|
|
inline size_t capacity() const
|
2020-02-25 00:44:40 +01:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
return allocated;
|
2020-04-12 15:47:19 +02:00
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
inline T *data() const
|
2020-04-12 15:47:19 +02:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
return _data;
|
2020-04-12 15:47:19 +02:00
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
inline T &back() const
|
2020-04-12 15:47:19 +02:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
return _data[arraySize - 1];
|
2020-04-12 15:47:19 +02:00
|
|
|
}
|
2020-06-08 01:44:47 +02:00
|
|
|
void pop()
|
2020-04-12 15:47:19 +02:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
arraySize--;
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-04-12 15:47:19 +02:00
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
constexpr inline T &operator[](size_t index)
|
2020-04-12 15:47:19 +02:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
assert(index < arraySize);
|
|
|
|
|
return _data[index];
|
2020-04-12 15:47:19 +02:00
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
constexpr inline const T &operator[](size_t index) const
|
2020-04-12 15:47:19 +02:00
|
|
|
{
|
2020-06-08 01:44:47 +02:00
|
|
|
assert(index < arraySize);
|
|
|
|
|
return _data[index];
|
2020-04-12 15:47:19 +02:00
|
|
|
}
|
2020-02-25 00:44:40 +01:00
|
|
|
private:
|
2021-03-31 12:18:16 +02:00
|
|
|
size_t calculateGrowth(size_t newSize) const
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
2021-03-31 12:18:16 +02:00
|
|
|
const size_t oldCapacity = capacity();
|
2020-06-08 01:44:47 +02:00
|
|
|
|
2021-03-31 12:18:16 +02:00
|
|
|
if (oldCapacity > SIZE_MAX - oldCapacity / 2)
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
return newSize; // geometric growth would overflow
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-31 12:18:16 +02:00
|
|
|
const size_t geometric = oldCapacity + oldCapacity / 2;
|
2020-06-08 01:44:47 +02:00
|
|
|
|
|
|
|
|
if (geometric < newSize)
|
|
|
|
|
{
|
|
|
|
|
return newSize; // geometric growth would be insufficient
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return geometric; // geometric growth is sufficient
|
|
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
void markIteratorDirty()
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
beginIt = Iterator(_data);
|
|
|
|
|
endIt = Iterator(_data + arraySize);
|
|
|
|
|
}
|
2021-09-29 22:12:56 +02:00
|
|
|
template<typename Type>
|
|
|
|
|
T& addInternal(Type&& t)
|
|
|
|
|
{
|
|
|
|
|
if (arraySize == allocated)
|
|
|
|
|
{
|
|
|
|
|
size_t newSize = arraySize + 1;
|
|
|
|
|
allocated = calculateGrowth(newSize);
|
|
|
|
|
T *tempArray = new T[allocated];
|
|
|
|
|
assert(tempArray != nullptr);
|
|
|
|
|
for (size_t i = 0; i < arraySize; ++i)
|
|
|
|
|
{
|
|
|
|
|
tempArray[i] = std::forward<Type>(_data[i]);
|
|
|
|
|
}
|
|
|
|
|
delete[] _data;
|
|
|
|
|
_data = tempArray;
|
|
|
|
|
}
|
|
|
|
|
_data[arraySize++] = std::forward<Type>(t);
|
|
|
|
|
markIteratorDirty();
|
|
|
|
|
return _data[arraySize - 1];
|
|
|
|
|
}
|
2020-08-06 00:54:43 +02:00
|
|
|
friend class boost::serialization::access;
|
|
|
|
|
template<class Archive>
|
|
|
|
|
void serialize(Archive& ar, const unsigned int version)
|
|
|
|
|
{
|
|
|
|
|
ar & arraySize;
|
2021-04-01 16:40:14 +02:00
|
|
|
resize(arraySize);
|
2021-03-31 12:18:16 +02:00
|
|
|
for(size_t i = 0; i < arraySize; ++i)
|
2020-08-06 00:54:43 +02:00
|
|
|
ar & _data[i];
|
2021-04-13 23:09:16 +02:00
|
|
|
markIteratorDirty();
|
2020-08-06 00:54:43 +02:00
|
|
|
}
|
2021-04-13 23:09:16 +02:00
|
|
|
size_t arraySize = 0;
|
|
|
|
|
size_t allocated = 0;
|
2020-06-08 01:44:47 +02:00
|
|
|
Iterator beginIt;
|
|
|
|
|
Iterator endIt;
|
2021-04-13 23:09:16 +02:00
|
|
|
T *_data = nullptr;
|
2020-02-25 00:44:40 +01:00
|
|
|
};
|
2020-04-12 15:47:19 +02:00
|
|
|
|
2021-03-31 12:18:16 +02:00
|
|
|
template <typename T, size_t N>
|
2020-06-08 01:44:47 +02:00
|
|
|
struct StaticArray
|
2020-04-12 15:47:19 +02:00
|
|
|
{
|
2021-03-31 12:18:16 +02:00
|
|
|
public:
|
2020-06-08 01:44:47 +02:00
|
|
|
template <typename X>
|
|
|
|
|
class IteratorBase
|
|
|
|
|
{
|
|
|
|
|
public:
|
2021-04-01 16:40:14 +02:00
|
|
|
using iterator_category = std::random_access_iterator_tag;
|
2021-03-31 12:18:16 +02:00
|
|
|
using value_type = X;
|
|
|
|
|
using difference_type = std::ptrdiff_t;
|
|
|
|
|
using reference = X&;
|
|
|
|
|
using pointer = X*;
|
2020-06-08 01:44:47 +02:00
|
|
|
|
|
|
|
|
IteratorBase(X *x = nullptr)
|
|
|
|
|
: p(x)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
reference operator*() const
|
|
|
|
|
{
|
|
|
|
|
return *p;
|
|
|
|
|
}
|
|
|
|
|
pointer operator->() const
|
|
|
|
|
{
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
inline bool operator!=(const IteratorBase &other)
|
|
|
|
|
{
|
|
|
|
|
return p != other.p;
|
|
|
|
|
}
|
|
|
|
|
inline bool operator==(const IteratorBase &other)
|
|
|
|
|
{
|
|
|
|
|
return p == other.p;
|
|
|
|
|
}
|
|
|
|
|
IteratorBase &operator++()
|
|
|
|
|
{
|
|
|
|
|
p++;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
IteratorBase operator++(int)
|
|
|
|
|
{
|
|
|
|
|
IteratorBase tmp(*this);
|
|
|
|
|
++*this;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
2021-04-01 16:40:14 +02:00
|
|
|
IteratorBase &operator--()
|
|
|
|
|
{
|
|
|
|
|
p--;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
IteratorBase operator--(int)
|
|
|
|
|
{
|
|
|
|
|
IteratorBase tmp(*this);
|
|
|
|
|
--*this;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-08 01:44:47 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
X *p;
|
|
|
|
|
};
|
2021-03-31 12:18:16 +02:00
|
|
|
using value_type = T;
|
|
|
|
|
using size_type = size_t;
|
|
|
|
|
using difference_type = std::ptrdiff_t;
|
|
|
|
|
using pointer = T*;
|
|
|
|
|
using const_pointer = const T*;
|
|
|
|
|
using reference = T&;
|
|
|
|
|
using const_reference = const T&;
|
2020-06-08 01:44:47 +02:00
|
|
|
|
2021-03-31 12:18:16 +02:00
|
|
|
using iterator = IteratorBase<T>;
|
|
|
|
|
using const_iterator = IteratorBase<const T>;
|
|
|
|
|
|
|
|
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
|
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
|
|
|
|
|
|
|
|
|
StaticArray()
|
|
|
|
|
{
|
|
|
|
|
beginIt = iterator(_data);
|
|
|
|
|
endIt = iterator(_data + N);
|
|
|
|
|
}
|
|
|
|
|
StaticArray(T value)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < N; ++i)
|
|
|
|
|
{
|
|
|
|
|
_data[i] = value;
|
|
|
|
|
}
|
|
|
|
|
beginIt = iterator(_data);
|
|
|
|
|
endIt = iterator(_data + N);
|
|
|
|
|
}
|
|
|
|
|
~StaticArray()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline size_type size() const
|
|
|
|
|
{
|
|
|
|
|
return N;
|
|
|
|
|
}
|
|
|
|
|
inline pointer data()
|
|
|
|
|
{
|
|
|
|
|
return _data;
|
|
|
|
|
}
|
|
|
|
|
inline const_pointer data() const
|
|
|
|
|
{
|
|
|
|
|
return _data;
|
|
|
|
|
}
|
|
|
|
|
constexpr reference operator[](size_type index) noexcept
|
|
|
|
|
{
|
2021-04-01 16:40:14 +02:00
|
|
|
assert(index < N);
|
2021-03-31 12:18:16 +02:00
|
|
|
return _data[index];
|
|
|
|
|
}
|
|
|
|
|
constexpr const_reference operator[](size_type index) const noexcept
|
|
|
|
|
{
|
2021-04-01 16:40:14 +02:00
|
|
|
assert(index < N);
|
2021-03-31 12:18:16 +02:00
|
|
|
return _data[index];
|
|
|
|
|
}
|
|
|
|
|
iterator begin()
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
return beginIt;
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
iterator end()
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
return endIt;
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
const_iterator begin() const
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
return beginIt;
|
|
|
|
|
}
|
2021-03-31 12:18:16 +02:00
|
|
|
const_iterator end() const
|
2020-06-08 01:44:47 +02:00
|
|
|
{
|
|
|
|
|
return beginIt;
|
|
|
|
|
}
|
2020-04-12 15:47:19 +02:00
|
|
|
private:
|
2020-06-08 01:44:47 +02:00
|
|
|
T _data[N];
|
2021-03-31 12:18:16 +02:00
|
|
|
iterator beginIt;
|
|
|
|
|
iterator endIt;
|
2020-08-06 00:54:43 +02:00
|
|
|
friend class boost::serialization::access;
|
|
|
|
|
template<class Archive>
|
|
|
|
|
void serialize(Archive& ar, const unsigned int version)
|
|
|
|
|
{
|
2021-04-01 16:40:14 +02:00
|
|
|
ar & version;
|
2020-08-06 00:54:43 +02:00
|
|
|
ar & N;
|
|
|
|
|
ar & _data;
|
|
|
|
|
}
|
2020-04-12 15:47:19 +02:00
|
|
|
};
|
|
|
|
|
} // namespace Seele
|