Expression Template 其の一
早速、Expression Template(ET)を試してみることにした。
ずいぶん前に、買って置いたC++テンプレートテクニックを参考に実装してみる。
そのままでは詰まらないので、ベクトルの次元数を型情報としてテンプレート引数にとるようにしてみた。Traitsってやつか?
次元数を追い出したのはいいが、コンストラクタで初期化出来なくなってしまったので、Boostの真似をして代入用の演算子を定義しておいた。
が、、+=が使えなくなるので、シフト演算子あたりに変えようかな・・・。
以下、vector_types.h
#ifndef _vector_types_h_ #define _vector_types_h_ #include <assert.h> namespace tml { typedef unsigned int size_t; // 型定義構造体 struct tagInt2 { typedef int Type; enum { Dim = 2 }; }; struct tagInt3 { typedef int Type; enum { Dim = 3 }; }; struct tagInt4 { typedef int Type; enum { Dim = 4 }; }; struct tagFloat2 { typedef float Type; enum { Dim = 2 }; }; struct tagFloat3 { typedef float Type; enum { Dim = 3 }; }; struct tagFloat4 { typedef float Type; enum { Dim = 4 }; }; // 本体 template<class _TypeTag> struct Vector { typedef typename _TypeTag::Type Type; enum { Dim = _TypeTag::Dim }; Type v[Dim]; Vector() { for(int n = 0; n < Dim; n++) v[n] = 0.0f; } Vector(Type vv[]) { for(int n = 0; n < Dim; n++) v[n] = vv[n]; } // Expression Template用 Type& operator[](size_t n) { return v[n]; } Type operator[](size_t n) const { return v[n]; } template<class _Expr> inline Vector<_TypeTag>& operator=(const _Expr &expr) { for(size_t i = 0; i < Dim; i++) { v[i] = expr[i]; } return *this; } }; // 代入簡略化 template<class _TypeTag, int N> struct VectorAssigner { Vector<_TypeTag> &v; VectorAssigner(Vector<_TypeTag> &vector) : v(vector) {} inline VectorAssigner<_TypeTag, N+1> operator,(typename _TypeTag::Type arg) // boostの真似 { assert(N < _TypeTag::Dim); // 代入しすぎ v.v[N] = arg; return VectorAssigner<_TypeTag, N+1>(v); } }; template<class _TypeTag> inline VectorAssigner<_TypeTag, 1> operator+=(Vector<_TypeTag> &v, typename _TypeTag::Type arg) { v.v[0] = arg; return VectorAssigner<_TypeTag, 1>(v); } } // namespace tml #endif
Vector側に実装したのは代入演算子だけで、まだ、ETの部分は書いていない。
次はExpression Template本体をやる予定。。