MGL::EnumBitFlags#

概要#

MGL::EnumBitFlagsはスコープを持つ列挙型でビットフラグを扱うためのテンプレートクラスです。enum class (またはenum struct ) で宣言した値を束ね、1つの値でフラグとして管理したい場合を想定して実装されています。

このクラスは列挙した値を直接ビットフラグとして扱う場合とは異なり、その列挙型でアクセス可能なビットフラグクラスを別途生成します。これにより、元となる列挙子の連続性と強い型付けによる安全性を損なわずにビットフラグを実現できます。

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags;
}

テンプレート引数#

class EnumType

スコープを持つ列挙型

typename FlagType = uint32_t

ビットフラグを保持するための基本型。uint8_tuint16_tuint32_tuint64_tのいずれか。(省略時はuint32_t

要件#

EnumTypeに指定する型はスコープを持つ列挙型でなければなりません。

FlagTypeに指定する型は符号なし整数の基本型であるか、演算子によって同等のビット演算が行える型である必要があります。

EnumType型の列挙子の最大値はFlagType型が扱えるビット長未満である必要があります。ビット長を超える列挙子を指定した場合の動作はFlagTypeに指定した型に依存します。

利用例#

宣言の例
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// 4方向の壁の有無を表すビットフラグ wall を宣言
DirectionFlags wall;

// 北側に壁を設定
wall.Set(Direction::North);

// |= 演算子で東側にも壁を設定 (効果はSet()と同じ)
wall |= Direction::East;

// 北側に壁があるかの判定
if (wall.Has(Direction::North))
{
    MGL_TRACE("北側に壁がある");
}

// いずれかの方向に壁があるかの判定
if (wall.HasAny())
{
    MGL_TRACE("いずれかの方向に壁がある");
}

メンバ情報#

種類

名前

内容

バージョン

関数

コンストラクタ

1.1.10+

関数

GetValue

フラグ全体の値を取得

1.1.10+

関数

Has

指定した値を保持しているかを取得

1.1.10+

関数

HasAny

いずれかの値を保持しているかを取得

1.1.10+

関数

Set

指定したビット位置に値をセット

1.1.10+

関数

Clear

指定したビット位置または全てのビットをクリア

1.1.10+

関数

Flip

指定したビット位置または全てのビットを反転

1.1.10+

関数

operator bool

bool型へのキャスト

1.1.10+

関数

operator !

否定演算子のオペレータ

1.1.10+

関数

operator |=

論理和の複合演算のオペレータ

1.1.10+

関数

operator &=

論理積の複合演算のオペレータ

1.1.10+

関数

operator ^=

排他的論理和の複合演算のオペレータ

1.1.10+

関数

operator |

論理和のオペレータ

1.1.10+

関数

operator &

論理積のオペレータ

1.1.10+

関数

operator ^

排他的論理和のオペレータ

1.1.10+

関数

operator ~

反転演算子のオペレータ

1.1.10+

関数

operator ==

等価演算子のオペレータ

1.1.10+

関数

operator !=

不等価演算子のオペレータ

1.1.10+


コンストラクタ#

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) 0で初期化
            constexpr EnumBitFlags() noexcept;

            // (2) 指定ビットのみをセットして初期化
            constexpr EnumBitFlags(EnumType value) noexcept;

            // (3) フラグ全体を値で初期化
            constexpr explicit EnumBitFlags(FlagType value) noexcept;
    };
}

引数#

(1) 0で初期化

引数なし

(2) 指定ビットのみをセットして初期化
EnumType value

セットするビット位置を表す値

(3) フラグ全体を値で初期化
FlagType value

フラグ全体に設定する値

説明#

ビットフラグを初期化するためのコンストラクタです。引数を省略した場合は全てのビットがクリアの状態で初期化されます。

(2)はEnumTypeに指定した列挙型のパラメータを指定し、そのビット位置のみをセットしたビットフラグで初期化します。

