[+] AuToIterator (function)
[+] AuToElementType (function) [+] AuToValueType (function) [+] Optimized 32bit/64bit hash routines [+] AuFnv1aRuntime (32bit/64bit auto variant) [+] std::array reimplementation for reasons i deleted from the file bc sperging [+] AuArrayList
This commit is contained in:
parent
117390825c
commit
f4487c589c
@ -76,4 +76,8 @@
|
||||
|
||||
//#define _AURORA_NULLEXPT_USE_TRY_EMPLACE_AFTER_FIND
|
||||
|
||||
//#define _AURORA_MISSING_STD_EXCEPTION
|
||||
//#define _AURORA_MISSING_STD_EXCEPTION
|
||||
|
||||
//#define _AURORA_AVOID_DUMB_STL_TYPES
|
||||
|
||||
#define _AURORA_AVOID_EXTREMLY_DUMB_STL_TYPES
|
||||
|
@ -1,4 +1,4 @@
|
||||
/***
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auArray.hpp
|
||||
@ -7,9 +7,221 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#if !defined(AURORA_RUNTIME_AU_ARRAY)
|
||||
#define AURORA_RUNTIME_AU_ARRAY std::array
|
||||
#endif
|
||||
#if defined(_AURORA_AVOID_EXTREMLY_DUMB_STL_TYPES) && !defined(_AURORA_FORCE_STD_ARRAY)
|
||||
template <class T, size_t Count>
|
||||
struct AuArray
|
||||
{
|
||||
T elements[Count] {};
|
||||
|
||||
template <class T, size_t Z>
|
||||
using AuArray = AURORA_RUNTIME_AU_ARRAY<T, Z>;
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
15
Include/auROXTL/auArrayList.hpp
Normal file
15
Include/auROXTL/auArrayList.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
/***
|
||||
Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: auArrayList.hpp
|
||||
Date: 2023-1-18
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#if !defined(AURORA_RUNTIME_AU_ARRAY_LIST)
|
||||
#define AURORA_RUNTIME_AU_ARRAY_LIST std::list
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
using AuArrayList = AURORA_RUNTIME_AU_ARRAY_LIST<T>;
|
@ -137,4 +137,11 @@ inline AuUInt64 AuFnv1a64Runtime(const void *base, AuUInt length) noexcept
|
||||
return result;
|
||||
}
|
||||
|
||||
inline auto AuFnv1aRuntime(const void *base, AuUInt length) noexcept
|
||||
{
|
||||
return _AU_FNV1_32 ?
|
||||
AuFnv1a32Runtime(base, length) :
|
||||
AuFnv1a64Runtime(base, length);
|
||||
}
|
||||
|
||||
#undef _AU_FNV1_32
|
@ -46,47 +46,135 @@ namespace AuHash
|
||||
}
|
||||
};
|
||||
|
||||
#define _HASH_F_CPP(type) \
|
||||
template <> \
|
||||
struct hash<type> \
|
||||
{ \
|
||||
constexpr AuUInt operator ()(const type b) const \
|
||||
{ \
|
||||
return AuFnv1aType<type>(b); \
|
||||
} \
|
||||
// Thomas Wang, Integer Hash Functions: https://web.archive.org/web/20061201032901/http://www.concentric.net/%7ETtwang/tech/inthash.htm
|
||||
// Updated version under V8: V8/v9-11/src/utils/utils.h
|
||||
//
|
||||
// I'm sure Google's tweaks and subsequence implementations have justification grounded in reality more so than the initial publishing of a 1999ish article by some dude at HP
|
||||
// Real world experience > 1999 HP guy > whatever the fuck the stl is doing (i think ms just uses fnv1s for everything)
|
||||
//
|
||||
// Preserving original function names for ease of xref. unseeded vs implied seeded doesnt mean anything. see: ComputeLongHash comment.
|
||||
inline constexpr AuUInt32 ComputeUnseededHash(AuUInt32 key)
|
||||
{
|
||||
AuUInt32 hash = key;
|
||||
hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
|
||||
hash = hash ^ (hash >> 12);
|
||||
hash = hash + (hash << 2);
|
||||
hash = hash ^ (hash >> 4);
|
||||
hash = hash * 2057; // hash = (hash + (hash << 3)) + (hash << 11);
|
||||
hash = hash ^ (hash >> 16);
|
||||
return hash;
|
||||
}
|
||||
|
||||
// ComputeLongHash(base::double_to_uint64(AsNumber())); ( pre-maglev V8 wasn't u64 optimizated. )
|
||||
// ComputeLongHash(static_cast<uint64_t>(digit(0))); ( most js wont touch >31bit ints. )
|
||||
inline constexpr AuUInt64 ComputeLongHash(AuUInt64 key)// ( i'm sure this function's fine for all ranges. )
|
||||
{
|
||||
AuUInt64 hash = key;
|
||||
hash = ~hash + (hash << 18); // hash = (hash << 18) - hash - 1;
|
||||
hash = hash ^ (hash >> 31);
|
||||
hash = hash * 21; // hash = (hash + (hash << 2)) + (hash << 4);
|
||||
hash = hash ^ (hash >> 11); // key = key ^ (key >>> 28); ?
|
||||
hash = hash + (hash << 6); // key = key + (key << 31); ?
|
||||
hash = hash ^ (hash >> 22); // ???????????
|
||||
return hash;
|
||||
}
|
||||
|
||||
#define _HASH_INT(type) \
|
||||
template <> \
|
||||
struct hash<type> \
|
||||
{ \
|
||||
constexpr AuUInt operator ()(const type b) const \
|
||||
{ \
|
||||
return AuFnv1aType<type>(b); \
|
||||
} \
|
||||
};
|
||||
|
||||
_HASH_F_CPP(bool);
|
||||
_HASH_F_CPP(char);
|
||||
_HASH_F_CPP(signed char);
|
||||
_HASH_F_CPP(unsigned char);
|
||||
_HASH_F_CPP(char8_t);
|
||||
_HASH_F_CPP(char16_t);
|
||||
_HASH_F_CPP(char32_t);
|
||||
_HASH_F_CPP(wchar_t);
|
||||
_HASH_F_CPP(short);
|
||||
_HASH_F_CPP(unsigned short);
|
||||
_HASH_F_CPP(int);
|
||||
_HASH_F_CPP(unsigned int);
|
||||
_HASH_F_CPP(long);
|
||||
_HASH_F_CPP(long long);
|
||||
_HASH_F_CPP(unsigned long);
|
||||
_HASH_F_CPP(unsigned long long);
|
||||
_HASH_F_CPP(float);
|
||||
_HASH_F_CPP(double);
|
||||
_HASH_F_CPP(long double);
|
||||
_HASH_F_CPP(std::nullptr_t);
|
||||
#if defined(AURORA_IS_32BIT)
|
||||
|
||||
#undef _HASH_F_CPP
|
||||
#define _HASH_INT32BIT(type) \
|
||||
template <> \
|
||||
struct hash<type> \
|
||||
{ \
|
||||
constexpr AuUInt operator ()(const type intValue) const \
|
||||
{ \
|
||||
return ComputeUnseededHash(AuUInt32(intValue)); \
|
||||
} \
|
||||
};
|
||||
|
||||
template <class T> struct hash<T *>
|
||||
#else
|
||||
|
||||
#define _HASH_INT32BIT(type) \
|
||||
template <> \
|
||||
struct hash<type> \
|
||||
{ \
|
||||
constexpr AuUInt operator ()(const type intValue) const \
|
||||
{ \
|
||||
return ComputeLongHash(AuUInt64(intValue)); \
|
||||
} \
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_32BIT)
|
||||
|
||||
#define _HASH_INT64BIT(type) \
|
||||
template <> \
|
||||
struct hash<type> \
|
||||
{ \
|
||||
constexpr AuUInt operator ()(const type intValue) const \
|
||||
{ \
|
||||
return AuUInt32(ComputeLongHash(AuUInt64(intValue)) & 0xFFFFFFFF); \
|
||||
} \
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define _HASH_INT64BIT(type) \
|
||||
template <> \
|
||||
struct hash<type> \
|
||||
{ \
|
||||
constexpr AuUInt operator ()(const type intValue) const \
|
||||
{ \
|
||||
return ComputeLongHash(AuUInt64(intValue)); \
|
||||
} \
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
_HASH_INT32BIT(bool);
|
||||
_HASH_INT32BIT(char);
|
||||
_HASH_INT32BIT(signed char);
|
||||
_HASH_INT32BIT(unsigned char);
|
||||
_HASH_INT32BIT(char8_t);
|
||||
_HASH_INT32BIT(char16_t);
|
||||
_HASH_INT32BIT(char32_t);
|
||||
_HASH_INT32BIT(wchar_t);
|
||||
_HASH_INT32BIT(short);
|
||||
_HASH_INT32BIT(unsigned short);
|
||||
_HASH_INT32BIT(int);
|
||||
_HASH_INT32BIT(unsigned int);
|
||||
_HASH_INT64BIT(long);
|
||||
_HASH_INT64BIT(long long);
|
||||
_HASH_INT64BIT(unsigned long);
|
||||
_HASH_INT64BIT(unsigned long long);
|
||||
_HASH_INT(float);
|
||||
_HASH_INT(double);
|
||||
_HASH_INT(long double);
|
||||
_HASH_INT(std::nullptr_t);
|
||||
|
||||
#undef _HASH_INT
|
||||
#undef _HASH_INT32BIT
|
||||
#undef _HASH_INT64BIT
|
||||
|
||||
template <class T>
|
||||
struct hash<T *>
|
||||
{
|
||||
AuUInt operator ()(T *ptr) const
|
||||
{
|
||||
#if defined(AURORA_IS_32BIT)
|
||||
return AuFnv1a32Runtime(&ptr, sizeof(T *));
|
||||
return ComputeUnseededHash(AuUInt(ptr));
|
||||
#else
|
||||
return AuFnv1a64Runtime(&ptr, sizeof(T *));
|
||||
return ComputeLongHash(AuUInt(ptr));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
@ -11,5 +11,10 @@
|
||||
#define AURORA_RUNTIME_AU_OPTIONAL std::optional
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
using AuOptional = AURORA_RUNTIME_AU_OPTIONAL<T>;
|
||||
#if defined(_AURORA_AVOID_DUMB_STL_TYPES)
|
||||
template <class T>
|
||||
using AuOptional = AuOptionalEx<T>;
|
||||
#else
|
||||
template <class T>
|
||||
using AuOptional = AURORA_RUNTIME_AU_OPTIONAL<T>;
|
||||
#endif
|
||||
|
@ -39,6 +39,15 @@ using AuToElementType_t = typename T::element_type;
|
||||
template <class T>
|
||||
using AuToIterator_t = typename T::iterator;
|
||||
|
||||
template <typename T>
|
||||
static AuToIterator_t<T> AuToIterator(const T &a); // intended use case: screwing over nasty ass lines of `AuToIterator_t<decltype(muh member)>` or worse.
|
||||
// example usage: `decltype(AuToIterator(myHashMap)) itr;`
|
||||
template <typename T>
|
||||
static AuToElementType_t<T> AuToElementType(const T &a);
|
||||
|
||||
template <typename T>
|
||||
static AuToValueType_t<T> AuToValueType(const T &a);
|
||||
|
||||
template <class T, class U>
|
||||
struct AuIsSame : AuFalseType
|
||||
{};
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <auROXTL/auTuple.hpp>
|
||||
#include <auROXTL/auOptional.hpp>
|
||||
#include <auROXTL/auVector.hpp>
|
||||
#include <auROXTL/auArrayList.hpp>
|
||||
|
||||
namespace Aurora::Memory
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user