enum (後半修正)

俺ルール的なモノです。

enum で、連続した値を定義する時は ..._begin, ..._end も書いておきます

enum Name {
	NAME_HOGE_begin,
	NAME_HOGE_A = NAME_HOGE_begin,
	...
	NAME_HOGE_Z,
	NAME_HOGE_end,

	NAME_PUHA_begin = NAME_HOGE_end,
	NAME_PUHA_A = NAME_PUHA_begin,
	...
	NAME_PUHA_Z,
	NAME_PUHA_end,

	...
};

たとえば、以下のようなループをするときや

for (int i = NAME_HOGE_begin; i != NAME_HOGE_end; ++ i) { ... }

以下のようにサイズを得たい時などに便利です。

int hoge[NAME_HOGE_end - NAME_HOGE_begin];
int puha[NAME_PUHA_end - NAME_PUHA_begin];

..._end しか定義しないこともよくあります。名前が ..._begin, ..._end なのは STL の影響を受けています。

enum で、フラグの中に値を混ぜる時は ..._shift, ..._mask, ..._bits も書いておきます

enum Flag {
	FLAG_X			= 1 << 0,
	FLAG_Y			= 1 << 1,
	FLAG_Z			= 1 << 2,

	FLAG_COLOR_shift	= 3,
	FLAG_COLOR_bits		= 3,
	FLAG_COLOR_mask		= 7 << FLAG_COLOR_shift,
	FLAG_COLOR_BLACK	= 0 << FLAG_COLOR_shift,
	...
	FLAG_COLOR_WHITE	= 7 << FLAG_COLOR_shift,

	FLAG_NEXT		= 1 << (FLAG_COLOR_shift + FLAG_COLOR_bits),
	...
};

たとえば、以下のようなケースで使います。

switch (flag & FLAG_COLOR_mask) {
case FLAG_COLOR_BLACK: ...
}

..._bits は記述しないことがあります。

enum で、フラグを定義するときに、2 つ以上の enum フラグを一つにまとめたい時は ..._begin, ..._end も書いておきます

enum FlagHoge {
	FLAG_HOGE_begin = 1 << 0,
	FLAG_HOGE_A     = FLAG_HOGE_begin << 0,
	FLAG_HOGE_B     = FLAG_HOGE_begin << 1,
	...
	FLAG_HOGE_J     = FLAG_HOGE_begin << 9,
	FLAG_HOGE_end   = FLAG_HOGE_begin << 10,
};

enum FlagPuha {
	FLAG_PUHA_begin = FLAG_HOGE_end,
	FLAG_PUHA_K     = FLAG_PUHA_begin << 0,
	FLAG_PUHA_L     = FLAG_PUHA_begin << 1,
	...
	FLAG_PUHA_Z     = FLAG_PUHA_begin << 16,
	FLAG_PUHA_end   = FLAG_PUHA_begin << 17,
};
BOOST_STATIC_ASSERT(FLAG_PUHA_begin < FLAG_PUHA_end);

以下のようにフラグを混ぜて使うことができますし、FlagHoge 内にフラグを追加した場合に FlagPuha の定義を変更する必要がありません。

int flags = FLAG_HOGE_A | FLAG_PUHA_B;

enumで、フラグを定義するときはデフォルトのフラグを0にします

たとえば、ある機能が有効か無効かを意味するフラグを定義したい場合、

enum Flag {
	FLAG_HOGE_ENABLED	= 0,
	FLAG_HOGE_DISABLED	= 1 << 0,
};

にするか、

enum Flag {
	FLAG_HOGE_ENABLED	= 1 << 0,
	FLAG_HOGE_DISABLED	= 0,
};

にするかは、どちらの状態をデフォルトにしたいかで選択します。デフォルトが0なので、変数を0で初期化できるからです。

int flags = 0;