(3)はFlagTypeに指定した値で直接初期化を行います。このコンストラクタはexplicitであり、明示的な型指定が無い限りは代入演算子で暗黙的に呼び出されることはありません。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// (1) 0で初期化
DirectionFlags flags1;

// (2) 指定ビットのみをセットして初期化
DirectionFlags flags2(Direction::North);    // Northのみをセット

// (3) フラグ全体を値で初期化
DirectionFlags flags3(0x0F);    // 下位4ビットを全てセット
注意点
DirectionFlags flags;

// EnumType型を代入した場合は(2)が呼び出される
flags = Direction::North;

// FlagType型の暗黙的な代入はexplicit指定により不可
flags = 0x0F;   // エラー

// 明示的ならOK(ただし推奨はされない)
flags = DirectionFlags(0x0F);   // OK

バージョン情報#

MGL 1.1.10
  • 初回リリース


GetValue#

フラグ全体の値を取得

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            [[nodiscard]] constexpr const FlagType &GetValue() const noexcept;
    };
}

戻り値#

const FlagType &

FlagTypeに指定した型の値

説明#

このクラスが内部で保持している値をそのまま返します。

この関数はFlagTypeにクラスを指定した場合に備え、値ではなく変更不可能な参照を返すようにしています。この関数を用いて値の内容を変更することはできない点にご注意ください。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// フラグに北を設定
DirectionFlags flags(Direction::North);

// ビットフラグを保持している値を取得して表示
MGL_TRACE("(1) flag value = %d", flags.GetValue());

// フラグに南を追加
flags.Set(Direction::South);

// もう一度表示
MGL_TRACE("(2) flag value = %d", flags.GetValue());
実行結果
(1) flag value = 1
(2) flag value = 3

バージョン情報#

MGL 1.1.10
  • 初回リリース

MGL 1.1.13
  • 関数の戻り値に[[nodiscard]]属性を付与

関連#


Has#

指定した値を保持しているかを取得

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            [[nodiscard]] constexpr bool Has(EnumType value) const noexcept;
    };
}

引数#

EnumType value

EnumTypeに指定した列挙型の値

戻り値#

bool

引数valueに対応するフラグがセットされている場合はtrue、クリアされている場合はfalse

説明#

特定のフラグの有効状態を取得します。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// フラグに北を設定
DirectionFlags flags(Direction::North);

// 北を保持しているかをチェック
if (flags.Has(Direction::North))
{
    MGL_TRACE("Direction::North は有効");
}
else
{
    MGL_TRACE("Direction::North は無効");
}
実行結果
Direction::North は有効

バージョン情報#

MGL 1.1.10
  • 初回リリース

MGL 1.1.13
  • 関数の戻り値に[[nodiscard]]属性を付与

関連#


HasAny#

いずれかの値を保持しているかを取得

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            [[nodiscard]] constexpr bool HasAny() const noexcept;
    };
}

戻り値#

bool

いずれかのフラグがセットされている場合はtrue、全てのフラグがクリアされている場合はfalse

説明#

いずれかのフラグがセットされているかを取得します。全てのフラグがクリアされている場合、この関数はfalseを返します。

この関数はGetValue() != 0と等価です。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// 空のフラグを用意
DirectionFlags flags;

// フラグがいずれかの値を保持しているかをチェック
if (flags.HasAny())
{
    MGL_TRACE("(1) いずれかのフラグがセットされている");
}
else
{
    MGL_TRACE("(1) 全てのフラグがクリアされている");
}

// フラグに北を設定
flags.Set(Direction::North);

// もう一度チェック
if (flags.HasAny())
{
    MGL_TRACE("(2) いずれかのフラグがセットされている");
}
else
{
    MGL_TRACE("(2) 全てのフラグがクリアされている");
}
実行結果
(1) 全てのフラグがクリアされている
(2) いずれかのフラグがセットされている

バージョン情報#

MGL 1.1.10
  • 初回リリース

