MGL::Range
Contents
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+ |
||
関数 |
開始値を取得 |
1.1.15+ |
|
関数 |
終了値を取得 |
1.1.15+ |
|
関数 |
範囲が正の方向であるかを取得 |
1.1.15+ |
|
関数 |
範囲が負の方向であるかを取得 |
1.1.15+ |
|
関数 |
範囲を持たない単一の値であるかを取得 |
1.1.15+ |
|
関数 |
指定した値の次の値を取得 |
1.1.15+ |
|
関数 |
指定した値の前の値を取得 |
1.1.15+ |
|
関数 |
指定した値が範囲内に含まれているかを取得 |
1.1.15+ |
|
関数 |
指定した値を範囲内にクランプ |
1.1.15+ |
|
関数 |
指定した値を0から1の間の値に正規化 |
1.1.15+ |
|
関数 |
指定した0から1の間の値をスケーリング |
1.1.15+ |
コンストラクタ#
宣言#
namespace MGL
{
template <class T>
class Range
{
constexpr Range(T begin, T end) noexcept;
};
}
引数#
- T beign
開始値
- T end
終了値
説明#
このクラスを初期化するためのコンストラクタです。
テンプレート引数T
には、範囲としてしたい値の型を指定します。begin
とend
にはそれぞれ、範囲の開始値と終了値を指定します。
end
がbegin
よりも大きい場合は「正の方向」、小さい場合は「負の方向」を持つ範囲として扱われます。また、begin
とend
が同一である場合は範囲ではない「単一の値」として扱われます。それぞれはIsPositive、IsNegative、IsSingleValueにてチェック可能です。
「単一の値」は厳密には範囲ではありませんが、範囲を動的に算出し、開始値・終了値が同一になった場合でも適切な値を返すために用意されています。なお、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
初回リリース