MGL::Array2D#

注意

このクラスは現在試験的に実装されています。今後大きな変更が加えられる可能性がある点にご注意ください。

概要#

MGL::Array2Dはメモリ安全性を重視し、範囲外アクセスに寛容なゲーム開発向けの2次元動的配列クラスです。

MGL::Array2Dは範囲外のインデックスにアクセスしても未定義動作や例外の送出を行うことはありません。代わりに無効値を返すようになっています。無効値はデフォルトでは0またはデフォルト構築されたオブジェクトが用いられますが、任意に変更可能です。

また、インデックスに使用する型もいずれかの整数型に任意に変更可能です。この機能は限定的な範囲アクセス、インデックス付きの範囲アクセス等の機能と組み合わせることで、より柔軟なインデックスの扱いが可能となります。ゲーム開発においては平面空間上の情報を2次元配列にマッピングする機会が多く、座標をインデックスとして利用する場合などには特に有用です。

配列に使用するメモリリソースはMGL::Memoryから取得するため、必要に応じてカスタマイズされたアロケーターを利用することも可能です。また、MGL::UniquePtrと同様に所有権を持つオブジェクトのみが単独で管理し、解放処理も自動化されています。

同じ特性を備えた1次元配列版のMGL::Arrayも利用可能です。

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        ...
    };
}

テンプレート引数#

class ValueType

要素の型

class IndexType

要素にアクセスするための座標の型。省略時はsize_t

要件#

ValueTypeはデフォルト構築可能な型である必要があります。

IndexTypeは符号付きまたは符号なしのいずれかの整数型でなければなりません。

利用例#

配列の生成と要素へのアクセス
// int型の5x5の2次元配列を生成
MGL::Array2D<int> array(5, 5);

// 座標(3, 2)の要素をトレース表示。
// 特に指定がない場合、数値の配列は0で初期化される。
MGL_TRACE("array[3, 2] = %d", array.Get(3, 2));

// C++23以降を利用している場合、添字アクセスも利用可能。
MGL_TRACE("array[3, 2] = %d", array[3, 2]);

// 2つの値の他に、ペアを生成してアクセスに用いることも可能。
// この場合はC++17でも添字アクセス可能。
const auto pair = array.MakePair(2, 3);
MGL_TRACE("array[3, 2] = %d", array[pair]);

// 要素の内容を書き換えるにはGetPtr()でポインタを取得する必要がある。
// 添字アクセスは読み取り専用なため、array[3, 2] = 3; のような記述は不可。
if (auto *value = array.GetPtr(3, 2); value != nullptr)
{
    *value = 3;
}

// 再度座標(3, 2)の要素をトレース表示
MGL_TRACE("array[3, 2] = %d", array.Get(3, 2));
実行結果
array[3, 2] = 0
array[3, 2] = 0
array[3, 2] = 0
array[3, 2] = 3
詳細
要素への範囲アクセス
// int型の5x5の2次元配列を生成
MGL::Array2D<int> array(5, 5);

// 全ての要素を3で埋める
array.Fill(3);

// ForEach()を用いることで座標付と共に要素にアクセス可能
array.ForEach([](auto x, auto y, const auto &value)
{
    MGL_TRACE("array[%zu, %zu] = %d", x, y, value);
});

// ForRange()を用いることで一部の範囲の要素にアクセス可能。
// (1, 1)から(3, 3)の領域に45を書き込み
array.ForRange(1, 1, 3, 3, [](auto &value)
{
    value = 45
});

// 書き換え後の全ての要素をトレース表示。
// 一般的な範囲for文も利用可能であり、constを外せば書き換えも可能。
MGL_TRACE("-----------------");
for (const auto &value : array)
{
    MGL_TRACE("%d", value);
}
実行結果
array[0, 0] = 3
array[1, 0] = 3
array[2, 0] = 3
array[3, 0] = 3
array[4, 0] = 3
array[0, 1] = 3
array[1, 1] = 3
... (省略)
array[3, 4] = 3
array[4, 4] = 3
-----------------
3
... (省略)
3
45
45
45
3
... (省略)
3
3
3
詳細
無効値と範囲外アクセス
// 配列初期化時に「無効値」を指定可能。
// Get()や添字アクセスで範囲外を指定した場合はこの無効値が返る。
// 無効値を省略した場合、値であれば0が、クラスであればデフォルト構築されたオブジェクトが
// 無効値として設定される。
// ここでは5x5、無効値に-1のint型配列を生成。
MGL::Array2D<int> array(5, 5, -1);

// 範囲外アクセスの例。無効値の-1が返る。
MGL_TRACE("array[8, 2] = %d", array.Get(8, 2));