MGL 1.1.13
  • 関数の戻り値に[[nodiscard]]属性を付与

関連#


Set#

指定したビット位置に値をセット

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            constexpr EnumBitFlags &Set(EnumType value) noexcept;
    };
}

引数#

EnumType value

セットするビット位置を表す値

戻り値#

EnumBitFlags &

セットした後の自身の参照

説明#

EnumType型の値を指定し、その値が表す位置のフラグをセットします。

指定した値がFlagType型のビット長を超える場合の動作は未定義です。FlagType型が符号なし整数の基本型である場合はいずれのフラグもセットしませんが、各演算子を定義したクラスを指定した場合はそのクラスの動作に依存します。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// 空のフラグを用意
DirectionFlags flags;

// フラグに南を追加
flags.Set(Direction::South);
MGL_TRACE("(1) flag value = %d", flags.GetValue());

// フラグに東を追加
flags.Set(Direction::East);
MGL_TRACE("(2) flag value = %d", flags.GetValue());

// フラグに南が追加されているかをチェック
if (flags.Has(Direction.South))
{
    MGL_TRACE("フラグは南を保持している");
}
else
{
    MGL_TRACE("フラグは南を保持していない");
}
実行結果
(1) flag value = 1
(2) flag value = 3
フラグは南を保持している

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


Clear#

指定したビット位置または全てのビットをクリア

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) 指定したビット位置をクリア
            constexpr EnumBitFlags &Clear(EnumType value) noexcept;

            // (2) 全てのビットをクリア
            constexpr EnumBitFlags &Clear() noexcept;
    };
}

引数#

(1) 指定したビット位置をクリア
EnumType value

クリアするビット位置を表す値

(2) 全てのビットをクリア

引数なし

戻り値#

EnumBitFlags &

クリア後の自身の参照

説明#

指定した位置のビット、または全てのビットをクリアします。

引数にEnumTypeに指定した型の値を用いてビット位置を指定し、対応したビットフラグをクリアします。指定した値がFlagType型のビット長を超える場合の動作は未定義です。FlagType型が符号なし整数の基本型である場合はいずれのフラグもクリアしませんが、各演算子を定義したクラスを指定した場合はそのクラスの動作に依存します。

引数を省略した場合は全てのビットをクリアします。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// フラグに北と南を設定
DirectionFlags flags(Direction::North);
flags.Set(Direction::South);

// 北だけクリア
flags.Clear(Direction::North);

// フラグをチェック
if (flags.Has(Direction::North))
{
    MGL_TRACE("北はクリアされたのでここには到達しない");
}
if (flags.Has(Direction::South))
{
    MGL_TRACE("南はまだ残っているのでここには到達する");
}

// 全てのフラグをクリア
flags.Clear();

// 全てのフラグをチェック
if (flags.HasAny())
{
    MGL_TRACE("全てのフラグがクリアされたのでここには到達しない");
}

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


Flip#

指定したビット位置または全てのビットを反転

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) 指定したビット位置を反転
            constexpr EnumBitFlags &Flip(EnumType value) noexcept;

            // (2) 全てのビットを反転
            constexpr EnumBitFlags &Flip() noexcept;
    };
}

引数#

(1) 指定したビット位置を反転
EnumType type

反転するビット位置を表す値

(2) 全てのビットを反転

引数なし

戻り値#

EnumBitFlags &

反転後の自身の参照

説明#

指定した位置のビット、または全てのビットを反転させます。

引数にEnumTypeに指定した型の値を用いてビット位置を指定し、対応したビットフラグを反転させます。指定した値がFlagType型のビット長を超える場合の動作は未定義です。FlagType型が符号なし整数の基本型である場合はいずれのフラグも変更しませんが、各演算子を定義したクラスを指定した場合はそのクラスの動作に依存します。

引数を省略した場合は全てのビットを反転させます。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;

