From 95ffb98a8d08ef20672d6ef91ea8fb4320c5ea85 Mon Sep 17 00:00:00 2001
From: Arnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Date: Mon, 14 Feb 2011 11:00:58 +0100
Subject: [PATCH] Use std::vector and stl algorithms for cost_func.

---
 cost_func.cpp | 58 ++++++++++++++++++++++-----------------------------
 cost_func.h   |  6 +++---
 2 files changed, 28 insertions(+), 36 deletions(-)

diff --git a/cost_func.cpp b/cost_func.cpp
index 7311199..12c20f6 100644
--- a/cost_func.cpp
+++ b/cost_func.cpp
@@ -1,58 +1,50 @@
 #include <algorithm>
-#include <cstdlib>
-#include <cstring>
+#include <tr1/functional>
+#include <numeric>
 #include <iterator>
 #include <sstream>
+#include <stdexcept>
 
 #include "cost_func.h"
 
 cost_func::cost_func(const char* param)
 {
-    int len = strlen(param);
-    char tmpbuf[len + 1];
-    char* tmp = tmpbuf;
-    memcpy(tmp, param, len + 1);
-    degree = std::count(tmp, tmp + len, ',');
-    factor = new double[degree + 1];
-    for (int i = degree ; i > 0 ; i--) {
-        char* next = strchr(tmp, ',');
-        *next++ = '\0';
-        std::istringstream(tmp) >> factor[i];
-        tmp = next;
+    std::istringstream paramstream(param);
+    std::string token;
+    while (std::getline(paramstream, token, ',')) {
+        std::istringstream str(token);
+        double f;
+        if ((str >> f) && str.eof())
+            factors.push_back(f);
+        else
+            throw std::invalid_argument("cost_func(): "
+                                        "cannot parse \"" + token + "\"");
     }
-    std::istringstream(tmp) >> factor[0];
+    if (factors.empty())
+        throw std::invalid_argument("cost_func(): no factor");
 }
 
 cost_func::~cost_func()
 {
-    delete[] factor;
-}
-
-cost_func& cost_func::operator=(const cost_func& ref)
-{
-    if (&ref != this) {
-        degree = ref.degree;
-        delete[] factor;
-        factor = new double[degree + 1];
-        memcpy(factor, ref.factor, (degree + 1) * sizeof *factor);
-    }
-    return *this;
 }
 
 double cost_func::operator()(double amount) const
 {
-    double result = factor[degree];
-    for (int i = degree - 1; i >= 0 ; i--)
-        result = amount * result + factor[i];
-    return result;
+    using std::tr1::bind;
+    using std::tr1::placeholders::_1;
+    using std::tr1::placeholders::_2;
+    return std::accumulate(++factors.begin(), factors.end(), factors.front(),
+                           bind(std::plus<double>(),
+                                bind(std::multiplies<double>(), amount, _1),
+                                _2));
 }
 
 std::string cost_func::to_string()
 {
     std::ostringstream oss;
-    std::reverse_copy(factor + 1, factor + degree + 1,
-                      std::ostream_iterator<double>(oss, ", "));
-    oss << factor[0];
+    std::copy(factors.begin(), --factors.end(),
+              std::ostream_iterator<double>(oss, ", "));
+    oss << factors.back();
     return oss.str();
 }
 
diff --git a/cost_func.h b/cost_func.h
index d7310d2..c6984d2 100644
--- a/cost_func.h
+++ b/cost_func.h
@@ -3,6 +3,7 @@
 
 #include <iostream>
 #include <string>
+#include <vector>
 
 // Define a polynomial function
 // The factors are given at construction time, in a C-style string,
@@ -11,13 +12,12 @@ class cost_func {
 public:
     cost_func(const char* param);
     ~cost_func();
-    cost_func& operator=(const cost_func& ref);
 
     double operator()(double amount) const;
     std::string to_string();
+
 private:
-    int degree;
-    double* factor;
+    std::vector<double> factors;
 };
 
 #endif // !COST_FUNC_H
-- 
2.39.5