MGL::Range#

概要#

MGL::Rangeは値の範囲を扱うための汎用的なユーティリティクラスです。

このクラスは開始値、終了値の2つの値で範囲を表現し、主に次のような用途に利用可能です。

  • 値が範囲内に収まっているかをチェックや、範囲内に収まるよう補正(クランプ)

  • 範囲内の値を順に(または逆順に)走査

  • 0から1の間で正規化およびスケーリング

宣言#

namespace MGL
{
    template <class T>
    class Range;
}

テンプレート引数#

T

扱う範囲の型

利用例#

クランプ処理の例
// int型の値を8ビット(0から255の間)にクランプ
int ClampIn8Bit(int value)
{
    MGL::Range<int> range(0, 255);

    return range.Clamp(value);
}
範囲内の値を順に走査する例
// 5から15までのインデックスを順に扱うループ処理
// range(15, 5)のように入れ替えることで逆順も可能
MGL::Range<size_t> range(5, 15);
for (
    auto index = range.Begin();
    range.Contains(index);
    index = range.Next(index)
)
{
    MGL_TRACE("%zu", index);
}
スケーリングを用いてAからBまでの間の中心を取得する例
// a と b の中心にある値を取得
int GetCenter(int a, int b)
{
    MGL::Range<int> range(a, b);

    return range.Scale(0.5f);
}

メンバ情報#

種類

名前

内容

バージョン

関数

コンストラクタ

1.1.15+

関数

Begin

開始値を取得

1.1.15+

関数

End

終了値を取得

1.1.15+

関数

IsPositive

範囲が正の方向であるかを取得

1.1.15+

関数

IsNegative

範囲が負の方向であるかを取得

1.1.15+

関数

IsSingleValue

範囲を持たない単一の値であるかを取得

1.1.15+

関数

Next

指定した値の次の値を取得

1.1.15+

関数

Previous

指定した値の前の値を取得

1.1.15+

関数

Contains

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

1.1.15+

関数

Clamp

指定した値を範囲内にクランプ

1.1.15+

関数

Normalize

指定した値を0から1の間の値に正規化

1.1.15+

関数

Scale

指定した0から1の間の値をスケーリング

1.1.15+


コンストラクタ#

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        constexpr Range(T begin, T end) noexcept;
    };
}

引数#

T beign

開始値

T end

終了値

説明#

このクラスを初期化するためのコンストラクタです。

テンプレート引数Tには、範囲としてしたい値の型を指定します。beginendにはそれぞれ、範囲の開始値と終了値を指定します。

endbeginよりも大きい場合は「正の方向」、小さい場合は「負の方向」を持つ範囲として扱われます。また、beginendが同一である場合は範囲ではない「単一の値」として扱われます。それぞれはIsPositiveIsNegativeIsSingleValueにてチェック可能です。

「単一の値」は厳密には範囲ではありませんが、範囲を動的に算出し、開始値・終了値が同一になった場合でも適切な値を返すために用意されています。なお、Tが浮動小数点数型である場合、std::numeric_limits<T>::epsilon()を誤差の許容範囲としたうえで単一の値として判定されます。

利用例#

// 2から5までのint型の範囲を生成。
// この範囲は正の方向を持つ。
MGL::Range<int> range1(2, 5);

// 7.0から-4.5までのfloat型の範囲を生成。
// この範囲は負の方向を持つ。
MGL::Range<float> range2(7.0f, -4.5f);

// int型の5を持つ単一の値を範囲として生成。
// これは範囲ではないが、動的に算出した結果に適切に対応するために用意されている。
MGL::Range<int> range3(5, 5);

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Begin#

開始値を取得

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr T Begin() const noexcept;
    };
}

戻り値#

T

開始値

説明#

コンストラクタにて指定した開始値を取得します。

利用例#

// 2から5までのint型の範囲を生成
MGL::Range<int> range(2, 5);

// 範囲の開始値をトレース表示
MGL_TRACE("begin = %d", range.Begin());
実行結果
begin = 2

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


End#

終了値を取得

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr T End() const noexcept;
    };
}

戻り値#

T

終了値

説明#

コンストラクタにて指定した終了値を取得します。

利用例#

// 2から5までのint型の範囲を生成
MGL::Range<int> range(2, 5);

// 範囲の終了値をトレース表示
MGL_TRACE("end = %d", range.End());
実行結果
end = 5

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


IsPositive#

範囲が正の方向であるかを取得

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr bool IsPositive() const noexcept;
    };
}

戻り値#

bool

範囲が正の方向を持つ場合はtrue、そうでなければfalse

説明#

範囲が正の方向を持つかを取得します。

この関数がtrueを返す場合、終了値が開始値よりも大きな値を持っている事を意味しています。

利用例#

// 2から5までのint型の範囲 range1 を生成
MGL::Range<int> range1(2, 5);

// range1が正の方向であるかをチェック
MGL_TRACE("range1は正の方向で%s", range1.IsPositive() ? "ある" : "ない");

