C++
ふくしゅう。 http://exe.adam.ne.jp/j/tmfd.html から。
template <int x> struct Square { enum { value = x * x}; }; int main() { std::cout << Square::<16>::value << std::endl; }
このコードだと実行時に計算が行われず、コンパイル時に計算される。マクロだと思えば良い。これを「定数の畳み込み」というらしい。
次、「ループ展開」。お題はビットフラグ。順に << したビット値が並ぶ定数がある。
#define BIT_ONE 0x0001 #define BIT_TWO 0x0002 #define BIT_THREE 0x0004 #define BIT_FOUR 0x0008
もうなんとなくわかるはず。こいつらをコンパイル時にループで定義しちまおうという話。 勉強だから自分で書いてみる。
/* BitFlagVector.h */ #pragma once /** * 先に部分特殊化を行うための前方宣言をする * テンプレートクラス本体の定義後で特殊化する場合は要らないんだって */ template <int n> struct BitFlags; /** * 具体的なパラメータ (0) によるテンプレートの部分特殊化 * テンプレートパラメータに 0 が指定された場合にこの定義が適用される */ template <> struct BitFlags<0> { enum {value = 0}; }; /** * ビットフラグの値を示すテンプレート * 1 を << していく */ template <int n> struct BitFlags { enum {value = 1 << (n - 1)}; }; template <typename T> struct BitFlagsVector { volatile T data_; BitFlagsVector() : data_(0) {} template <int i> void on() { data_ |= BitFlags<i>::value; } template <int i> void off() { data_ &= ~BitFlags<i>::value; } template <int i> bool is() const { return data_ & BitFlags<i>::value; } void reset() { data_ = 0; } }; typedef BitFlagsVector<UInt32> BitFlagsVector32;
これを利用するとき。
class poo { BitFlagsVector32 bits_; public: enum Bits { None, BitOne, BitTwo, BitThree, BitFour }; bool Something() { bits_.on<Bits::BitThree>(); bits_.off<Bits::BitOne>(); return bits.is<BitFour>(); } };
実際にビルドしないとな〜