// フラグの状態を表示する関数
void PrintDirectionFlags(const char *label, DirectionFlags flags) noexcept
{
    MGL_TRACE(label);
    MGL_TRACE("  North: %d", flags.Has(Direction::North) ? 1 : 0);
    MGL_TRACE("  South: %d", flags.Has(Direction::South) ? 1 : 0);
    MGL_TRACE("  East:  %d", flags.Has(Direction::East)  ? 1 : 0);
    MGL_TRACE("  West:  %d", flags.Has(Direction::West)  ? 1 : 0);
    MGL_TRACE("");
}
利用例
// フラグに北と南を設定
DirectionFlags flags(Direction::North);
flags.Set(Direction::South);

PrintDirectionFlags("(1) 北と南を設定", flags);

// 北と東のフラグを反転
flags.Flip(Direction::North);
flags.Flip(Direction::East);

PrintDirectionFlags("(2) 北と東を反転", flags);

// 全てのフラグを反転
flags.Flip();

PrintDirectionFlags("(3) 全てを反転", flags);
実行結果
(1) 北と南を設定
  North: 1
  South: 1
  East:  0
  West:  0

(2) 北と東を反転
  North: 0
  South: 1
  East:  1
  West:  0

(3) 全てを反転
  North: 1
  South: 0
  East:  0
  West:  1

バージョン情報#

MGL 1.1.10
  • 初回リリース


operator bool#

bool型へのキャスト

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            constexpr explicit operator bool() const noexcept;
    };
}

戻り値#

bool

いずれかのフラグがセットされている場合はtrue、全てのフラグがクリアされている場合はfalse

説明#

bool型へ変換した際のオペレータです。いずれかのフラグがセットされている場合はtrueに変換されます。

このオペレータは!HasAny()と等価になります。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// フラグに北をセット
DirectionFlags flags(Direction::North);

// bool型としてチェック
if (flags)
{
    MGL_TRACE("フラグに北が設定されているためここに到達する");
}

// 全てのフラグをクリア
flags.Clear();

// 再度bool型としてチェック
if (flags)
{
    MGL_TRACE("全てのフラグがクリアされているためここには到達しない");
}

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


operator !#

否定演算子のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            constexpr bool operator!() const noexcept;
    };
}

戻り値#

bool

全てのフラグがクリアされている場合はtrue、いずれかのフラグがセットされている場合はfalse

説明#

このクラスに否定演算子を適用した場合のオペレータです。全てのフラグがクリアされている場合にtrueが返ります。

このオペレータはHasAny()と等価になります。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// フラグに北をセット
DirectionFlags flags(Direction::North);

// bool型としてチェック
if (!flags)
{
    MGL_TRACE("フラグに北が設定されているためここに到達しない");
}

// 全てのフラグをクリア
flags.Clear();

// 再度bool型としてチェック
if (!flags)
{
    MGL_TRACE("全てのフラグがクリアされているためここには到達する");
}

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


operator |=#

論理和の複合演算のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) EnumType型との論理和の複合演算
            constexpr EnumBitFlags &operator|=(EnumType rhs) noexcept;

            // (2) 自身の型との論理和の複合演算
            constexpr EnumBitFlags &operator|=(const EnumBitFlags &rhs) noexcept;
    };
}

引数#

(1) EnumType型との論理和の複合演算
EnumType rhs

EnumType型の右辺値

(2) 自身の型との論理和の複合演算
const EnumBitFlags &rhs

自身の型の右辺値

戻り値#

EnumBitFlags &

演算後の自身の参照

説明#

自身との論理和の複合演算を行うためのオペレータです。

(1) は右辺値にEnumType型の値を指定し、その値が表すビット位置のフラグをセットします。この動作はSetと等価です。

左辺値に自身と同じ型を指定した場合は(2)が呼び出されます。複数のフラグを同時にセットしたい場合はこちらが利用可能です。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;