// 書き換え用にGetPtr()を使用する場合、範囲外を指定するとnullptrが返る。
// すなわち、特定の座標のみを書き換える場合はNULLチェックが必須。
if (auto *value = array.GetPtr(8, 2); value != nullptr)
{
    // ここには到達しない
}
実行結果
array[8, 2] = -1
詳細
インデックスに使用する型の変更
// テンプレート引数の第2引数には座標に使用する型も指定可能。
// ここでは、座標にもint型を用いる5x5のint型配列を生成。
MGL::Array2D<int, int> array(3, 3);

int x = 0;
int y = 1;

// (x, y)を中心に周囲の1マスを含めた3x3の範囲を取得する例。
// ForRange()は範囲外の座標をスキップするため、どちらかの要素が範囲外になっても
// &valueに範囲外の不正な参照が届くことはない。
array.ForRange(x - 1, y - 1, x + 1, y + 1, [](auto x, auto y, const auto &value)
{
    MGL_TRACE("array[%d, %d] = %d", x, y, value);  // この場合、indexはint型になる
});
実行結果
array[0, 0] = 0
array[1, 0] = 0
array[0, 1] = 0
array[1, 1] = 0
array[0, 2] = 0
array[1, 2] = 0
詳細

メンバ情報#

種類

名前

内容

バージョン

関数

コンストラクタ

1.1.15+

関数

New

配列の初期化

1.1.15+

関数

Renew

配列の再初期化

1.1.15+

関数

Fill

全ての要素に指定の値を書き込み

1.1.15+

関数

MakePair

要素アクセスのためのペアを生成

1.1.15+

関数

Get

要素の取得

1.1.15+

関数

GetPtr

要素をポインタで取得

1.1.15+

関数

ForEach

関数オブジェクトを用いた全ての要素へのアクセス

1.1.15+

関数

ForRange

関数オブジェクトを用いた指定範囲の要素へのアクセス

1.1.15+

関数

Contains

指定した要素が範囲内に含まれているかを取得

1.1.15+

関数

SetInvalidValue

無効値の設定

1.1.15+

関数

GetWidth

X方向のサイズを取得

1.1.15+

関数

GetHeight

Y方向のサイズを取得

1.1.15+

関数

begin

先頭の要素を指すポインタを取得

1.1.15+

関数

end

末尾の次の要素を指すポインタを取得

1.1.15+

オペレータ

operator=

演算子によるムーブ

1.1.15+

オペレータ

operator[]

添字による要素アクセス

1.1.15+


コンストラクタ#

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) 空の配列を生成
        Array2D(
            Memory::ClearMode clearMode = Memory::ClearMode::Auto) noexcept;

        // (2) サイズを指定して配列を初期化
        Array2D(
            IndexType width,
            IndexType height,
            Memory::ClearMode clearMode = Memory::ClearMode::Auto) noexcept;

        // (3) サイズと無効値を指定して配列を初期化
        Array2D(
            IndexType width,
            IndexType height,
            const ValueType &invalidValue,
            Memory::ClearMode clearMode = Memory::ClearMode::Auto) noexcept;

        // (4) サイズと右辺値参照による無効値を指定して配列を初期化
        Array2D(
            IndexType width,
            IndexType height,
            ValueType &&invalidValue,
            Memory::ClearMode clearMode = Memory::ClearMode::Auto) noexcept;

        // (5) ムーブコンストラクタ
        Array2D(Array2D &&rhs) noexcept;

        // (6) コピーコンストラクタの削除
        Array2D(Array2D &) = delete;
    };
}

引数#

(1) 空の配列を生成
MGL::Memory::ClearMode clearMode

配列が使用するメモリリソースのクリア方法。省略事はAuto

(2) サイズを指定して配列を初期化
IndexType width

2次元配列の幅

IndexType height

2次元配列の高さ

MGL::Memory::ClearMode clearMode

配列が使用するメモリリソースのクリア方法。省略事はAuto

(3) サイズと無効値を指定して配列を初期化
IndexType width

2次元配列の幅

IndexType height

2次元配列の高さ

const ValueType &invalidValue

生成する配列に設定する無効値

MGL::Memory::ClearMode clearMode

配列が使用するメモリリソースのクリア方法。省略事はAuto

(4) サイズと右辺値参照による無効値を指定して配列を初期化
IndexType width

2次元配列の幅

IndexType height

2次元配列の高さ

const ValueType &&invalidValue

生成する配列に設定する無効値

MGL::Memory::ClearMode clearMode

配列が使用するメモリリソースのクリア方法。省略事はAuto

(5) ムーブコンストラクタ
Array &&rhs

