/******************************************************************************/
/* */
/* 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 ;
}