// フラグの状態を表示する関数
void PrintDirectionFlags(const char *label, DirectionFlags flags) noexcept
{
    MGL_TRACE(label);
    MGL_TRACE("  North: %d", flags.Has(Direction::North) ? 1 : 0);
    MGL_TRACE("  South: %d", flags.Has(Direction::South) ? 1 : 0);
    MGL_TRACE("  East:  %d", flags.Has(Direction::East)  ? 1 : 0);
    MGL_TRACE("  West:  %d", flags.Has(Direction::West)  ? 1 : 0);
    MGL_TRACE("");
}
利用例
// 空のフラグ flags1 を用意
DirectionFlags flags1;

// flags1 に 東を設定
flags1 |= Direction::East;
PrintDirectionFlags("(1) flags1 に 東を設定", flags1);

// 北と南を設定した flags2 を用意
DirectionFlags flags2(Direction::North);
flags2 |= Direction::South;
PrintDirectionFlags("(2) flags2 を準備", flags2);

// flags1 に flags2 の内容を適用
flags1 |= flags2;
PrintDirectionFlags("(3) flags1 に flags2 を適用", flags1);
実行結果
(1) flags1 に 東を設定
  North: 0
  South: 0
  East:  1
  West:  0

(2) flags2 を準備
  North: 1
  South: 1
  East:  0
  West:  0

(3) flags1 に flags2 を適用
  North: 1
  South: 1
  East:  1
  West:  0

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


operator &=#

論理積の複合演算のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) EnumType型との論理積の複合演算
            constexpr EnumBitFlags &operator&=(EnumType rhs) noexcept;

            // (2) 自身の型との論理積の複合演算
            constexpr EnumBitFlags &operator&=(const EnumBitFlags &rhs) noexcept;
    };
}

引数#

(1) EnumType型との論理積の複合演算
EnumType rhs

EnumType型の右辺値

(2) 自身の型との論理積の複合演算
const EnumBitFlags &rhs

自身の型の右辺値

戻り値#

EnumBitFlags &

演算後の自身の参照

説明#

自身との論理積の複合演算を行うためのオペレータです。

(1) は右辺値にEnumType型の値を指定し、その値が表すビット位置のフラグ以外をクリアします。

左辺値に自身と同じ型を指定した場合は(2)が呼び出されます。特定のビット位置のみをマスクする場合などにはこちらが利用可能です。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;

// フラグの状態を表示する関数
void PrintDirectionFlags(const char *label, DirectionFlags flags) noexcept
{
    MGL_TRACE(label);
    MGL_TRACE("  North: %d", flags.Has(Direction::North) ? 1 : 0);
    MGL_TRACE("  South: %d", flags.Has(Direction::South) ? 1 : 0);
    MGL_TRACE("  East:  %d", flags.Has(Direction::East)  ? 1 : 0);
    MGL_TRACE("  West:  %d", flags.Has(Direction::West)  ? 1 : 0);
    MGL_TRACE("");
}
利用例
// 東北を表す定数を用意
constexpr auto kNorthEast = DirectionFlags(Direction::North) | Direction::East;

// 全てのビットを持つフラグを用意
DirectionFlags flags;
flags.Flip();
PrintDirectionFlags("(1) 全てを保持するフラグ", flags);

// フラグから東北のみをマスク
flags &= kNorthEast;
PrintDirectionFlags("(2) (1)から東北のみをマスク", flags);

// さらに東のみにマスク
flags &= Direction::East;
PrintDirectionFlags("(3) さらに東のみにマスク", flags);
実行結果
(1) 全てを保持するフラグ
  North: 1
  South: 1
  East:  1
  West:  1

(2) (1)から東北のみをマスク
  North: 1
  South: 0
  East:  1
  West:  0

(3) さらに東のみにマスク
  North: 0
  South: 0
  East:  1
  West:  0

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


operator ^=#

排他的論理和の複合演算のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) EnumType型との排他的論理和の複合演算
            constexpr EnumBitFlags &operator^=(EnumType rhs) noexcept;

            // (2) 自身の型との排他的論理和の複合演算
            constexpr EnumBitFlags &operator^=(const EnumBitFlags &rhs) noexcept;
    };
}