移動元の配列

説明#

配列を生成・初期化するためのコンストラクタです。

テンプレート引数ValueTypeには各要素の型を、IndexTypeには要素にアクセスする際に指定する座標の型を指定します。

ValueTypeはデフォルト構築可能な型である必要があり、各要素の初期値はデフォルト構築された値になります。

IndexTypeの指定を省略した場合はsize_t型になります。

(1)は空の配列を生成します。幅と高さは後からNewにて変更できます。

(2)は配列の幅と高さを指定して生成します。

(3) と (4) はサイズと同時に無効値を指定して初期化します。無効値は範囲外アクセスの際に代替される読み取り専用の要素です。 (4)は無効値を右辺値参照で渡した際に呼び出され、機能は(3)と同等です。

(1)から(4)までの引数clearModeは、メモリアロケータから配列用に確保したメモリリソースの初期化方法の指定になります。省略またはAutoを指定した場合、ValueTypeがクラスである場合はメモリリソースの初期化をスキップし、それ以外の場合はゼロクリアを行います。それ以外の値についてはMGL::Memory::ClearModeの説明を参照してください。

(5) は他の配列をムーブするためのコンストラクタです。これに伴い、コピーコンストラクタは(6)によって明示的に削除されています。

サイズの変更を伴う配列の初期化はコンストラクタを呼び出した後でもNewにて行えます。また、無効値の再設定はSetInvalidValueにて行えます。

注釈

2次元のデータレコードには「Row(行)」と「Column(列)」という単語が広く用いられていますが、MGLはゲーム開発に特化したライブラリであるため、よりゲームと親和性のある「Width(幅)」と「Height(高さ)」という単語を用いています。

利用例#

// 空のint型配列を生成
MGL::Array2D<int> emptyArray;

// 空の配列は常に無効値(int型の場合はデフォルトで0)を返す。
// サイズはNew()で後から変更可能。
MGL_TRACE("emptyArray[0, 0] = %d", emptyArray.Get(0, 0));

// サイズ5x5、無効値に-1のint型配列を生成
MGL::Array2D<int> array(5, 5, -1);

// (0, 0)から(4, 4)までの座標はデフォルト値である0が返るが、
// それ以外の座標では無効値に指定した-1が返るようになる。
MGL_TRACE("array[2, 3] = %d", array.Get(2, 3));
MGL_TRACE("array[0, 8] = %d", array.Get(0, 8));

// ムーブによって配列の移動が可能。
// この場合はarrayの内容がarray2に移動し、arrayは空となる。
MGL::Array2D<int> array2(std::move(array));

// コピーは不可
MGL::Array2D<int> array3(array2);  // コンパイルエラー!!
実行結果
emptyArray[0, 0] = 0
array[2, 3] = 0
array[0, 8] = -1

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


New#

配列の初期化

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        bool New(
            size_t width,
            size_t height,
            Memory::ClearMode clearMode = Memory::ClearMode::Auto) noexcept;
    };
}

引数#

size_t width

2次元配列の幅

size_t height

2次元配列の高さ

MGL::Memory::ClearMode clearMode

配列が使用するメモリリソースのクリア方法。省略事はAuto

戻り値#

bool

成功時にtrue、失敗時にfalse

説明#

指定したサイズで配列を初期化します。この関数は主にコンストラクタの呼び出し時点でサイズが確定していない場合の使用を想定しています。

既に配列が生成済みだった場合、既存の内容は破棄され新たな配列が生成されます。

引数clearModeは、メモリアロケータから配列用に確保したメモリリソースの初期化方法の指定になります。省略またはAutoを指定した場合、ValueTypeがクラスである場合はメモリリソースの初期化をスキップし、それ以外の場合はゼロクリアを行います。それ以外の値についてはMGL::Memory::ClearModeの説明を参照してください。

配列のサイズ分のメモリリソースを確保できなかった場合、初期化に失敗し戻り値にfalseが返ります。

利用例#

// 一旦空の配列を生成
MGL::Array2D<int> array;

// 配列をサイズ5x5で初期化
array.New(5, 5);

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Renew#

配列の再初期化

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        bool Renew(Memory::ClearMode clearMode = Memory::ClearMode::Auto) noexcept;
    };
}

引数#

MGL::Memory::ClearMode clearMode

配列が使用するメモリリソースのクリア方法。省略事はAuto

戻り値#

bool

成功時にtrue、失敗時にfalse

説明#

現在のサイズで配列を再初期化します。すなわち、全体サイズを変更せずに全ての要素をデフォルト構築し直します。

