AuROXTL/Include/auROXTL/auArray.hpp

228 lines
4.8 KiB
C++
Raw Normal View History

/***
2022-04-01 04:06:53 +00:00
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)
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;
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 swap(AuArray &other)
{
AuArray temp;
if constexpr (std::is_trivially_copyable_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];
}
}
}
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 const_iterator cbegin() const
{
return begin();
}
constexpr const_iterator cend() const
{
return end();
}
constexpr size_type size() const
{
return kElementCount;
}
constexpr size_type max_size() const
{
return kElementCount;
}
2022-04-01 04:06:53 +00:00
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 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 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 (std::is_trivially_copyable_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