//-------------------------------------------------------------------------------------------------
double BenchChaiScript::DoBenchmark(const std::string& sExpr, long iCount)
{
   StopTimerAndReport("");
   return std::numeric_limits<double>::quiet_NaN();
   /*
   double a = 1.1;
   double b = 2.2;
   double c = 3.3;
   double x = 2.123456;
   double y = 3.123456;
   double z = 4.123456;
   double w = 5.123456;

   chaiscript::ChaiScript chai;

   chai.add(chaiscript::var(a), "a");
   chai.add(chaiscript::var(b), "b");
   chai.add(chaiscript::var(c), "c");
   chai.add(chaiscript::var(x), "x");
   chai.add(chaiscript::var(y), "y");
   chai.add(chaiscript::var(z), "z");
   chai.add(chaiscript::var(w), "w");

   // Calculate/bench and show result finally
   double fRes  = 0;
   double fSum  = 0;

   try
   {
      fRes = chai.eval<double>(sExpr);
   }
   catch (std::exception& e)
   {
      StopTimerAndReport(e.what());
      return std::numeric_limits<double>::quiet_NaN();
   }

   StartTimer();
   for (int j = 0; j < iCount; j++)
   {
      fSum += chai.eval<double>(sExpr);
      std::swap(a,b);
      std::swap(x,y);
   }
   StopTimer(fRes, fSum, iCount);

   return m_fTime1;
   */
}
//-------------------------------------------------------------------------------------------------
double BenchFParser::DoBenchmark(const std::string& sExpr, long iCount)
{
   double fRes (0);
   double fSum (0);

   FunctionParser Parser;
   Parser.AddConstant("pi", (double)M_PI);
   Parser.AddConstant("e", (double)M_E);

   if (Parser.Parse(sExpr.c_str(), "a,b,c,x,y,z,w") >= 0)
   {
      StopTimerAndReport(Parser.ErrorMsg());
      return m_fTime1;
   }
   else
   {
      double vals[] = {
                        1.1,
                        2.2,
                        3.3,
                        2.123456,
                        3.123456,
                        4.123456,
                        5.123456
                      };

      fRes = Parser.Eval(vals);

      StartTimer();

      for (int j = 0; j < iCount; ++j)
      {
         fSum += Parser.Eval(vals);
         std::swap(vals[0], vals[1]);
         std::swap(vals[3], vals[4]);
      }

      StopTimer(fRes, fSum, iCount);
   }

   return m_fTime1;
}
//-------------------------------------------------------------------------------------------------
double BenchATMSP::DoBenchmark(const std::string& sExpr, long iCount)
{
   ATMSB<double> bc;

   // Parsing/bytecode generation with error check. In a scope here JUST to
   // demonstrate that a parser-instance itself is NOT needed later on
   ATMSP<double> p;

   unsigned int err = p.parse(bc, sExpr, "a, b, c, x, y, z, w");

   if (err)
   {
      StopTimerAndReport(p.errMessage(err));
   }
   else
   {
      // Set variable values for x,y,z. Here always 1,2,3
      bc.var[0] = 1.1;
      bc.var[1] = 2.2;
      bc.var[2] = 3.3;
      bc.var[3] = 2.123456;
      bc.var[4] = 3.123456;
      bc.var[5] = 4.123456;
      bc.var[6] = 5.123456;

      //Prime the I and D caches for the expression
      {
         double d0 = 0.0;
         double d1 = 0.0;

         for (std::size_t i = 0; i < priming_rounds; ++i)
         {
            if (i & 1)
               d0 += bc.run();
            else
               d1 += bc.run();
         }

         if (
               (d0 == std::numeric_limits<double>::infinity()) &&
               (d1 == std::numeric_limits<double>::infinity())
            )
         {
            printf("\n");
         }
      }

      // Perform benchmark then return results
      double fRes (0);
      double fSum (0);

      fRes = bc.run();

      StartTimer();

      for (int j = 0; j < iCount; ++j)
      {
         fSum += bc.run();
         std::swap(bc.var[0], bc.var[1]);
         std::swap(bc.var[3], bc.var[4]);
      }

      StopTimer(fRes, fSum, iCount);
   }

   return m_fTime1;
}
//-------------------------------------------------------------------------------------------------
double BenchFParser::DoBenchmark(const std::string& sExpr, long iCount)
{
   double fRes = 0.0;
   double fSum = 0.0;

   FunctionParser Parser;
   Parser.AddConstant("pi", (double)M_PI);
   Parser.AddConstant("e", (double)M_E);

   if (Parser.Parse(sExpr.c_str(), "a,b,c,x,y,z,w") >= 0)
   {
      StopTimerAndReport(Parser.ErrorMsg());
      return m_fTime1;
   }
   else
   {
      double vals[] = {
                        1.1,
                        2.2,
                        3.3,
                        2.123456,
                        3.123456,
                        4.123456,
                        5.123456
                      };

      //Prime the I and D caches for the expression
      {
         double d0 = 0.0;
         double d1 = 0.0;

         for (std::size_t i = 0; i < priming_rounds; ++i)
         {
            if (i & 1)
               d0 += Parser.Eval(vals);
            else
               d1 += Parser.Eval(vals);
         }

         if (
               (d0 == std::numeric_limits<double>::infinity()) &&
               (d1 == std::numeric_limits<double>::infinity())
            )
         {
            printf("\n");
         }
      }

      fRes = Parser.Eval(vals);

      StartTimer();

      for (int j = 0; j < iCount; ++j)
      {
         fSum += Parser.Eval(vals);
         std::swap(vals[0], vals[1]);
         std::swap(vals[3], vals[4]);
      }

      StopTimer(fRes, fSum, iCount);
   }

   return m_fTime1;
}