TR1ちょっとやってみた@type_traits

今日は仕事してないんじゃないかぐらいの勢いでPOSTしてますが。
TR1で遊んでみる事が仕事なのさ。多分。だって職場しかVS2008ないんだもの。


つーことで、以下のは、type_traitsを使ってバッファの破棄処理を
スカラー型/非スカラー型で分岐させた自作配列クラスのコード。
スカラー型は簡単に言うとJavaで言ったりするところのプリミティブな型。
 後ポインタ。非スカラーJavaでryのオブジェクトな型。


#include 
#include

// Hogeクラス
struct Hoge
{
Hoge()
{
std::cout << "Created hoge." << std::endl;
}

~Hoge()
{
std::cout << "Destroyed hoge." << std::endl;
}
};

// 自作配列クラス
template
class MyArray
{
public:
T* _buf;

MyArray()
{
_buf = (T*)malloc(sizeof(T)*SIZE);
}

~MyArray()
{
// is_scalarでスカラー型/非スカラー型の処理を分ける。
MyArrayDestroyer<T, std::tr1::is_scalar::value> destroyer;
destroyer.Destroy(_buf, SIZE);
}

private:
// スカラー型用。バッファを解放するだけ。
template struct MyArrayDestroyer
{
void Destroy(T* buf, int size)
{
std::cout << "Destroyer for scalar." << std::endl;
free(buf);
}
};

// 非スカラー型用。全要素のデストラクタを呼んでからバッファを解放する。
template struct MyArrayDestroyer
{
void Destroy(T* buf, int size)
{
std::cout << "Destroyer for non-scalar." << std::endl;
for (int i = 0; i < size; ++i) buf[i].~T();
free(buf);
}
};
};

// main関数
int main()
{
MyArray intArray;
MyArray hogeArray;

return 0;
}

Destroyer for non-scalar.
Destroyed hoge.
Destroyed hoge.
Destroyed hoge.
Destroyed hoge.
Destroyed hoge.
Destroyer for scalar.

type_traitsが実装される前は、↓みたいなコードを書いて
場合分けしてました。type_traits自作しろよってツッコミはなし。

// 型タグ	... xutilityを参考に
struct ScalarTypeTag {
// スカラータイプ (非クラス)
};

struct NonScalarTypeTag {
// 非スカラータイプ (クラス)
};

template inline NonScalarTypeTag TypeTag(T& t) { return NonScalarTypeTag(); }
template inline ScalarTypeTag TypeTag(T* t) { return ScalarTypeTag(); }
template inline ScalarTypeTag TypeTag(const T* t) { return ScalarTypeTag(); }
inline ScalarTypeTag TypeTag(signed char t) { return ScalarTypeTag(); }
inline ScalarTypeTag TypeTag(unsigned char t) { return ScalarTypeTag(); }
inline ScalarTypeTag TypeTag(signed short t) { return ScalarTypeTag(); }
...以降全プリミティブ型についてTypeTag定義

// DestroyArray()
template void DestroyArray(T* p, int length, NonScalarTypeTag& tag) {
for (int i = length - 1; i >= 0; --i) p[i].~T();
}

template void DestroyArray(T* p, int length, ScalarTypeTag& tag) {
}

これが、std::tr1::is_scalarだけで実現できるなんて!
スゴイ時代になりましたね。


え?こんなめんどくせー事しないでnew/delete使えって?
'`,、(´∀`)'`,、


ちなみにtype_traitsについては↓のサイトとか参考になりメス。
boostのですが。
http://boost.cppll.jp/BDTJ_1_30/libs/type_traits/index.htm