AuROXTL/Include/auROXTL/auArray.hpp
2024-09-01 22:19:18 +01:00

397 lines
8.1 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auArray.hpp
Date: 2022-2-1
Author: Reece
***/
#pragma once
#if defined(_AURORA_AVOID_EXTREMLY_DUMB_STL_TYPES) && !defined(_AURORA_FORCE_STD_ARRAY)
// following the conventions set out in other out of ecosystem macro-test cases for identifying aurora types in portable header libraries
#define AU_AuArray AuArray
template <class T, size_t Count>
struct AuArray
{
T elements[Count] {};
static const AuUInt kElementCount = Count;
using value_type = T;
using size_type = AuUInt;
using difference_type = AuSInt;
using pointer = value_type *;
using const_pointer = const value_type *;
using reference = value_type &;
using const_reference = const value_type &;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = AuReverseIterator<iterator>;
using const_reverse_iterator = AuReverseIterator<const_iterator>;
void fill(const T &value)
{
if constexpr (AuIsSame_v<T, AuUInt8> || AuIsSame_v<T, AuInt8>)
{
AuMemset(this->elements, value, sizeof(this->elements));
}
else
{
for (AU_ITERATE_N(i, kElementCount))
{
this->elements[i] = value;
}
}
}
void Fill(const T &value)
{
this->fill(value);
}
void swap(AuArray &other)
{
AuArray temp;
if constexpr (AuIsTriviallyCopyable_v<T>)
{
AuMemcpy(temp, this->elements, sizeof(this->elements));
AuMemcpy(this->elements, other.elements, sizeof(this->elements));
AuMemcpy(other.elements, temp, sizeof(this->elements));
}
else
{
AuArray temp;
for (AU_ITERATE_N(i, kElementCount))
{
temp[i] = this->elements[i];
}
for (AU_ITERATE_N(i, kElementCount))
{
this->elements[i] = other.elements[i];
}
for (AU_ITERATE_N(i, kElementCount))
{
other.elements[i] = temp[i];
}
}
}
void Swap(AuArray &other)
{
this->swap(other);
}
constexpr iterator begin()
{
return this->elements;
}
constexpr const_iterator begin() const
{
return this->elements;
}
constexpr iterator Begin()
{
return this->elements;
}
constexpr const_iterator Begin() const
{
return this->elements;
}
constexpr iterator end()
{
return this->elements + kElementCount;
}
constexpr const_iterator end() const
{
return this->elements + kElementCount;
}
constexpr iterator End()
{
return this->elements + kElementCount;
}
constexpr const_iterator End() const
{
return this->elements + kElementCount;
}
constexpr const_iterator cbegin() const
{
return begin();
}
constexpr const_iterator cend() const
{
return end();
}
constexpr const_iterator CBegin() const
{
return begin();
}
constexpr const_iterator CEnd() const
{
return end();
}
constexpr const_reverse_iterator rbegin() const
{
return reverse_iterator(end());
}
constexpr reverse_iterator RBegin()
{
return reverse_iterator(end());
}
constexpr const_reverse_iterator RBegin() const
{
return const_reverse_iterator(end());
}
constexpr reverse_iterator rend()
{
return reverse_iterator(begin());
}
constexpr const_reverse_iterator rend() const
{
return reverse_iterator(begin());
}
constexpr reverse_iterator REnd()
{
return const_reverse_iterator(begin());
}
constexpr const_reverse_iterator REnd() const
{
return const_reverse_iterator(begin());
}
constexpr const_reverse_iterator crbegin() const
{
return const_reverse_iterator(end());
}
constexpr const_reverse_iterator crend() const
{
return const_reverse_iterator(begin());
}
constexpr const_reverse_iterator CRBegin() const
{
return const_reverse_iterator(end());
}
constexpr const_reverse_iterator CREnd() const
{
return const_reverse_iterator(begin());
}
constexpr size_type size() const
{
return kElementCount;
}
constexpr size_type Size() const
{
return kElementCount;
}
constexpr size_type max_size() const
{
return kElementCount;
}
constexpr size_type MaxSize() const
{
return kElementCount;
}
constexpr bool empty() const
{
return false;
}
constexpr bool Empty() const
{
return false;
}
reference at(size_type pos)
{
#if defined(AU_CFG_ID_DEBUG)
if (pos >= kElementCount)
{
AuMemoryPanic("out of bounds access");
}
#endif
return this->elements[pos];
}
constexpr const_reference at(size_type pos) const
{
#if defined(AU_CFG_ID_DEBUG)
if (pos >= kElementCount)
{
AuMemoryPanic("out of bounds access");
}
#endif
return this->elements[pos];
}
reference At(size_type pos)
{
#if defined(AU_CFG_ID_DEBUG)
if (pos >= kElementCount)
{
AuMemoryPanic("out of bounds access");
}
#endif
return this->elements[pos];
}
constexpr const_reference At(size_type pos) const
{
#if defined(AU_CFG_ID_DEBUG)
if (pos >= kElementCount)
{
AuMemoryPanic("out of bounds access");
}
#endif
return this->elements[pos];
}
reference operator[](size_type pos)
{
#if defined(AU_CFG_ID_DEBUG)
if (pos >= kElementCount)
{
AuMemoryPanic("out of bounds access");
}
#endif
return this->elements[pos];
}
constexpr const_reference operator[](size_type pos) const
{
#if defined(AU_CFG_ID_DEBUG)
if (pos >= Count)
{
AuMemoryPanic("out of bounds access");
}
#endif
return this->elements[pos];
}
constexpr reference front()
{
return this->elements[0];
}
constexpr const_reference front() const
{
return this->elements[0];
}
constexpr reference back()
{
return this->elements[Count - 1];
}
constexpr const_reference back() const
{
return this->elements[Count - 1];
}
constexpr reference Front()
{
return this->elements[0];
}
constexpr const_reference Front() const
{
return this->elements[0];
}
constexpr reference Back()
{
return this->elements[Count - 1];
}
constexpr const_reference Back() const
{
return this->elements[Count - 1];
}
constexpr T *data()
{
return this->elements;
}
constexpr const T *data() const
{
return this->elements;
}
constexpr T *Data()
{
return this->elements;
}
constexpr const T *Data() const
{
return this->elements;
}
// oh look, its that feature in that nearly 30 year old programming language intended to replace xerox alto's OOP language for the internet era.
AuUInt HashCode() const
{
AuUInt uRet {};
if constexpr (AuIsTriviallyCopyable_v<T>)
{
return AuFnv1aRuntime(this->elements, sizeof(this->elements));
}
else
{
for (AU_ITERATE_N(i, kElementCount))
{
uRet ^= AuHashCode(this->elements[i]);
}
}
return uRet;
}
};
#else
#if !defined(AURORA_RUNTIME_AU_ARRAY)
#define AURORA_RUNTIME_AU_ARRAY std::array
#endif
template <class T, size_t Z>
using AuArray = AURORA_RUNTIME_AU_ARRAY<T, Z>;
#endif