引数#

(1) EnumType型との排他的論理和の複合演算
EnumType rhs

EnumType型の右辺値

(2) 自身の型との排他的論理和の複合演算
const EnumBitFlags &rhs

自身の型の右辺値

戻り値#

EnumBitFlags &

演算後の自身の参照

説明#

自身との排他的論理和の複合演算を行うためのオペレータです。排他的論理和の主な用途は、特定のビット位置を反転させたり、2つのビットフラグの差分を得る場合などに用いられます。

(1) は右辺値にEnumType型の値を指定し、その値が表すビット位置のみがセットされたフラグとの排他的論理和を適用します。この場合の動作はFlipと等価となります。

左辺値に自身と同じ型を指定した場合は(2)が呼び出されます。一度に複数のフラグを反転させたり、2つのビットフラグの差分を検出する場合などにはこちらが使用できます。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;

// フラグの状態を表示する関数
void PrintDirectionFlags(const char *label, DirectionFlags flags) noexcept
{
    MGL_TRACE(label);
    MGL_TRACE("  North: %d", flags.Has(Direction::North) ? 1 : 0);
    MGL_TRACE("  South: %d", flags.Has(Direction::South) ? 1 : 0);
    MGL_TRACE("  East:  %d", flags.Has(Direction::East)  ? 1 : 0);
    MGL_TRACE("  West:  %d", flags.Has(Direction::West)  ? 1 : 0);
    MGL_TRACE("");
}
利用例
// 東北を表すフラグ
constexpr auto kNorthEast = DirectionFlags(Direction::North) | Direction::East;

// フラグに東北を設定
DirectionFlags flags(kNorthEast);
PrintDirectionFlags("(1) フラグに東北を設定", flags);

// 北のみのフラグで排他的論理和を適用
flags ^= Direction::North;
PrintDirectionFlags("(2) 北のみのフラグで排他的論理和を適用(北のみ反転する)", flags);

// さらに東北で排他的論理和を適用
flags ^= kNorthEast;
PrintDirectionFlags(
        "(3) さらに東北で排他的論理和を適用(2つが同時に反転し、東北との差分にもなる)",
        flags);
実行結果
(1) フラグに東北を設定
  North: 1
  South: 0
  East:  1
  West:  0

(2) 北のみのフラグで排他的論理和を適用(北のみ反転する)
  North: 0
  South: 0
  East:  1
  West:  0

(3) さらに東北で排他的論理和を適用(2つが同時に反転し、東北との差分にもなる)
  North: 1
  South: 0
  East:  0
  West:  0

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


operator |#

論理和のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) EnumType型との論理和
            constexpr EnumBitFlags operator|(EnumType rhs) const noexcept;

            // (2) 自身の型との論理和
            constexpr EnumBitFlags operator|(const EnumBitFlags &rhs) const noexcept;
    };
}

引数#

(1) EnumType型との論理和
EnumType rhs

EnumType型の右辺値

(2) 自身の型との論理和
const EnumBitFlags &rhs

自身の型の右辺値

戻り値#

EnumBitFlags

論理和の計算結果

説明#

2つのビットフラグの論理和を計算して結果を返すオペレータです。

(1) は右辺値にEnumType型の値を指定し、その値が表すビット位置のみがセットされたフラグとの論理和を計算します。 (2) は2つのビットフラグの論理和を計算して返します。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;

// フラグの状態を表示する関数
void PrintDirectionFlags(const char *label, DirectionFlags flags) noexcept
{
    MGL_TRACE(label);
    MGL_TRACE("  North: %d", flags.Has(Direction::North) ? 1 : 0);
    MGL_TRACE("  South: %d", flags.Has(Direction::South) ? 1 : 0);
    MGL_TRACE("  East:  %d", flags.Has(Direction::East)  ? 1 : 0);
    MGL_TRACE("  West:  %d", flags.Has(Direction::West)  ? 1 : 0);
    MGL_TRACE("");
}
利用例
// 東北を表すフラグ
constexpr auto kNorthEast = DirectionFlags(Direction::North) | Direction::East;

