/******************************************************************************/ /* */ /* FILE: july.cpp */ /* */ /* As you can see, expression templates are worth studying */ /* ======================================================= */ /* */ /* Compiled and tested with gcc version 2.95.4 */ /* */ /* V1.00 30-JUL-2003 P. Tellenbach http://www.heimetli.ch/ */ /* */ /******************************************************************************/ #include <iostream> #include <functional> using namespace std ; template< class E1, class E2, class OP > class BinaryOperation { public: BinaryOperation( E1 e1, E2 e2, OP op=OP() ) : expr1(e1), expr2(e2), operation(op) { } double eval() const { return operation( expr1.eval(), expr2.eval() ) ; } protected: OP operation ; E1 expr1 ; E2 expr2 ; } ; template< class E1, class OP > class BinaryOperation< E1, double, OP > { public: BinaryOperation( E1 e1, double val, OP op=OP() ) : expr1(e1), value(val), operation(op) { } double eval() const { return operation( expr1.eval(), value ) ; } protected: OP operation ; E1 expr1 ; double value ; } ; class Variable { public: Variable( int &var ) : variable(var) { } int eval() const { return variable ; } protected: int &variable ; } ; template< class E1, class E2 > BinaryOperation< E1, E2, multiplies<double> > operator*( E1 e1, E2 e2 ) { return BinaryOperation< E1, E2, multiplies<double> >( e1, e2 ) ; } template< class E1, class E2 > BinaryOperation< E1, E2, plus<double> > operator+( E1 e1, E2 e2 ) { return BinaryOperation< E1, E2, plus<double> >( e1, e2 ) ; } template< class E1, class E2 > BinaryOperation< E1, E2, minus<double> > operator-( E1 e1, E2 e2 ) { return BinaryOperation< E1, E2, minus<double> >( e1, e2 ) ; } int main() { int counter ; Variable v( counter ) ; for( counter = 0; counter < 14; counter++ ) { double d = ((v * -0.0000199493478221892) + 0.00170801522349198).eval() ; d = ((v * d) - 0.0652646127594653).eval() ; d = ((v * d) + 1.46796617521522).eval() ; d = ((v * d) - 21.5819612576657).eval() ; d = ((v * d) + 217.713509399792).eval() ; d = ((v * d) - 1538.60419552855).eval() ; d = ((v * d) + 7635.50553541271).eval() ; d = ((v * d) - 26240.4880212878).eval() ; d = ((v * d) + 60422.8402050241).eval() ; d = ((v * d) - 87602.3794713755).eval() ; d = ((v * d) + 70841.9748145348).eval() ; cout << (char) (v * ((v * d) - 23687.3847948726) + 72.5).eval() ; } return 0 ; }
Update 31. July 2023
The compiler warned about the order of initializers. Reordering them resolved the problem.
/******************************************************************************/ /* */ /* FILE: july.cpp */ /* */ /* As you can see, expression templates are worth studying */ /* ======================================================= */ /* */ /* Compiled and tested with gcc version 2.95.4 */ /* */ /* V1.00 30-JUL-2003 P. Tellenbach https://www.heimetli.ch */ /* */ /* Compiled and tested with g++ version 11.2.0 */ /* */ /* V1.10 31-JUL-2023 P. Tellenbach https://www.heimetli.ch */ /* */ /******************************************************************************/ #include <iostream> #include <functional> using namespace std ; template< class E1, class E2, class OP > class BinaryOperation { public: BinaryOperation( E1 e1, E2 e2, OP op=OP() ) : operation(op), expr1(e1), expr2(e2) { } double eval() const { return operation( expr1.eval(), expr2.eval() ) ; } protected: OP operation ; E1 expr1 ; E2 expr2 ; } ; template< class E1, class OP > class BinaryOperation< E1, double, OP > { public: BinaryOperation( E1 e1, double val, OP op=OP() ) : operation(op), expr1(e1), value(val) { } double eval() const { return operation( expr1.eval(), value ) ; } protected: OP operation ; E1 expr1 ; double value ; } ; class Variable { public: Variable( int &var ) : variable(var) { } int eval() const { return variable ; } protected: int &variable ; } ; template< class E1, class E2 > BinaryOperation< E1, E2, multiplies<double> > operator*( E1 e1, E2 e2 ) { return BinaryOperation< E1, E2, multiplies<double> >( e1, e2 ) ; } template< class E1, class E2 > BinaryOperation< E1, E2, plus<double> > operator+( E1 e1, E2 e2 ) { return BinaryOperation< E1, E2, plus<double> >( e1, e2 ) ; } template< class E1, class E2 > BinaryOperation< E1, E2, minus<double> > operator-( E1 e1, E2 e2 ) { return BinaryOperation< E1, E2, minus<double> >( e1, e2 ) ; } int main() { int counter ; Variable v( counter ) ; for( counter = 0; counter < 14; counter++ ) { double d = ((v * -0.0000199493478221892) + 0.00170801522349198).eval() ; d = ((v * d) - 0.0652646127594653).eval() ; d = ((v * d) + 1.46796617521522).eval() ; d = ((v * d) - 21.5819612576657).eval() ; d = ((v * d) + 217.713509399792).eval() ; d = ((v * d) - 1538.60419552855).eval() ; d = ((v * d) + 7635.50553541271).eval() ; d = ((v * d) - 26240.4880212878).eval() ; d = ((v * d) + 60422.8402050241).eval() ; d = ((v * d) - 87602.3794713755).eval() ; d = ((v * d) + 70841.9748145348).eval() ; cout << (char) (v * ((v * d) - 23687.3847948726) + 72.5).eval() ; } return 0 ; }