11#ifndef INCGUARD_MGL_ARRAY_H_1744450834
12#define INCGUARD_MGL_ARRAY_H_1744450834
31template <
class ValueType,
class IndexType =
size_t>
36 static_assert(std::is_default_constructible_v<ValueType>,
"Array element must be constructible by default.");
39 static_assert(std::is_integral_v<IndexType>,
"IndexType must be integral value.");
54 Allocate(arraySize, clearMode);
65 Array(
size_t arraySize,
const ValueType &invalidValue,
Memory::ClearMode clearMode = Memory::ClearMode::Auto)
noexcept
67 Allocate(arraySize, clearMode);
81 Allocate(arraySize, clearMode);
93 *
this = std::move(rhs);
107 _arraySize = rhs._arraySize;
141 if (_tail !=
nullptr)
143 auto invalidValue = std::move(*_tail);
144 if (Allocate(arraySize, clearMode))
155 return Allocate(arraySize, clearMode);
169 return New(_arraySize, clearMode);
178 constexpr void Fill(
const ValueType &value)
noexcept
180 for (
auto *e =
begin(); e !=
end(); e++)
193 [[nodiscard]]
constexpr const ValueType &
Get(IndexType index)
const noexcept
195 return _top[GetIndex(index)];
205 [[nodiscard]]
constexpr const ValueType &
operator[](IndexType index)
const noexcept
217 [[nodiscard]]
constexpr ValueType *
GetPtr(IndexType index)
noexcept
219 if (
auto i = GetIndex(index); i < _arraySize)
221 return std::addressof(_top[i]);
236 constexpr bool Set(IndexType index,
const ValueType &value)
noexcept
238 if (
auto *e =
GetPtr(index); e !=
nullptr)
256 template <
class Body>
257 constexpr bool Write(IndexType index, Body body)
noexcept
259 if (
auto *e =
GetPtr(index); e !=
nullptr)
261 if constexpr (std::is_invocable_r_v<void,
decltype(body), ValueType &>)
268 static_assert(std::false_type::value,
"Write function is not matching arguments.");
285 constexpr bool Set(IndexType index, ValueType &&value)
noexcept
287 if (
auto *e =
GetPtr(index); e !=
nullptr)
289 *e = std::move(value);
303 template <
class LoopBody>
304 constexpr void ForEach(LoopBody body)
noexcept
306 for (
size_t i = 0; i < _arraySize; i++)
308 if (!InvokeLoopBody(body,
static_cast<IndexType
>(i)))
322 template <
class LoopBody>
323 constexpr void ForEach(LoopBody body)
const noexcept
325 for (
size_t i = 0; i < _arraySize; i++)
327 if (!InvokeLoopBody(body,
static_cast<IndexType
>(i)))
343 template <
class LoopBody>
352 std::clamp(
begin,
static_cast<IndexType
>(0),
static_cast<IndexType
>(_arraySize) - 1),
353 std::clamp(
end,
static_cast<IndexType
>(0),
static_cast<IndexType
>(_arraySize) - 1));
357 if (!InvokeLoopBody(body, i))
373 template <
class LoopBody>
382 std::clamp(
begin, 0,
static_cast<IndexType
>(_arraySize) - 1),
383 std::clamp(
end, 0,
static_cast<IndexType
>(_arraySize) - 1));
387 if (!InvokeLoopBody(body, i))
402 [[nodiscard]]
constexpr bool Contains(
const ValueType &element)
const noexcept
404 return Contains(std::addressof(element));
415 [[nodiscard]]
constexpr bool Contains(
const ValueType *element)
const noexcept
421 auto topAddress =
reinterpret_cast<uintptr_t
>(_top);
422 auto elemAddress =
reinterpret_cast<uintptr_t
>(element);
423 auto tailAddress =
reinterpret_cast<uintptr_t
>(_tail);
425 return (topAddress <= elemAddress) && (elemAddress < tailAddress);
436 if (_tail !=
nullptr)
450 if (_tail !=
nullptr)
452 *_tail = std::move(value);
462 [[nodiscard]]
constexpr size_t GetSize() const noexcept
473 [[nodiscard]]
constexpr ValueType *
begin() const noexcept
484 [[nodiscard]]
constexpr ValueType *
end() const noexcept
495 [[nodiscard]]
constexpr const ValueType *
cbegin() const noexcept
506 [[nodiscard]]
constexpr const ValueType *
cend() const noexcept
524 if ((_top !=
nullptr) && (_arraySize == arraySize))
527 std::destroy_n(_top, _arraySize + 1);
530 _top = Memory::Utility::InitializeArrayBuffer<ValueType>(_top, _arraySize + 1, clearMode);
539 const auto size =
sizeof(ValueType) * (arraySize + 1);
540 auto *ptr = Memory::Allocate(size);
548 _top = Memory::Utility::InitializeArrayBuffer<ValueType>(ptr, arraySize + 1, clearMode);
551 _tail = std::addressof(_top[arraySize]);
552 _arraySize = arraySize;
563 void Deallocate() noexcept
567 std::destroy_n(_top, _arraySize + 1);
568 Memory::Deallocate(_top);
569 _top = _tail =
nullptr;
581 [[nodiscard]]
constexpr size_t GetIndex(IndexType index)
const noexcept
584 if constexpr (std::is_signed_v<IndexType>)
586 if ((index >= 0) && (
static_cast<size_t>(index) < _arraySize))
588 return static_cast<size_t>(index);
594 if (
static_cast<size_t>(index) < _arraySize)
596 return static_cast<size_t>(index);
614 template <
class LoopBody>
615 constexpr bool InvokeLoopBody(LoopBody body, IndexType index)
noexcept
618 if constexpr (std::is_invocable_r_v<bool,
decltype(body), IndexType,
ValueType &>)
620 return body(index, _top[GetIndex(index)]);
623 else if constexpr (std::is_invocable_r_v<void,
decltype(body), IndexType,
ValueType &>)
625 body(index, _top[GetIndex(index)]);
629 else if constexpr (std::is_invocable_r_v<bool,
decltype(body),
ValueType &>)
631 return body(_top[GetIndex(index)]);
634 else if constexpr (std::is_invocable_r_v<void,
decltype(body),
ValueType &>)
636 body(_top[GetIndex(index)]);
642 static_assert(std::false_type::value,
"Loop body is not matching arguments.");
657 template <
class LoopBody>
658 constexpr bool InvokeLoopBody(LoopBody body, IndexType index)
const noexcept
661 if constexpr (std::is_invocable_r_v<bool,
decltype(body), IndexType,
ValueType &>)
663 return body(index, _top[GetIndex(index)]);
666 else if constexpr (std::is_invocable_r_v<void,
decltype(body), IndexType,
ValueType &>)
668 body(index, _top[GetIndex(index)]);
672 else if constexpr (std::is_invocable_r_v<bool,
decltype(body),
ValueType &>)
674 return body(_top[GetIndex(index)]);
677 else if constexpr (std::is_invocable_r_v<void,
decltype(body),
ValueType &>)
679 body(_top[GetIndex(index)]);
685 static_assert(std::false_type::value,
"Loop body is not matching arguments.");
690 size_t _arraySize{0};
動的配列クラス
Definition mgl_array.h:33
constexpr void ForEach(LoopBody body) noexcept
全ての要素へのアクセス
Definition mgl_array.h:304
constexpr void SetInvalidValue(const ValueType &value) noexcept
無効値の設定
Definition mgl_array.h:434
constexpr bool Contains(const ValueType *element) const noexcept
指定した要素が範囲内に含まれているかを取得
Definition mgl_array.h:415
constexpr const ValueType & Get(IndexType index) const noexcept
要素の取得
Definition mgl_array.h:193
constexpr ValueType * GetPtr(IndexType index) noexcept
書き込み可能な要素へのポインタを取得
Definition mgl_array.h:217
Array(size_t arraySize=0, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array.h:52
Array(size_t arraySize, const ValueType &invalidValue, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array.h:65
constexpr bool Contains(const ValueType &element) const noexcept
指定した要素が範囲内に含まれているかを取得
Definition mgl_array.h:402
constexpr void SetInvalidValue(ValueType &&value) noexcept
無効値の設定
Definition mgl_array.h:448
constexpr void ForRange(IndexType begin, IndexType end, LoopBody body) const noexcept
範囲を指定して読み取り専用で要素にアクセス
Definition mgl_array.h:374
~Array() noexcept
デストラクタ
Definition mgl_array.h:124
constexpr bool Write(IndexType index, Body body) noexcept
値の書き込み
Definition mgl_array.h:257
bool Renew(Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
配列を同じサイズで構築し直す
Definition mgl_array.h:167
constexpr ValueType * begin() const noexcept
先頭の要素を取得
Definition mgl_array.h:473
constexpr bool Set(IndexType index, ValueType &&value) noexcept
要素に値をムーブ設定
Definition mgl_array.h:285
constexpr const ValueType & operator[](IndexType index) const noexcept
添字による要素の取得
Definition mgl_array.h:205
constexpr void ForEach(LoopBody body) const noexcept
全ての要素へ読み取り専用でアクセス
Definition mgl_array.h:323
Array & operator=(Array &&rhs) noexcept
ムーブ代入
Definition mgl_array.h:102
constexpr ValueType * end() const noexcept
末尾の要素を取得
Definition mgl_array.h:484
Array(size_t arraySize, ValueType &&invalidValue, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array.h:79
constexpr bool Set(IndexType index, const ValueType &value) noexcept
要素に値を設定
Definition mgl_array.h:236
bool New(size_t arraySize, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
配列の生成
Definition mgl_array.h:138
constexpr const ValueType * cend() const noexcept
末尾の要素をconstで取得
Definition mgl_array.h:506
constexpr void ForRange(IndexType begin, IndexType end, LoopBody body) noexcept
範囲を指定して要素にアクセス
Definition mgl_array.h:344
constexpr size_t GetSize() const noexcept
配列の要素数を取得
Definition mgl_array.h:462
constexpr void Fill(const ValueType &value) noexcept
全ての要素を指定値で書き込む
Definition mgl_array.h:178
constexpr const ValueType * cbegin() const noexcept
先頭の要素をconstで取得
Definition mgl_array.h:495
Array(Array &&rhs) noexcept
ムーブコンストラクタ
Definition mgl_array.h:91
値の範囲を表現するクラス
Definition mgl_range.h:28
constexpr bool Contains(T value) const noexcept
指定された値が範囲内に含まれているかを取得
Definition mgl_range.h:181
constexpr T Next(T value) const noexcept
指定された値の次の値を取得
Definition mgl_range.h:142
constexpr T Begin() const noexcept
開始値を取得
Definition mgl_range.h:56
ValueType
値のタイプ
Definition mgl_achievement_defs.h:33
ClearMode
クリアモード
Definition mgl_memory_utility.h:23
#define MGL_ASSERT(...)
アサート用マクロ
Definition mgl_system_debug_macro.h:88