11#ifndef INCGUARD_MGL_ARRAY_2D_H_1746562234
12#define INCGUARD_MGL_ARRAY_2D_H_1746562234
31template <
class ValueType,
class IndexType =
size_t>
36 static_assert(std::is_default_constructible_v<ValueType>,
"Array2D element must be constructible by default.");
39 static_assert(std::is_integral_v<IndexType>,
"IndexType must be integral value.");
66 Allocate(width, height, clearMode);
78 Array2D(IndexType width, IndexType height,
const ValueType &invalidValue,
Memory::ClearMode clearMode = Memory::ClearMode::Auto)
noexcept
80 Allocate(width, height, clearMode);
93 Array2D(IndexType width, IndexType height, ValueType &&invalidValue,
Memory::ClearMode clearMode = Memory::ClearMode::Auto)
noexcept
95 Allocate(width, height, clearMode);
107 *
this = std::move(rhs);
122 _height = rhs._height;
123 _arraySize = rhs._arraySize;
160 if (_tail !=
nullptr)
162 auto invalidValue = std::move(*_tail);
163 if (Allocate(width, height, clearMode))
174 return Allocate(width, height, clearMode);
188 return New(_width, _height, clearMode);
197 constexpr void Fill(
const ValueType &value)
noexcept
199 for (
auto *e =
begin(); e !=
end(); ++e)
213 [[nodiscard]]
static constexpr std::pair<IndexType, IndexType>
MakePair(IndexType x, IndexType y)
noexcept
226 [[nodiscard]]
constexpr const ValueType &
Get(IndexType x, IndexType y)
const noexcept
228 return _top[GetIndex(x, y)];
238 [[nodiscard]]
const ValueType &
Get(
const std::pair<IndexType, IndexType> &pair)
const noexcept
240 return Get(pair.first, pair.second);
243#if __cplusplus >= 202211L
252 [[nodiscard]]
const ValueType &
operator[](IndexType x, IndexType y)
const noexcept
265 [[nodiscard]]
const ValueType &
operator[](
const std::pair<IndexType, IndexType> &pair)
const noexcept
267 return Get(pair.first, pair.second);
278 [[nodiscard]]
constexpr ValueType *
GetPtr(IndexType x, IndexType y)
noexcept
280 auto index = GetIndex(x, y);
281 if (index >= _arraySize)
296 [[nodiscard]]
constexpr ValueType *
GetPtr(
const std::pair<IndexType, IndexType> &pair)
noexcept
298 return GetPtr(pair.first, pair.second);
311 constexpr bool Set(IndexType x, IndexType y,
const ValueType &value)
noexcept
313 if (
auto *e =
GetPtr(x, y); e !=
nullptr)
331 constexpr bool Set(
const std::pair<IndexType, IndexType> &pair,
const ValueType &value)
noexcept
333 return Set(pair.first, pair.second, value);
346 constexpr bool Set(IndexType x, IndexType y,
const ValueType &&value)
noexcept
348 if (
auto *e =
GetPtr(x, y); e !=
nullptr)
350 *e = std::move(value);
366 constexpr bool Set(
const std::pair<IndexType, IndexType> &pair,
const ValueType &&value)
noexcept
368 return Set(pair.first, pair.second, std::forward<ValueType>(value));
381 template <
class Body>
382 constexpr bool Write(IndexType x, IndexType y, Body body)
noexcept
384 if (
auto *e =
GetPtr(x, y); e !=
nullptr)
386 if constexpr (std::is_invocable_r_v<void,
decltype(body), ValueType &>)
393 static_assert(std::false_type::value,
"Write function is not matching arguments.");
410 template <
class Body>
411 constexpr bool Write(
const std::pair<IndexType, IndexType> &pair, Body body)
noexcept
413 return Write(pair.first, pair.second, body);
423 template <
class LoopBody>
424 constexpr void ForEach(LoopBody body)
noexcept
426 for (IndexType y = 0; y < _height; ++y)
428 for (IndexType x = 0; x < _width; ++x)
430 if (!InvokeLoopBody(body, x, y))
445 template <
class LoopBody>
446 constexpr void ForEach(LoopBody body)
const noexcept
448 for (IndexType y = 0; y < _height; ++y)
450 for (IndexType x = 0; x < _width; ++x)
452 if (!InvokeLoopBody(body, x, y))
471 template <
class LoopBody>
472 constexpr void ForRange(IndexType beginX, IndexType beginY, IndexType endX, IndexType endY, LoopBody body)
noexcept
480 std::clamp(beginX,
static_cast<IndexType
>(0),
GetWidth() - 1),
481 std::clamp(endX,
static_cast<IndexType
>(0),
GetWidth() - 1));
484 std::clamp(beginY,
static_cast<IndexType
>(0),
GetHeight() - 1),
485 std::clamp(endY,
static_cast<IndexType
>(0),
GetHeight() - 1));
491 if (!InvokeLoopBody(body, x, y))
508 template <
class LoopBody>
510 const std::pair<IndexType, IndexType> &
begin,
511 const std::pair<IndexType, IndexType> &
end,
512 LoopBody body)
noexcept
528 template <
class LoopBody>
529 constexpr void ForRange(IndexType beginX, IndexType beginY, IndexType endX, IndexType endY, LoopBody body)
const noexcept
537 std::clamp(beginX, 0,
GetWidth() - 1),
538 std::clamp(endX, 0,
GetWidth() - 1));
548 if (!InvokeLoopBody(body, x, y))
565 template <
class LoopBody>
567 const std::pair<IndexType, IndexType> &
begin,
568 const std::pair<IndexType, IndexType> &
end,
569 LoopBody body)
const noexcept
582 [[nodiscard]]
constexpr bool Contains(
const ValueType &element)
const noexcept
584 return Contains(std::addressof(element));
595 [[nodiscard]]
constexpr bool Contains(
const ValueType *element)
const noexcept
601 auto topAddress =
reinterpret_cast<uintptr_t
>(_top);
602 auto elemAddress =
reinterpret_cast<uintptr_t
>(element);
603 auto tailAddress =
reinterpret_cast<uintptr_t
>(_tail);
605 return (topAddress <= elemAddress) && (elemAddress < tailAddress);
616 if (_tail !=
nullptr)
630 if (_tail !=
nullptr)
632 *_tail = std::move(value);
642 [[nodiscard]]
constexpr IndexType
GetWidth() const noexcept
653 [[nodiscard]]
constexpr IndexType
GetHeight() const noexcept
675 [[nodiscard]]
constexpr ValueType *
begin() const noexcept
686 [[nodiscard]]
constexpr ValueType *
end() const noexcept
697 [[nodiscard]]
constexpr const ValueType *
cbegin() const noexcept
708 [[nodiscard]]
constexpr const ValueType *
cend() const noexcept
724 bool Allocate(IndexType width, IndexType height,
Memory::ClearMode clearMode)
noexcept
727 if constexpr (std::is_signed_v<IndexType>)
729 width = std::max(0, width);
730 height = std::max(0, height);
734 if ((width == 0) || (height == 0))
738 auto arraySize =
static_cast<size_t>(width) *
static_cast<size_t>(height);
741 if ((_top !=
nullptr) && (_arraySize == arraySize))
744 std::destroy_n(_top, _arraySize + 1);
747 _top = Memory::Utility::InitializeArrayBuffer<ValueType>(_top, _arraySize + 1, clearMode);
756 const auto size =
sizeof(
ValueType) * (arraySize + 1);
757 auto *ptr = Memory::Allocate(size);
765 _top = Memory::Utility::InitializeArrayBuffer<ValueType>(ptr, arraySize + 1, clearMode);
768 _tail = std::addressof(_top[arraySize]);
771 _arraySize = arraySize;
782 void Deallocate() noexcept
786 std::destroy_n(_top, _arraySize + 1);
787 Memory::Deallocate(_top);
788 _top = _tail =
nullptr;
801 [[nodiscard]]
constexpr size_t GetIndex(IndexType x, IndexType y)
const noexcept
804 if constexpr (std::is_signed_v<IndexType>)
822 return static_cast<size_t>(y * _width + x);
836 template <
class LoopBody>
837 constexpr bool InvokeLoopBody(LoopBody body, IndexType x, IndexType y)
noexcept
840 if constexpr (std::is_invocable_r_v<bool,
decltype(body), IndexType, IndexType,
ValueType &>)
842 return body(x, y, _top[GetIndex(x, y)]);
845 else if constexpr (std::is_invocable_r_v<void,
decltype(body), IndexType, IndexType,
ValueType &>)
847 body(x, y, _top[GetIndex(x, y)]);
851 else if constexpr (std::is_invocable_r_v<bool,
decltype(body),
ValueType &>)
853 return body(_top[GetIndex(x, y)]);
856 else if constexpr (std::is_invocable_r_v<void,
decltype(body),
ValueType &>)
858 body(_top[GetIndex(x, y)]);
864 static_assert(std::false_type::value,
"Loop body is not matching arguments.");
880 template <
class LoopBody>
881 constexpr bool InvokeLoopBody(LoopBody body, IndexType x, IndexType y)
const noexcept
884 if constexpr (std::is_invocable_r_v<bool,
decltype(body), IndexType, IndexType,
const ValueType &>)
886 return body(x, y, _top[GetIndex(x, y)]);
889 else if constexpr (std::is_invocable_r_v<void,
decltype(body), IndexType, IndexType,
const ValueType &>)
891 body(x, y, _top[GetIndex(x, y)]);
895 else if constexpr (std::is_invocable_r_v<bool,
decltype(body),
const ValueType &>)
897 return body(_top[GetIndex(x, y)]);
900 else if constexpr (std::is_invocable_r_v<void,
decltype(body),
const ValueType &>)
902 body(_top[GetIndex(x, y)]);
908 static_assert(std::false_type::value,
"Loop body is not matching arguments.");
914 IndexType _height{0};
915 size_t _arraySize{0};
動的2次元配列クラス
Definition mgl_array_2d.h:33
Array2D & operator=(Array2D &&rhs) noexcept
ムーブ代入
Definition mgl_array_2d.h:116
bool Renew(Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
配列を同じサイズで構築し直す
Definition mgl_array_2d.h:186
constexpr ValueType * begin() const noexcept
先頭の要素を取得
Definition mgl_array_2d.h:675
constexpr IndexType GetHeight() const noexcept
配列のY方向の最大値を取得
Definition mgl_array_2d.h:653
static constexpr std::pair< IndexType, IndexType > MakePair(IndexType x, IndexType y) noexcept
ペアの生成
Definition mgl_array_2d.h:213
constexpr const ValueType * cbegin() const noexcept
先頭の要素をconstで取得
Definition mgl_array_2d.h:697
bool New(IndexType width, IndexType height, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
配列の生成
Definition mgl_array_2d.h:157
constexpr void ForRange(IndexType beginX, IndexType beginY, IndexType endX, IndexType endY, LoopBody body) noexcept
範囲を指定して要素にアクセス
Definition mgl_array_2d.h:472
constexpr IndexType GetWidth() const noexcept
配列のX方向の最大値を取得
Definition mgl_array_2d.h:642
constexpr ValueType * GetPtr(IndexType x, IndexType y) noexcept
書き込み可能な要素へのポインタを取得
Definition mgl_array_2d.h:278
constexpr size_t GetArraySize() const noexcept
配列全体のサイズを取得
Definition mgl_array_2d.h:664
constexpr bool Set(const std::pair< IndexType, IndexType > &pair, const ValueType &&value) noexcept
要素に値を設定
Definition mgl_array_2d.h:366
constexpr bool Set(IndexType x, IndexType y, const ValueType &&value) noexcept
要素に値を設定
Definition mgl_array_2d.h:346
Array2D(IndexType width, IndexType height, ValueType &&invalidValue, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array_2d.h:93
constexpr void ForEach(LoopBody body) const noexcept
全ての要素へ読み取り専用でアクセス
Definition mgl_array_2d.h:446
constexpr void ForRange(const std::pair< IndexType, IndexType > &begin, const std::pair< IndexType, IndexType > &end, LoopBody body) noexcept
範囲を指定して要素にアクセス
Definition mgl_array_2d.h:509
constexpr void Fill(const ValueType &value) noexcept
全ての要素を指定値で書き込む
Definition mgl_array_2d.h:197
constexpr bool Contains(const ValueType *element) const noexcept
指定した要素が範囲内に含まれているかを取得
Definition mgl_array_2d.h:595
constexpr void ForRange(IndexType beginX, IndexType beginY, IndexType endX, IndexType endY, LoopBody body) const noexcept
範囲を指定して読み取り専用で要素にアクセス
Definition mgl_array_2d.h:529
constexpr bool Set(IndexType x, IndexType y, const ValueType &value) noexcept
要素に値を設定
Definition mgl_array_2d.h:311
const ValueType & operator[](const std::pair< IndexType, IndexType > &pair) const noexcept
添字演算子による要素の取得
Definition mgl_array_2d.h:265
constexpr bool Set(const std::pair< IndexType, IndexType > &pair, const ValueType &value) noexcept
要素に値を設定
Definition mgl_array_2d.h:331
constexpr void ForRange(const std::pair< IndexType, IndexType > &begin, const std::pair< IndexType, IndexType > &end, LoopBody body) const noexcept
範囲を指定して読み取り専用で要素にアクセス
Definition mgl_array_2d.h:566
constexpr void SetInvalidValue(ValueType &&value) noexcept
無効値の設定
Definition mgl_array_2d.h:628
constexpr ValueType * end() const noexcept
末尾の要素を取得
Definition mgl_array_2d.h:686
constexpr bool Write(IndexType x, IndexType y, Body body) noexcept
値の書き込み
Definition mgl_array_2d.h:382
constexpr const ValueType * cend() const noexcept
末尾の要素をconstで取得
Definition mgl_array_2d.h:708
constexpr bool Write(const std::pair< IndexType, IndexType > &pair, Body body) noexcept
値の書き込み
Definition mgl_array_2d.h:411
~Array2D() noexcept
デストラクタ
Definition mgl_array_2d.h:142
Array2D(Array2D &&rhs) noexcept
ムーブコンストラクタ
Definition mgl_array_2d.h:105
constexpr void SetInvalidValue(const ValueType &value) noexcept
無効値の設定
Definition mgl_array_2d.h:614
constexpr void ForEach(LoopBody body) noexcept
全ての要素へのアクセス
Definition mgl_array_2d.h:424
constexpr bool Contains(const ValueType &element) const noexcept
指定した要素が範囲内に含まれているかを取得
Definition mgl_array_2d.h:582
const ValueType & Get(const std::pair< IndexType, IndexType > &pair) const noexcept
要素の取得
Definition mgl_array_2d.h:238
constexpr ValueType * GetPtr(const std::pair< IndexType, IndexType > &pair) noexcept
書き込み可能な要素へのポインタを取得
Definition mgl_array_2d.h:296
Array2D(IndexType width, IndexType height, const ValueType &invalidValue, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array_2d.h:78
Array2D(Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array_2d.h:51
Array2D(IndexType width, IndexType height, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array_2d.h:64
constexpr const ValueType & Get(IndexType x, IndexType y) const noexcept
要素の取得
Definition mgl_array_2d.h:226
値の範囲を表現するクラス
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