引数clearModeは、メモリアロケータから配列用に確保したメモリリソースの初期化方法の指定になります。省略またはAutoを指定した場合、ValueTypeがクラスである場合はメモリリソースの初期化をスキップし、それ以外の場合はゼロクリアを行います。それ以外の値についてはMGL::Memory::ClearModeの説明を参照してください。

この関数の呼び出しはNewの引数にGetWidthおよびGetHeightの戻り値を指定した場合と等価です。

利用例#

// サイズ5x5のint型配列を生成
MGL::Array2D<int> array(5, 5);

// 全ての要素を3で埋める
array.Fill(3);

// (0, 0)の内容を表示
MGL_TRACE("(1) array[0, 0] = %d", array.Get(0, 0));

// 配列を再初期化
// 全ての要素はデフォルト(int型の場合は0)に戻る
array.Renew();

// もう一度0番目の内容を表示
MGL_TRACE("(2) array[0, 0] = %d", array.Get(0, 0));
実行結果
(1) array[0, 0] = 3
(2) array[0, 0] = 0

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Fill#

全ての要素に指定の値を書き込み

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        constexpr void Fill(const ValueType &value) noexcept;
    };
}

引数#

ValueType value

書き込む値

説明#

配列内の全ての要素に引数でした値を書き込みます。

valueはコピー可能なオブジェクトである必要があります。

利用例#

// サイズ5x5のint型配列を生成
MGL::Array2D<int> array(5, 5);

// 全ての要素に 39 を書き込む
array.Fill(39);

// 全ての要素をトレース表示
for (const auto &value : array)
{
    MGL_TRACE("%d", value);
}
実行結果
39
39
39
...

バージョン情報#

MGL 1.1.15
  • 初回リリース


MakePair#

要素アクセスのためのペアを生成

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        [[nodiscard]] static constexpr std::pair<IndexType, IndexType> MakePair(
            IndexType x,
            IndexType y) noexcept;
    };
}

引数#

IndexType x

X座標

IndexType y

Y座標

戻り値#

std::pair<IndexType, IndexType>

XとYのペア

説明#

配列の要素にアクセスするためのペアを生成します。

ペアはXとYの2つの要素を持った1つのオブジェクトであり、座標をパラメータとして受け取る各々の関数に座標の代わりに指定可能です。また、C++23以降でなければ利用できないoperator[]も、ペアによる指定であればC++17から利用可能となります。

利用例#

// サイズ5x5のint型配列を生成
MGL::Array2D<int> array(5, 5);

// (3, 2)の座標を表すペアを生成
const auto pair = array.MakePair(3, 2);

// ペアを用いて要素にアクセスし、その内容を表示
MGL_TRACE("%d", array[pair]);
実行結果
0

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Get#

要素の取得

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) XとYで取得
        [[nodiscard]] constexpr const ValueType &Get(
            IndexType x,
            IndexType y) const noexcept;

        // (2) ペアで取得
        [[nodiscard]] const ValueType &Get(
            const std::pair<IndexType, IndexType> &pair) const noexcept;
    };
}

引数#

(1) XとYで取得
IndexType x

X座標

IndexType y

Y座標

(2) ペアで取得
const std::pair<IndexType, IndexType> &pair

XとYのペア

戻り値#

const ValueType &

引数に対応した座標の要素。範囲外の場合は無効値。

説明#

要素を読み取り専用で取得します。引数にX座標とY座標、またはそのペアを指定することで、その値に対応した要素の参照を返します。

この戻り値は読み取り専用であり、取得した要素を書き換えることはできません。値を書き換える必要がある場合はGetPtrForEachForRange、範囲for文のいずれかを使用してください。

範囲外の座標を渡した場合、コンストラクタまたはSetInvalidValueで設定した無効値を返します。無効値を明示的に設定していない場合、そのデフォルト値は初期化時に指定したMGL::Memory::ClearModeによって変化します。

戻り値が範囲内の要素であるかを調べる場合はContainsを使用してください。

この関数はoperator[]で代替できます。ただし、XとYの2つのパラメータを受ける添字アクセスはC++23以降でないと利用できません。

利用例#

// サイズ5x5のint型配列を生成
MGL::Array2D<int> array(5, 5, -1);

// 配列の全ての要素を32で埋める
array.Fill(32);

// (3, 2)の内容を表示
MGL_TRACE("array[3, 2] = %d", array.Get(3, 2));

// (6, 7)の内容を表示(範囲外)
MGL_TRACE("array[6, 7] = %d", array.Get(6, 7));
実行結果
array[3, 2] = 32
array[6, 7] = -1

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


GetPtr#