// 8から-3までのint型の範囲 range2 を生成
MGL::Range<int> range2(8, -3);

// range2が正の方向であるかをチェック
MGL_TRACE("range2は正の方向で%s", range2.IsPositive() ? "ある" : "ない");
実行結果
range1は正の方向である
range2は正の方向でない

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


IsNegative#

範囲が負の方向であるかを取得

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr bool IsNegative() const noexcept;
    };
}

戻り値#

bool

範囲が負の方向を持つ場合はtrue、そうでなければfalse

説明#

範囲が負の方向を持つかを取得します。

この関数がtrueを返す場合、終了値が開始値よりも小さな値を持っている事を意味しています。

利用例#

// 2から5までのint型の範囲 range1 を生成
MGL::Range<int> range1(2, 5);

// range1が負の方向であるかをチェック
MGL_TRACE("range1は負の方向で%s", range1.IsNegative() ? "ある" : "ない");

// 8から-3までのint型の範囲 range2 を生成
MGL::Range<int> range2(8, -3);

// range2が負の方向であるかをチェック
MGL_TRACE("range2は負の方向で%s", range2.IsNegative() ? "ある" : "ない");
実行結果
range1は負の方向でない
range2は負の方向である

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


IsSingleValue#

範囲を持たない単一の値であるかを取得

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr bool IsSingleValue() const noexcept;
    };
}

戻り値#

bool

開始値と終了値が同一であればtrue ,そうでなければfalse

説明#

開始値と終了値が同一であるかを取得します。

この関数がtrueを返す場合、開始値と終了値が同一である単一の値である事を意味しています。

Tが浮動小数点数型である場合、std::numeric_limits<T>::epsilon()を誤差の許容範囲としたうえで単一の値として判定されます。

利用例#

// 2から5までのint型の範囲 range1 を生成
MGL::Range<int> range1(2, 5);

// range1が単一の値であるかをチェック
MGL_TRACE("range1は単一の値で%s", range1.IsSingleValue() ? "ある" : "ない");

// 開始値も終了値も5である範囲 range2 を生成
MGL::Range<int> range2(5, 5);

// range2が単一の値であるかをチェック
MGL_TRACE("range2は単一の値で%s", range2.IsSingleValue() ? "ある" : "ない");
実行結果
range1は単一の値でない
range2は単一の値である

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Next#

指定した値の次の値を取得

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr T Next(T value) const noexcept;
    };
}

引数#

T value

元になる値

戻り値#

T

引数に指定した値の次の値

説明#

指定した値から、その範囲における次の値を取得します。

次の値とは、範囲が正の方向を持つ場合はvalueをインクリメントした値、負の方向を持つ場合はデクリメントした値です。インクリメント・デクリメントは++valueまたは--valueで行われ、この動作はTに指定した型に依存します。

取得結果が範囲外の値になる場合もあります。値が範囲内のものであるかを調べるにはContainsを利用してください。

範囲が単一の値である場合はインクリメントが行われます。

利用例#

// 2から8までの範囲 range1 を生成
MGL::Range<int> range1(2, 8);

// range1を順にトレース表示
MGL_TRACE("-- range1 --");
for (
    auto value = range1.Begin();
    range1.Contains(value);
    value = range1.Next(value))
{
    MGL_TRACE("%d", value);
}

// 5から0までの範囲 range2 を生成
MGL::Range<int> range2(5, 0);

// range2を順にトレース表示
MGL_TRACE("-- range2 --");
for (
    auto value = range2.Begin();
    range2.Contains(value);
    value = range2.Next(value))
{
    MGL_TRACE("%d", value);
}
実行結果
-- range1 --
2
3
4
5
6
7
8
-- range2 --
5
4
3
2
1
0

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Previous#

指定した値の前の値を取得

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr T Previous(T value) const noexcept;
    };
}

引数#

T value

元になる値

戻り値#

T

引数に指定した値の前の値

説明#

指定した値から、その範囲における前の値を取得します。

前の値とは、範囲が正の方向を持つ場合はvalueをデクリメントした値、負の方向を持つ場合はインクリメントした値です。インクリメント・デクリメントは++valueまたは--valueで行われ、この動作はTに指定した型に依存します。

取得結果が範囲外の値になる場合もあります。値が範囲内のものであるかを調べるにはContainsを利用してください。

範囲が単一の値である場合はデクリメントが行われます。

利用例#

// 2から8までの範囲 range1 を生成
MGL::Range<int> range1(2, 8);

// range1を逆にトレース表示
MGL_TRACE("-- range1 --");
for (
    auto value = range1.End();
    range1.Contains(value);
    value = range1.Previous(value))
{
    MGL_TRACE("%d", value);
}

// 5から0までの範囲 range2 を生成
MGL::Range<int> range1(2, 8);

// range2を逆順にトレース表示
MGL_TRACE("-- range2 --");
for (
    auto value = range2.End();
    range2.Contains(value);
    value = range2.Previous(value))
{
    MGL_TRACE("%d", value);
}
実行結果
-- range1 --
8
7
6
5
4
3
2
-- range2 --
0
1
2
3
4
5

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Contains#

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

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr bool Contains(T value) const noexcept;
    };
}

