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