要素をポインタで取得

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) XとYで取得
        [[nodiscard]] constexpr ValueType *GetPtr(
            IndexType x,
            IndexType y) const noexcept;

        // (2) ペアで取得
        [[nodiscard]] constexpr ValueType *GetPtr(
            const std::pair<IndexType, IndexType> &pair) const noexcept;
    };
}

引数#

(1) XとYで取得
IndexType x

X座標

IndexType y

Y座標

(2) ペアで取得
const std::pair<IndexType, IndexType> &pair

XとYのペア

戻り値#

ValueType *

引数に対応した座標の要素へのポインタ。範囲外の場合はnullptr

説明#

要素の書き込み可能なポインタを取得します。引数にX座標とY座標、またはそのペアを指定することで、その値に対応した要素のポインタを返します。

引数に範囲外のインデックスを渡した場合はnullptrが返ります。安全のため、この関数の戻り値は必ずNULLチェックを行ってください。

この関数は特定の要素の内容を書き換える場合にのみ使用してください。書き換える必要がない場合はGetを、複数の要素を対象とする場合はForEachForRange、範囲for文などを用いたほうが安全です。

注意

この関数で取得した戻り値に対し、++--、添字アクセス等を行わないでください。本クラスは範囲外アクセス等の未定義動作を防ぐ目的でも用意されているため、戻り値を通常の配列のように扱う事は想定されていません。また、将来に渡って常に要素が連続配置される保証もありません。

利用例#

// サイズ10のint型の配列を生成
MGL::Array<int> array(10);

// インデックス3の要素を取得し、成功したらその内容を76に書き換える。
if (auto *value = array.GetPtr(3); value != nullptr)
{
    *value = 76;
}

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


ForEach#

関数オブジェクトを用いた全ての要素へのアクセス

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) 非const版
        template <class LoopBody>
        constexpr void ForEach(LoopBody body) noexcept;

        // (2) const版
        template <class LoopBody>
        constexpr void ForEach(LoopBody body) const noexcept;
    };
}

引数#

LoopBody body

各々の要素にアクセスするための関数。詳細は説明を参照。

説明#

配列が保持する全ての要素に対し、関数オブジェクトを用いてアクセスを行うための関数です。指定した関数は要素ごとに、X座標を優先して昇順に呼び出されます。

引数の関数オブジェクトに指定可能なフォーマットは次の通りです。

  1. 引数で要素の参照のみを受ける
    // サイズ3x3のint型の配列を生成
    MGL::Array2D<int> array(3, 3);
    
    // array内の全ての要素に32を書き込み
    array.ForEach([](auto &value)
    {
        value = 32;
    });
    
    // array内の全ての要素をトレース表示
    array.ForEach([](const auto &value) // constを付けることで読み取り専用になる
    {
        MGL_TRACE("%d", value);
    });
    
    実行結果
    32
    32
    32
    32
    32
    ...
    
    補足

    この例のように参照のみを取得するForEach()の使用はあまり意味がなく、通常は次のような使用方法が推奨される。

    // サイズ3x3のint型の配列を生成
    MGL::Array2D<int> array(3, 3);
    
    // array内の全ての要素に32を書き込み (Fill()を使用)
    array.Fill(32);
    
    // array内の全ての要素をトレース表示 (範囲for文を使用)
    for (const auto &value : array)
    {
        MGL_TRACE("%d", value);
    }
    
  2. 引数に要素の参照とインデックスを受ける
    // サイズ3x3のint型の配列を生成
    MGL::Array2D<int> array(3, 3);
    
    // array内の全ての要素にX * 10 + yの値を書き込む
    array.ForEach([](size_t x, size_t y, auto &value)
    {
        value = static_cast<int>(x * 10 + y);
    });
    
    // array内の全ての要素をインデックス付きでトレース表示
    array.ForEach([](size_t x, size_t y, const auto &value)
    {
        MGL_TRACE("array[%zu, %zu] = %d", x, y, value);
    });
    
    実行結果
    array[0, 0] = 0
    array[1, 0] = 10
    array[2, 0] = 20
    array[0, 1] = 1
    array[1, 1] = 11
    array[2, 1] = 21
    array[0, 2] = 2
    array[1, 2] = 12
    array[2, 2] = 22
    
  3. 戻り値について

    関数オブジェクトの戻り値をboolにしてfalseを返すことで、ループの中断が可能です。

    // サイズ3x3のint型の配列を生成
    MGL::Array2D<int> array(3, 3);
    
    // (1, 2)に-1を書き込む
    if (auto *value = array.GetPtr(1, 2); value != nullptr)
    {
        *value = -1;
    }
    
    // 先頭から負の値が見つかるまでをトレース表示
    array.ForEach([](size_t x, size_t y, const auto &value)
    {
        if (value < 0)
        {
            return false;
        }
    
        MGL_TRACE("array[%zu, %zu] = %d", x, y, value);
    
        return true;
    });
    
    実行結果
    array[0, 0] = 0
    array[1, 0] = 0
    array[2, 0] = 0
    array[0, 1] = 0
    array[1, 1] = 0
    array[2, 1] = 0
    array[0, 2] = 0
    

    関数オブジェクトがvoid型(値を返さない)場合は常に継続となります。

