11#ifndef INCGUARD_MGL_ARRAY_2D_H_1746562234
12#define INCGUARD_MGL_ARRAY_2D_H_1746562234
20#include <mgl/memory/mgl_memory_utility.h>
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.");
51 Array2D(Memory::ClearMode clearMode = Memory::ClearMode::Auto) noexcept
64 Array2D(IndexType width, IndexType height, Memory::ClearMode clearMode = Memory::ClearMode::Auto)
noexcept
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;
157 bool New(
size_t width,
size_t height, Memory::ClearMode clearMode = Memory::ClearMode::Auto)
noexcept
160 if (_tail !=
nullptr)
162 auto invalidValue = std::move(*_tail);
163 if (Allocate(width, height, clearMode))
174 return Allocate(width, height, clearMode);
186 bool Renew(Memory::ClearMode clearMode = Memory::ClearMode::Auto)
noexcept
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)
const noexcept
280 auto index = GetIndex(x, y);
281 if (index >= _arraySize)
296 [[nodiscard]]
constexpr ValueType *
GetPtr(
const std::pair<IndexType, IndexType> &pair)
const noexcept
298 return GetPtr(pair.first, pair.second);
308 template <
class LoopBody>
309 constexpr void ForEach(LoopBody body)
noexcept
311 for (IndexType y = 0; y < _height; ++y)
313 for (IndexType x = 0; x < _width; ++x)
315 if (!InvokeLoopBody(body, x, y))
330 template <
class LoopBody>
331 constexpr void ForEach(LoopBody body)
const noexcept
333 for (IndexType y = 0; y < _height; ++y)
335 for (IndexType x = 0; x < _width; ++x)
337 if (!InvokeLoopBody(body, x, y))
356 template <
class LoopBody>
357 constexpr void ForRange(IndexType beginX, IndexType beginY, IndexType endX, IndexType endY, LoopBody body)
noexcept
365 std::clamp(beginX,
static_cast<IndexType
>(0),
GetWidth() - 1),
366 std::clamp(endX,
static_cast<IndexType
>(0),
GetWidth() - 1));
369 std::clamp(beginY,
static_cast<IndexType
>(0),
GetHeight() - 1),
370 std::clamp(endY,
static_cast<IndexType
>(0),
GetHeight() - 1));
376 if (!InvokeLoopBody(body, x, y))
393 template <
class LoopBody>
395 const std::pair<IndexType, IndexType> &
begin,
396 const std::pair<IndexType, IndexType> &
end,
397 LoopBody body)
noexcept
413 template <
class LoopBody>
414 constexpr void ForRange(IndexType beginX, IndexType beginY, IndexType endX, IndexType endY, LoopBody body)
const noexcept
422 std::clamp(beginX, 0,
GetWidth() - 1),
423 std::clamp(endX, 0,
GetWidth() - 1));
433 if (!InvokeLoopBody(body, x, y))
450 template <
class LoopBody>
452 const std::pair<IndexType, IndexType> &
begin,
453 const std::pair<IndexType, IndexType> &
end,
454 LoopBody body)
const noexcept
467 [[nodiscard]]
constexpr bool Contains(
const ValueType &element)
const noexcept
469 return Contains(std::addressof(element));
480 [[nodiscard]]
constexpr bool Contains(
const ValueType *element)
const noexcept
486 auto topAddress =
reinterpret_cast<uintptr_t
>(_top);
487 auto elemAddress =
reinterpret_cast<uintptr_t
>(element);
488 auto tailAddress =
reinterpret_cast<uintptr_t
>(_tail);
490 return (topAddress <= elemAddress) && (elemAddress < tailAddress);
501 if (_tail !=
nullptr)
515 if (_tail !=
nullptr)
517 *_tail = std::move(value);
527 [[nodiscard]]
constexpr IndexType
GetWidth() const noexcept
538 [[nodiscard]]
constexpr IndexType
GetHeight() const noexcept
560 [[nodiscard]]
constexpr ValueType *
begin() const noexcept
571 [[nodiscard]]
constexpr ValueType *
end() const noexcept
582 [[nodiscard]]
constexpr const ValueType *
cbegin() const noexcept
593 [[nodiscard]]
constexpr const ValueType *
cend() const noexcept
609 bool Allocate(IndexType width, IndexType height, Memory::ClearMode clearMode)
noexcept
612 if constexpr (std::is_signed_v<IndexType>)
614 width = std::max(0, width);
615 height = std::max(0, height);
619 if ((width == 0) || (height == 0))
623 auto arraySize =
static_cast<size_t>(width) *
static_cast<size_t>(height);
626 if ((_top !=
nullptr) && (_arraySize == arraySize))
629 std::destroy_n(_top, _arraySize + 1);
632 _top = Memory::Utility::InitializeArrayBuffer<ValueType>(_top, _arraySize + 1, clearMode);
641 const auto size =
sizeof(
ValueType) * (arraySize + 1);
642 auto *ptr = Memory::Allocate(size);
650 _top = Memory::Utility::InitializeArrayBuffer<ValueType>(ptr, arraySize + 1, clearMode);
653 _tail = std::addressof(_top[arraySize]);
656 _arraySize = arraySize;
667 void Deallocate() noexcept
671 std::destroy_n(_top, _arraySize + 1);
672 Memory::Deallocate(_top);
673 _top = _tail =
nullptr;
686 [[nodiscard]]
constexpr size_t GetIndex(IndexType x, IndexType y)
const noexcept
689 if constexpr (std::is_signed_v<IndexType>)
707 return static_cast<size_t>(y * _width + x);
721 template <
class LoopBody>
722 constexpr bool InvokeLoopBody(LoopBody body, IndexType x, IndexType y)
noexcept
725 if constexpr (std::is_invocable_r_v<bool,
decltype(body), IndexType, IndexType,
ValueType &>)
727 return body(x, y, _top[GetIndex(x, y)]);
730 else if constexpr (std::is_invocable_r_v<void,
decltype(body), IndexType, IndexType,
ValueType &>)
732 body(x, y, _top[GetIndex(x, y)]);
736 else if constexpr (std::is_invocable_r_v<bool,
decltype(body),
ValueType &>)
738 return body(_top[GetIndex(x, y)]);
741 else if constexpr (std::is_invocable_r_v<void,
decltype(body),
ValueType &>)
743 body(_top[GetIndex(x, y)]);
749 static_assert(std::false_type::value,
"Loop body is not matching arguments.");
765 template <
class LoopBody>
766 constexpr bool InvokeLoopBody(LoopBody body, IndexType x, IndexType y)
const noexcept
769 if constexpr (std::is_invocable_r_v<bool,
decltype(body), IndexType, IndexType,
const ValueType &>)
771 return body(x, y, _top[GetIndex(x, y)]);
774 else if constexpr (std::is_invocable_r_v<void,
decltype(body), IndexType, IndexType,
const ValueType &>)
776 body(x, y, _top[GetIndex(x, y)]);
780 else if constexpr (std::is_invocable_r_v<bool,
decltype(body),
const ValueType &>)
782 return body(_top[GetIndex(x, y)]);
785 else if constexpr (std::is_invocable_r_v<void,
decltype(body),
const ValueType &>)
787 body(_top[GetIndex(x, y)]);
793 static_assert(std::false_type::value,
"Loop body is not matching arguments.");
799 IndexType _height{0};
800 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:560
constexpr IndexType GetHeight() const noexcept
配列のY方向の最大値を取得
Definition mgl_array_2d.h:538
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:582
constexpr void ForRange(IndexType beginX, IndexType beginY, IndexType endX, IndexType endY, LoopBody body) noexcept
範囲を指定して要素にアクセス
Definition mgl_array_2d.h:357
constexpr IndexType GetWidth() const noexcept
配列のX方向の最大値を取得
Definition mgl_array_2d.h:527
constexpr size_t GetArraySize() const noexcept
配列全体のサイズを取得
Definition mgl_array_2d.h:549
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:331
constexpr void ForRange(const std::pair< IndexType, IndexType > &begin, const std::pair< IndexType, IndexType > &end, LoopBody body) noexcept
範囲を指定して要素にアクセス
Definition mgl_array_2d.h:394
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:480
constexpr void ForRange(IndexType beginX, IndexType beginY, IndexType endX, IndexType endY, LoopBody body) const noexcept
範囲を指定して読み取り専用で要素にアクセス
Definition mgl_array_2d.h:414
const ValueType & operator[](const std::pair< IndexType, IndexType > &pair) const noexcept
添字演算子による要素の取得
Definition mgl_array_2d.h:265
constexpr void ForRange(const std::pair< IndexType, IndexType > &begin, const std::pair< IndexType, IndexType > &end, LoopBody body) const noexcept
範囲を指定して読み取り専用で要素にアクセス
Definition mgl_array_2d.h:451
constexpr void SetInvalidValue(ValueType &&value) noexcept
無効値の設定
Definition mgl_array_2d.h:513
constexpr ValueType * end() const noexcept
末尾の要素を取得
Definition mgl_array_2d.h:571
constexpr const ValueType * cend() const noexcept
末尾の要素をconstで取得
Definition mgl_array_2d.h:593
~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:499
constexpr void ForEach(LoopBody body) noexcept
全ての要素へのアクセス
Definition mgl_array_2d.h:309
constexpr bool Contains(const ValueType &element) const noexcept
指定した要素が範囲内に含まれているかを取得
Definition mgl_array_2d.h:467
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) const 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
bool New(size_t width, size_t height, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
配列の生成
Definition mgl_array_2d.h:157
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
constexpr ValueType * GetPtr(IndexType x, IndexType y) const noexcept
書き込み可能な要素へのポインタを取得
Definition mgl_array_2d.h:278
値の範囲を表現するクラス
Definition mgl_range.h:28
constexpr bool Contains(T value) const noexcept
指定された値が範囲内に含まれているかを取得
Definition mgl_range.h:154
constexpr T Next(T value) const noexcept
指定された値の次の値を取得
Definition mgl_range.h:115
constexpr T Begin() const noexcept
開始値を取得
Definition mgl_range.h:49
ValueType
値のタイプ
Definition mgl_achievement_defs.h:33
#define MGL_ASSERT(...)
アサート用マクロ
Definition mgl_system_debug_macro.h:88