2003

Grusel++ of the month

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