浮動小数点演算(FLoating point Operation)の回数をカウントする以下のような非常に単純なクラスを作ってみました.
#include#include template< class Real = double, class Counter = long long> class flo_counter : public boost::unit_steppable , boost::euclidian_ring_operators , boost::euclidian_ring_operators , Real, boost::partially_ordered , boost::partially_ordered , Real > > > > > { public: flo_counter(Real const &r = Real()) : val(r) { } flo_counter(flo_counter const &r) : val(r.val) { } flo_counter &operator++() { return ++val; } flo_counter &operator--() { return --val; } #define DEFINE_ASSIGNMENT_OPERATOR(OP) \ flo_counter & operator ## OP(flo_counter const &rhs) \ { \ val OP rhs.val; \ ++cnt; \ return *this; \ } \ #define DEFINE_ASSIGNMENT_OPERATOR2(OP) \ flo_counter & operator ## OP(Real const &rhs) \ { \ val OP rhs; \ ++cnt; \ return *this; \ } \ DEFINE_ASSIGNMENT_OPERATOR(+=) DEFINE_ASSIGNMENT_OPERATOR(-=) DEFINE_ASSIGNMENT_OPERATOR(*=) DEFINE_ASSIGNMENT_OPERATOR(/=) DEFINE_ASSIGNMENT_OPERATOR(%=) DEFINE_ASSIGNMENT_OPERATOR2(+=) DEFINE_ASSIGNMENT_OPERATOR2(-=) DEFINE_ASSIGNMENT_OPERATOR2(*=) DEFINE_ASSIGNMENT_OPERATOR2(/=) DEFINE_ASSIGNMENT_OPERATOR2(%=) #undef DEFINE_ASSIGNMENT_OPERATOR #undef DEFINE_ASSIGNMENT_OPERATOR2 #define DEFINE_BOOLEAN_OPERATOR(OP) \ bool operator ## OP(flo_counter const &rhs) const \ { \ return val OP rhs.val; \ } \ #define DEFINE_BOOLEAN_OPERATOR2(OP) \ bool operator ## OP(Real const &rhs) const \ { \ return val OP rhs; \ } \ DEFINE_BOOLEAN_OPERATOR(<) DEFINE_BOOLEAN_OPERATOR(==) DEFINE_BOOLEAN_OPERATOR2(<) DEFINE_BOOLEAN_OPERATOR2(>) DEFINE_BOOLEAN_OPERATOR2(==) #undef DEFINE_BOOLEAN_OPERATOR #undef DEFINE_BOOLEAN_OPERATOR2 flo_counter sqrt() const { return flo_counter(std::sqrt(val)); } flo_counter abs() const { return flo_counter(std::abs(val)); } static Counter &count() { return cnt; } private: Real val; static Counter cnt; }; template Counter flo_counter ::cnt = 0;
sqrtやabsのようなあまり本質的でないメンバ関数が入ってますがあまり気にしないでください.このクラスで一番目立つのは継承の部分でしょうか?Boost.Operatorsの枠組みに従うと必然的にこうなります.この継承の部分はよく見れば分かりますが,CRTPとChained Inheritanceの複合技です.Boost.OperatorsがCRTPで何をしているかについてはid:Cryolite:20040605#p2あたりを参考にしてみてください.
上のflo_counterはこれで組み込みの浮動小数点型とほとんど同等なものとして振舞うことが可能になります.でもこれだけでは全然面白くないので,次回はこれをboost::numeric::ublas::vectorあたりにでも突っ込んでみようかと思います.