利用例#

説明を参照してください。

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


ForRange#

関数オブジェクトを用いた指定範囲の要素へのアクセス

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) XとYで範囲を指定
        template <class LoopBody>
        constexpr void ForRange(
            IndexType beginX,
            IndexType beginY,
            IndexType endX,
            IndexType endY,
            LoopBody body) noexcept;

        // (2) ペアで範囲を指定
        template <class LoopBody>
        constexpr void ForRange(
            const std::pair<IndexType, IndexType> &begin,
            const std::pair<IndexType, IndexType> &end,
            LoopBody body) noexcept;

        // (3) XとYで範囲を指定(const版)
        template <class LoopBody>
        constexpr void ForRange(
            IndexType beginX,
            IndexType beginY,
            IndexType endX,
            IndexType endY,
            LoopBody body) const noexcept;

        // (4) ペアで範囲を指定(const版)
        template <class LoopBody>
        constexpr void ForRange(
            const std::pair<IndexType, IndexType> &begin,
            const std::pair<IndexType, IndexType> &end,
            LoopBody body) const noexcept;
    };
}

引数#

(1)と(3) XとYで範囲を指定
IndexType beginX

開始X座標

IndexType beginY

開始Y座標

IndexType endX

終了X座標

IndexType endY

終了Y座標

LoopBody body

各々の要素にアクセスするための関数。詳細は説明を参照。

(2)と(4) ペアで範囲を指定
const std::pair<IndexType, IndexType> &begin

開始座標のペア

const std::pair<IndexType, IndexType> &end

終了座標のペア

LoopBody body

各々の要素にアクセスするための関数。詳細は説明を参照。

説明#

2次元配列上の指定の領域に対し、関数オブジェクトを用いてアクセスを行うための関数です。

引数で指定した開始座標から終了座標までの要素を取得し、bodyに指定した関数オブジェクトに渡して呼び出します。座標が範囲外になる場合はbodyの関数の呼び出しを行いません。

bodyに指定可能な関数オブジェクトのフォーマットについてはForEachと同等ですので、詳細は該当関数の説明を参照してください。

呼び出しはbeginからendに向かうように、X座標を優先的に更新しながら順に行われます。endにはbeginよりも小さい座標を指定することも可能で、その場合は小さくなる要素をデクリメントしながらbodyが呼び出されます。

利用例#

// サイズ5x5のint型の配列を生成
MGL::Array2D<int> array(5, 5);

// (1, 1)から(3, 3)の領域に76を書き込み
array.ForRange(1, 1, 3, 3, [](auto &value)
{
    value = 76;
});

// array内の全ての要素をインデックス付きでトレース表示
array.ForEach([](size_t x, size_t y, const auto &value)
{
    MGL_TRACE("array[%zu, %zu] = %d", x, y, value);
});

// (4, 6)から (2, 3)までの
// 範囲外のインデックスは無視されるため、(4, 6)や(4, 5)などは呼び出されない。
MGL_TRACE("---------------");
array.ForRange(4, 6, 2, 3, [](size_t x, size_t y, const auto &value)
{
    MGL_TRACE("array[%zu, %zu] = %d", x, y, value);
});
実行結果
array[0, 0] = 0
array[1, 0] = 0
array[2, 0] = 0
array[3, 0] = 0
array[4, 0] = 0
array[0, 1] = 0
array[1, 1] = 76
array[2, 1] = 76
array[3, 1] = 76
array[4, 1] = 0
array[0, 2] = 0
array[1, 2] = 76
array[2, 2] = 76
array[3, 2] = 76
array[4, 2] = 0
array[0, 3] = 0
array[1, 3] = 76
array[2, 3] = 76
array[3, 3] = 76
array[4, 3] = 0
array[0, 4] = 0
array[1, 4] = 0
array[2, 4] = 0
array[3, 4] = 0
array[4, 4] = 0
---------------
array[4, 4] = 0
array[3, 4] = 0
array[2, 4] = 0
array[4, 3] = 0
array[3, 3] = 76
array[2, 3] = 76

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Contains#