// 東北に西を追加したフラグを生成
auto flags = kNorthEast | Direction::West;
PrintDirectionFlags("東北に西を追加したフラグ", flags);
実行結果
東北に西を追加したフラグ
  North: 1
  South: 0
  East:  1
  West:  1

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#

operator |=


operator &#

論理積のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) EnumType型との論理積
            constexpr EnumBitFlags operator&(EnumType rhs) const noexcept;

            // (2) 自身の型との論理積
            constexpr EnumBitFlags operator&(const EnumBitFlags &rhs) const noexcept;
    };
}

引数#

(1) EnumType型との論理積
EnumType rhs

EnumType型の右辺値

(2) 自身の型との論理積
const EnumBitFlags &rhs

自身の型の右辺値

戻り値#

EnumBitFlags

論理積の計算結果

説明#

2つのビットフラグの論理積を計算して結果を返すオペレータです。

(1) は右辺値にEnumType型の値を指定し、その値が表すビット位置のみがセットされたフラグとの論理積を計算します。 (2) は2つのビットフラグの論理積を計算して返します。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;

// フラグの状態を表示する関数
void PrintDirectionFlags(const char *label, DirectionFlags flags) noexcept
{
    MGL_TRACE(label);
    MGL_TRACE("  North: %d", flags.Has(Direction::North) ? 1 : 0);
    MGL_TRACE("  South: %d", flags.Has(Direction::South) ? 1 : 0);
    MGL_TRACE("  East:  %d", flags.Has(Direction::East)  ? 1 : 0);
    MGL_TRACE("  West:  %d", flags.Has(Direction::West)  ? 1 : 0);
    MGL_TRACE("");
}
利用例
// 東北を表すフラグ
constexpr auto kNorthEast = DirectionFlags(Direction::North) | Direction::East;

// 東北の北だけをマスクしたフラグを生成
auto flags = kNorthEast & Direction::North;
PrintDirectionFlags("東北の北だけをマスクしたフラグ", flags);
実行結果
東北の北だけをマスクしたフラグ
  North: 1
  South: 0
  East:  0
  West:  0

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#

operator &=


operator ^#

排他的論理和のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            // (1) EnumType型との排他的論理和
            constexpr EnumBitFlags operator^(EnumType rhs) const noexcept;

            // (2) 自身の型との排他的論理和
            constexpr EnumBitFlags operator^(const EnumBitFlags &rhs) const noexcept
    };
}

引数#

(1) EnumType型との排他的論理和
EnumType rhs

EnumType型の右辺値

(2) 自身の型との排他的論理和
const EnumBitFlags &rhs

自身の型の右辺値

戻り値#

EnumBitFlags

排他的論理和の計算結果

説明#

2つのビットフラグの排他的論理和を計算して結果を返すオペレータです。

(1) は右辺値にEnumType型の値を指定し、その値が表すビット位置のみがセットされたフラグとの排他的論理和を計算します。 (2) は2つのビットフラグの排他的論理和を計算して返します。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;

// フラグの状態を表示する関数
void PrintDirectionFlags(const char *label, DirectionFlags flags) noexcept
{
    MGL_TRACE(label);
    MGL_TRACE("  North: %d", flags.Has(Direction::North) ? 1 : 0);
    MGL_TRACE("  South: %d", flags.Has(Direction::South) ? 1 : 0);
    MGL_TRACE("  East:  %d", flags.Has(Direction::East)  ? 1 : 0);
    MGL_TRACE("  West:  %d", flags.Has(Direction::West)  ? 1 : 0);
    MGL_TRACE("");
}
利用例
// 東北を表すフラグ
constexpr auto kNorthEast = DirectionFlags(Direction::North) | Direction::East;