引数#

T value

チェックする値

戻り値#

bool

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

説明#

指定した値が範囲内に含まれているかを取得します。

利用例#

// 3から8の範囲を生成
MGL::Range<int> range(3, 8);

// 範囲に6が含まれているかチェック
MGL_TRACE("6はrangeに含まれて%s", range.Contains(6) ? "いる" : "いない");

// 範囲に8が含まれているかチェック
MGL_TRACE("8はrangeに含まれて%s", range.Contains(8) ? "いる" : "いない");

// 範囲に1が含まれているかチェック
MGL_TRACE("1はrangeに含まれて%s", range.Contains(1) ? "いる" : "いない");
実行結果
6はrangeに含まれている
8はrangeに含まれている
1はrangeに含まれていない

バージョン情報#

MGL 1.1.15
  • 初回リリース


Clamp#

指定した値を範囲内にクランプ

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr T Clamp(T value) const noexcept;
    };
}

引数#

T value

クランプする値

戻り値#

T

クランプ結果

説明#

引数で指定された値を範囲内に収まるように補正した結果を返します。

指定された値が既に範囲内に収まっている場合は値をそのまま返します。値が範囲外である場合、BeginまたはEndのどちらかの値を返します。

範囲が単一の値である場合、値の内容によらず常にBeginの値を返します。

利用例#

// 2から6までの範囲を生成
MGL::Range<int> range(2, 6);

// 0をクランプ
MGL_TRACE("range.Clamp(0) = %d", range.Clamp(0));

// 5をクランプ
MGL_TRACE("range.Clamp(5) = %d", range.Clamp(5));

// 10をクランプ
MGL_TRACE("range.Clamp(10) = %d", range.Clamp(10));
実行結果
range.Clamp(0) = 2
range.Clamp(5) = 5
range.Clamp(10) = 6

バージョン情報#

MGL 1.1.15
  • 初回リリース


Normalize#

指定した値を0から1の間の値に正規化

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr float Normalize(T value) const noexcept;
    };
}

引数#

T value

正規化する値

戻り値#

float

引数を範囲で正規化した値。valueが範囲内に収まっている場合は0.0fから1.0fの値。

説明#

範囲を元に引数で受けた値を0から1の値に正規化します。

正規化された値は開始値を0、終了値を1とし、その中間を線形的に補間した値です。指定された値が範囲外である場合、戻り値は0から1の範囲を超えて返します。

この関数で正規化した値はScaleによって逆変換が可能です。ただし、数値の表現誤差により同一の値にならない場合もあります。

範囲が単一の値(IsSingleValue)の場合、この関数は常に1.0fを返します。

利用例#

// 0から255までの範囲を生成
MGL::Range<int> range(0, 255);

// 50を正規化した値を取得
MGL_TRACE("range.Normalize(50) = %f", range.Normalize(50));

// 128を正規化した値を取得
MGL_TRACE("range.Normalize(127) = %f", range.Normalize(128));

// 300を正規化した値を取得
MGL_TRACE("range.Normalize(300) = %f", range.Normalize(300));

// -3を正規化した値を取得
MGL_TRACE("range.Normalize(-3) = %f", range.Normalize(-3));
実行結果
range.Normalize(50) = 0.196078
range.Normalize(127) = 0.501961
range.Normalize(300) = 1.176471
range.Normalize(-3) = -0.011765

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Scale#

指定した0から1の間の値をスケーリング

宣言#

namespace MGL
{
    template <class T>
    class Range
    {
        [[nodiscard]] constexpr T Scale(float normalizedValue) const noexcept;
    };
}

引数#

float normalizedValue

正規化された値

戻り値#

T

範囲でスケーリングされた値

説明#

開始値を0、終了値を1として正規化された値normalizedValueを元に、範囲上の値を算出して取得します。0以下または1以上の値を指定することで、範囲外の値を取得することも可能です。

Normalizeで取得した値はこの関数を用いることで逆変換が可能です。ただし、数値の表現誤差により同一の値にならない場合もあります。

利用例#

// 100から300までの範囲を生成
MGL::Range<int> range(100, 300);

// 0.0fの値をスケーリング
MGL_TRACE("range.Scale(0.0f) = %d", range.Scale(0.0f));

// 1.0fの値をスケーリング
MGL_TRACE("range.Scale(1.0f) = %d", range.Scale(1.0f));

// 0.5fの値をスケーリング
MGL_TRACE("range.Scale(0.5f) = %d", range.Scale(0.5f));

// -0.75の値をスケーリング
MGL_TRACE("range.Scale(-0.75f) = %d", range.Scale(-0.75f));
実行結果
range.Scale(0.0f) = 100
range.Scale(1.0f) = 300
range.Scale(0.5f) = 200
range.Scale(-0.75f) = -50

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#