指定した要素が範囲内に含まれているかを取得

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) 参照で指定
        [[nodiscard]] constexpr bool Contains(const ValueType &element) const noexcept;

        // (2) ポインタで指定
        [[nodiscard]] constexpr bool Contains(const ValueType *element) const noexcept;
    };
}

引数#

(1) 参照でチェック
const ValueType &element

チェックする要素の参照

(2) ポインタでチェック
const ValueType *element

チェックする要素へのポインタ

戻り値#

bool

範囲内に含まれている場合はtrue、含まれていない場合はfalse

説明#

指定した要素が配列の範囲内に存在しているかをチェックします。

引数elementにはValueTypeの型の参照またはポインタを指定します。もしその要素が配列ないに存在している場合は戻り値にtrueを返します。

利用例#

// サイズ3x3のint型の配列を生成
MGL::Array2D<int> array(3, 3);

// (1, 2)の要素を取得してチェック
// 範囲内の有効な値が返るため、この結果はtrueになる。
const auto &value1 = array.Get(1, 2);
if (array.Contains(value1))
{
    MGL_TRACE("value1 は array内の要素。");
}
else
{
    MGL_TRACE("value1 は array内の要素ではない。");
}

// (4, 2)の要素を取得してチェック
// 範囲外となり無効値が返るため、この結果はfalseになる。
const auto &value2 = array.Get(4, 2);
if (array.Contains(value2))
{
    MGL_TRACE("value2 は array内の要素。");
}
else
{
    MGL_TRACE("value2 は array内の要素ではない。");
}

// int型のローカル変数を生成してチェック
// 配列とは無関係な値であるため、この結果はfalseになる。
int value3 = 32;
if (array.Contains(value3))
{
    MGL_TRACE("value3 は array内の要素。");
}
else
{
    MGL_TRACE("value3 は array内の要素ではない。");
}
実行結果
value1 は array内の要素。
value2 は array内の要素ではない。
value3 は array内の要素ではない。

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


SetInvalidValue#

無効値の設定

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) 通常
        constexpr void SetInvalidValue(const ValueType &value) noexcept;

        // (2) 右辺値参照
        constexpr void SetInvalidValue(ValueType &&value) noexcept;
    };
}

引数#

(1) 通常
const ValueType &value

無効値として設定する値

(2) 右辺値参照
ValueType &&value

無効値として設定する値

説明#

Getで範囲外のインデックスを指定した際に、無効値として返す値を設定します。

引数を右辺値参照で指定した場合、無効値はコピーではなくムーブによって設定されます。コピーのコストが高い場合やコピー禁止のクラスを扱う場合などはstd::move()と併せてこちらを利用してください。

無効値はコンストラクタの引数で指定することも可能です。

利用例#

// サイズ3x3のint型の配列を生成
MGL::Array2D<int> array(3, 3);

// 無効値に-1を設定
array.SetInvalidValue(-1);

// (4, 2)の要素を取得して表示
// 範囲外なので無効値として設定した-1が返る
MGL_TRACE("array[4, 2] = %d", array.Get(4, 2));
実行結果
array[4, 2] = -1;

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


GetWidth#

X方向のサイズを取得

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        [[nodiscard]] constexpr IndexType GetWidth() const noexcept;
    };
}

戻り値#

IndexType

X方向のサイズ(幅)

説明#

X方向のサイズ、すなわち2次元配列の幅を取得します。

配列は0からこの値が返す値-1までが有効なX座標となります。

利用例#

// サイズ3x6のint型の配列を生成
MGL::Array2D<int> array(3, 6);

// 配列の幅を取得
MGL_TRACE("array width = %zu", array.GetWidth());
実行結果
array width = 3

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


GetHeight#

Y方向のサイズを取得

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        [[nodiscard]] constexpr IndexType GetHeight() const noexcept;
    };
}

戻り値#

IndexType

Y方向のサイズ(高さ)

説明#

X方向のサイズ、すなわち2次元配列の高さを取得します。

配列は0からこの値が返す値-1までが有効なY座標となります。

利用例#

// サイズ3x6のint型の配列を生成
MGL::Array2D<int> array(3, 6);

// 配列の高さを取得
MGL_TRACE("array height = %zu", array.GetHeight());
実行結果
array height = 6

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


begin#

先頭の要素を指すポインタを取得

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        [[nodiscard]] constexpr ValueType *begin() const noexcept;
    };
}

戻り値#

配列の先頭の要素を指すポインタ

説明#

配列の先頭の要素を指すポインタを取得します。この関数は通常endと組み合わせて使用されます。

注意

この関数は範囲for文および一部の標準ライブラリの関数を利用する目的で実装されています。この関数をイテレータを取る標準ライブラリの引数以外に使用しないでください。