// 東西を表すフラグ
constexpr auto kNorthWest = DirectionFlags(Direction::North) | Direction::West;

// 東北から東西を反転
auto flags = kNorthEast ^ kNorthWest;
PrintDirectionFlags("東北から東西を反転したフラグ", flags);
実行結果
東北から東西を反転したフラグ
  North: 0
  South: 0
  East:  1
  West:  1

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#

operator ^=


operator ~#

反転演算子のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            constexpr EnumBitFlags operator~() const noexcept;
    };
}

戻り値#

EnumBitFlags

全てのフラグを反転した結果

説明#

自身の全てのビットフラグを反転した結果を返すオペレータです。

このオペレータが返す値はFlipに引数を指定しなかった場合と同じですが、Flipとは異なり自身の値を変更しません。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;

// フラグの状態を表示する関数
void PrintDirectionFlags(const char *label, DirectionFlags flags) noexcept
{
    MGL_TRACE(label);
    MGL_TRACE("  North: %d", flags.Has(Direction::North) ? 1 : 0);
    MGL_TRACE("  South: %d", flags.Has(Direction::South) ? 1 : 0);
    MGL_TRACE("  East:  %d", flags.Has(Direction::East)  ? 1 : 0);
    MGL_TRACE("  West:  %d", flags.Has(Direction::West)  ? 1 : 0);
    MGL_TRACE("");
}
利用例
// 東北を表すフラグ
constexpr auto kNorthEast = DirectionFlags(Direction::North) | Direction::East;

// 東北を反転したフラグを生成
auto flags = ~kNorthEast;
PrintDirectionFlags("東北を反転したフラグ", flags);
実行結果
東北を反転したフラグ
  North: 0
  South: 1
  East:  0
  West:  1

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


operator ==#

等価演算子のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            constexpr bool operator==(const EnumBitFlags &rhs) const noexcept;
    };
}

引数#

const EnumBitFlags &rhs

比較する値の右辺値

戻り値#

bool

2つのビットフラグの等価比較結果

説明#

2つのビットフラグが等価であるかを判別するためのオペレータです。全てのビットの状態が同じであればtrueを、そうでなければfalseを返します。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// 東北を表すフラグ
constexpr auto kNorthEast = DirectionFlags(Direction::North) | Direction::East;

// 比較対象を生成
DirectionFlags flags(Direction::North);
flags.Set(Direction::East);

// 2つのビットフラグが同じかチェック
if (flags == kNorthEast)
{
    MGL_TRACE("2つのビットフラグは同じなのでここに到達する");
}

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#


operator !=#

不等価演算子のオペレータ

宣言#

namespace MGL
{
    template <class EnumType, typename FlagType = uint32_t>
    class EnumBitFlags
    {
        public:
            constexpr bool operator!=(const EnumBitFlags &rhs) const noexcept;
    };
}

引数#

const EnumBitFlags &rhs

比較する値の右辺値

戻り値#

bool

2つのビットフラグの不等価比較結果

説明#

2つのビットフラグが不等価であるかを判別するためのオペレータです。異なる状態のフラグがあればtrueを、全てのフラグが等しければfalseを返します。

利用例#

宣言
// 方角を表す列挙型の宣言
enum class Direction : uint8_t
{
    North,      // 北
    South,      // 南
    East,       // 東
    West        // 西
};

// 複数の方角を持てるビットフラグ型の宣言 (ここでは8ビットを指定)
using DirectionFlags = MGL::EnumBitFlags<Direction, uint8_t>;
利用例
// 東北を表すフラグ
constexpr auto kNorthEast = DirectionFlags(Direction::North) | Direction::East;

// 比較対象を生成(東西を生成)
DirectionFlags flags(Direction::North);
flags.Set(Direction::West);

// 2つのビットフラグが異なるかチェック
if (flags != kNorthEast)
{
    MGL_TRACE("2つのビットフラグは異なるのでここに到達する");
}

バージョン情報#

MGL 1.1.10
  • 初回リリース

関連#