利用例#

// サイズ5x5のint型の配列を生成
MGL::Array2D<int> array(5, 5);

// 範囲for文を用いて各要素に値を書き込み
// Note:
//  C++の範囲for文はbeginとendを用いたコードに置き換えられるため、
//  この関数が無ければ次のような範囲for文は使用できない。
//  なお、範囲for文は要素の座標が取れないため、ForEach()を用いたほうが実用的。
int i = 3;
for (auto &value : array)
{
    value = i++;
}

// 標準ライブラリの std::find() を用いて配列内に7が含まれているかをチェック
// Note:
//  このようなイテレータを取る関数に利用する限りは問題無いが、
//  それ以外の用途においては推奨されない。
auto result = std::find(array.begin(), array.end(), 7);
if (result != array.end())
{
    MGL_TRACE("7を発見!");
}

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


end#

末尾の次の要素を指すポインタを取得

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        [[nodiscard]] constexpr ValueType *end() const noexcept;
    };
}

戻り値#

配列の末尾の次の要素を指すポインタ

説明#

配列の末尾の次の要素を指すポインタを取得します。この関数は通常beginと組み合わせて使用されます。

注意

この関数は範囲for文および一部の標準ライブラリの関数を利用する目的で実装されています。この関数をイテレータを取る標準ライブラリの引数以外に使用しないでください。

利用例#

beginの利用例を参照してください。

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


operator=#

演算子によるムーブ

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) 演算子によるムーブ
        Array2D &operator=(Array2D &&rhs) noexcept;

        // (2) コピーを禁止するための宣言
        Array2D &operator=(Array2D &) = delete;
    };
}

引数#

Array &&rhs

ムーブ元の配列

戻り値#

Array &

ムーブ後の配列

説明#

=演算子によるムーブ、およびコピーを禁止するための宣言です。

=演算子の右辺が右辺値参照である場合、その内容を左辺値へとムーブします。右辺が右辺値参照ではない場合は禁止されているコピーとなるため、コンパイルエラーとなります。

利用例#

// サイズ3x3のint型の配列 array を生成
MGL::Array2D<int> array(3, 3);

// array を array2 へとムーブ
// これによりarrayの内容はarray2へと移り、arrayは空の配列となる。
auto array2 = std::move(array);

// コピーは禁止されているため、次のような記述は不可能。
auto array3 = array2;   // コンパイルエラー!!

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


operator[]#

添字による要素アクセス

宣言#

namespace MGL
{
    template <class ValueType, class IndexType = size_t>
    class Array2D
    {
        // (1) ペアで要素にアクセス
        [[nodiscard]] const ValueType &operator[](
            const std::pair<IndexType, IndexType> &pair) const noexcept;

        // (2) XとYで要素にアクセス(C++23以降)
        [[nodiscard]] const ValueType &operator[](
            IndexType x,
            IndexType y) const noexcept;
    };
}

引数#

(1) ペアで要素にアクセス
const std::pair<IndexType, IndexType> &pair

XとYのペア

(2) XとYで要素にアクセス(C++23以降)
IndexType x

X座標

IndexType y

Y座標

戻り値#

const ValueType &

引数に対応した座標の要素。範囲外の場合は無効値。

説明#

要素を読み取り専用で取得します。引数にMakePairで生成したペアを指定することで、その値に対応した要素の参照を返します。

C++23以降を利用している場合、添字にX座標とY座標の2つの値を指定する方法も利用できます。

この戻り値は読み取り専用であり、取得した要素を書き換えることはできません。値を書き換える必要がある場合はGetPtrForEachForRange、範囲for文のいずれかを使用してください。

範囲外の座標を渡した場合、コンストラクタまたはSetInvalidValueで設定した無効値を返します。無効値を明示的に設定していない場合、そのデフォルト値は初期化時に指定したMGL::Memory::ClearModeによって変化します。

戻り値が範囲内の要素であるかを調べる場合はContainsを使用してください。

この関数はX座標とY座標の指定がC++23以降である事を除き、Getと等価です。

利用例#

// サイズ5x5のint型配列を生成
MGL::Array2D<int> array(5, 5, -1);

// 配列の全ての要素を32で埋める
array.Fill(32);

// (3, 2)の内容を表示
//  この方法はC++23以降でないと利用不可
MGL_TRACE("array[3, 2] = %d", array[3, 2]);

// (6, 7)の内容を表示(範囲外)
//  ペアを生成して指定すればC++17でも利用可能
const auto pair = array.MakePair(6, 7);
MGL_TRACE("array[6, 7] = %d", array[pair]);
実行結果
array[3, 2] = 32
array[6, 7] = -1

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#