Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/36277 )

Change subject: sim: Generalize the arrayParamOut and arrayParamIn functions.
......................................................................

sim: Generalize the arrayParamOut and arrayParamIn functions.

These had been written specifically for the vector, list, set, and C
style array types. This change reworks them to share an implementation,
and to work with more general types. The arrayParamOut method requires
std::begin() and std::end() to accept that type, and the arrayParamIn
method requires either insert or push_back, or the type to be an array.

Also fix up a couple of files which accidentally depended on includes in
the serialize headers which are no longer necessary.

Change-Id: I6ec4fe3bb900603bbb4e35c4efa620c249942452
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36277
Reviewed-by: Andreas Sandberg <[email protected]>
Maintainer: Andreas Sandberg <[email protected]>
Tested-by: kokoro <[email protected]>
---
M src/sim/fd_array.hh
M src/sim/serialize.cc
M src/sim/serialize.hh
M src/sim/system.hh
4 files changed, 76 insertions(+), 201 deletions(-)

Approvals:
  Andreas Sandberg: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/sim/fd_array.hh b/src/sim/fd_array.hh
index 5b9265d..5295566 100644
--- a/src/sim/fd_array.hh
+++ b/src/sim/fd_array.hh
@@ -35,6 +35,7 @@
 #define __FD_ARRAY_HH__

 #include <array>
+#include <map>
 #include <memory>
 #include <string>

diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc
index 5aa933d..e502d9a 100644
--- a/src/sim/serialize.cc
+++ b/src/sim/serialize.cc
@@ -49,6 +49,7 @@
 #include <cerrno>
 #include <fstream>
 #include <list>
+#include <set>
 #include <string>
 #include <vector>

diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh
index 6c06eeb..22c40aa 100644
--- a/src/sim/serialize.hh
+++ b/src/sim/serialize.hh
@@ -48,10 +48,9 @@

 #include <algorithm>
 #include <iostream>
-#include <list>
-#include <map>
+#include <iterator>
 #include <stack>
-#include <set>
+#include <type_traits>
 #include <vector>

 #include "base/bitunion.hh"
@@ -524,18 +523,18 @@
 /**
  * @ingroup api_serialize
  */
-template <class T>
+template <class InputIterator>
 void
 arrayParamOut(CheckpointOut &os, const std::string &name,
-              const std::vector<T> &param)
+              InputIterator start, InputIterator end)
 {
-    typename std::vector<T>::size_type size = param.size();
     os << name << "=";
-    if (size > 0)
-        showParam(os, param[0]);
-    for (typename std::vector<T>::size_type i = 1; i < size; ++i) {
+    auto it = start;
+    if (it != end)
+        showParam(os, *it++);
+    while (it != end) {
         os << " ";
-        showParam(os, param[i]);
+        showParam(os, *it++);
     }
     os << "\n";
 }
@@ -544,45 +543,14 @@
  * @ingroup api_serialize
  */
 template <class T>
-void
+decltype(std::begin(std::declval<const T&>()),
+         std::end(std::declval<const T&>()), void())
 arrayParamOut(CheckpointOut &os, const std::string &name,
-              const std::list<T> &param)
+              const T &param)
 {
-    typename std::list<T>::const_iterator it = param.begin();
-
-    os << name << "=";
-    if (param.size() > 0)
-        showParam(os, *it);
-    it++;
-    while (it != param.end()) {
-        os << " ";
-        showParam(os, *it);
-        it++;
-    }
-    os << "\n";
+    arrayParamOut(os, name, std::begin(param), std::end(param));
 }

-/**
- * @ingroup api_serialize
- */
-template <class T>
-void
-arrayParamOut(CheckpointOut &os, const std::string &name,
-              const std::set<T> &param)
-{
-    typename std::set<T>::const_iterator it = param.begin();
-
-    os << name << "=";
-    if (param.size() > 0)
-        showParam(os, *it);
-    it++;
-    while (it != param.end()) {
-        os << " ";
-        showParam(os, *it);
-        it++;
-    }
-    os << "\n";
-}

 /**
  * @ingroup api_serialize
@@ -592,14 +560,7 @@
 arrayParamOut(CheckpointOut &os, const std::string &name,
               const T *param, unsigned size)
 {
-    os << name << "=";
-    if (size > 0)
-        showParam(os, param[0]);
-    for (unsigned i = 1; i < size; ++i) {
-        os << " ";
-        showParam(os, param[i]);
-    }
-    os << "\n";
+    arrayParamOut(os, name, param, param + size);
 }

 /**
@@ -613,160 +574,71 @@
  *
  * @ingroup api_serialize
  */
+
+template <class T, class InsertIterator>
+void
+arrayParamIn(CheckpointIn &cp, const std::string &name,
+             InsertIterator inserter, ssize_t fixed_size=-1)
+{
+    const std::string &section = Serializable::currentSection();
+    std::string str;
+    fatal_if(!cp.find(section, name, str),
+        "Can't unserialize '%s:%s'.", section, name);
+
+    std::vector<std::string> tokens;
+    tokenize(tokens, str, ' ');
+
+    fatal_if(fixed_size >= 0 && tokens.size() != fixed_size,
+             "Array size mismatch on %s:%s (Got %u, expected %u)'\n",
+             section, name, tokens.size(), fixed_size);
+
+    for (const auto &token: tokens) {
+        T value;
+ fatal_if(!parseParam(token, value), "Could not parse \"%s\".", str);
+        *inserter = value;
+    }
+}
+
+/**
+ * @ingroup api_serialize
+ */
+template <class T>
+decltype(std::declval<T>().insert(std::declval<typename T::value_type>()),
+         void())
+arrayParamIn(CheckpointIn &cp, const std::string &name, T &param)
+{
+    param.clear();
+    arrayParamIn<typename T::value_type>(
+            cp, name, std::inserter(param, param.begin()));
+}
+
+/**
+ * @ingroup api_serialize
+ */
+template <class T>
+decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()),
+         void())
+arrayParamIn(CheckpointIn &cp, const std::string &name, T &param)
+{
+    param.clear();
+ arrayParamIn<typename T::value_type>(cp, name, std::back_inserter(param));
+}
+
+/**
+ * @ingroup api_serialize
+ */
 template <class T>
 void
 arrayParamIn(CheckpointIn &cp, const std::string &name,
              T *param, unsigned size)
 {
-    const std::string &section(Serializable::currentSection());
-    std::string str;
-    if (!cp.find(section, name, str)) {
-        fatal("Can't unserialize '%s:%s'\n", section, name);
-    }
+    struct ArrayInserter
+    {
+        T *data;
+        T &operator *() { return *data++; }
+    } insert_it{param};

-    // code below stolen from VectorParam<T>::parse().
-    // it would be nice to unify these somehow...
-
-    std::vector<std::string> tokens;
-
-    tokenize(tokens, str, ' ');
-
-    // Need this if we were doing a vector
-    // value.resize(tokens.size());
-
-    fatal_if(tokens.size() != size,
-             "Array size mismatch on %s:%s (Got %u, expected %u)'\n",
-             section, name, tokens.size(), size);
-
- for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
-        // need to parse into local variable to handle vector<bool>,
-        // for which operator[] returns a special reference class
-        // that's not the same as 'bool&', (since it's a packed
-        // vector)
-        T scalar_value;
-        if (!parseParam(tokens[i], scalar_value)) {
-            std::string err("could not parse \"");
-
-            err += str;
-            err += "\"";
-
-            fatal(err);
-        }
-
-        // assign parsed value to vector
-        param[i] = scalar_value;
-    }
-}
-
-/**
- * @ingroup api_serialize
- */
-template <class T>
-void
-arrayParamIn(CheckpointIn &cp, const std::string &name, std::vector<T> &param)
-{
-    const std::string &section(Serializable::currentSection());
-    std::string str;
-    if (!cp.find(section, name, str)) {
-        fatal("Can't unserialize '%s:%s'\n", section, name);
-    }
-
-    // code below stolen from VectorParam<T>::parse().
-    // it would be nice to unify these somehow...
-
-    std::vector<std::string> tokens;
-
-    tokenize(tokens, str, ' ');
-
-    // Need this if we were doing a vector
-    // value.resize(tokens.size());
-
-    param.resize(tokens.size());
-
- for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
-        // need to parse into local variable to handle vector<bool>,
-        // for which operator[] returns a special reference class
-        // that's not the same as 'bool&', (since it's a packed
-        // vector)
-        T scalar_value;
-        if (!parseParam(tokens[i], scalar_value)) {
-            std::string err("could not parse \"");
-
-            err += str;
-            err += "\"";
-
-            fatal(err);
-        }
-
-        // assign parsed value to vector
-        param[i] = scalar_value;
-    }
-}
-
-/**
- * @ingroup api_serialize
- */
-template <class T>
-void
-arrayParamIn(CheckpointIn &cp, const std::string &name, std::list<T> &param)
-{
-    const std::string &section(Serializable::currentSection());
-    std::string str;
-    if (!cp.find(section, name, str)) {
-        fatal("Can't unserialize '%s:%s'\n", section, name);
-    }
-    param.clear();
-
-    std::vector<std::string> tokens;
-    tokenize(tokens, str, ' ');
-
- for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
-        T scalar_value;
-        if (!parseParam(tokens[i], scalar_value)) {
-            std::string err("could not parse \"");
-
-            err += str;
-            err += "\"";
-
-            fatal(err);
-        }
-
-        // assign parsed value to vector
-        param.push_back(scalar_value);
-    }
-}
-
-/**
- * @ingroup api_serialize
- */
-template <class T>
-void
-arrayParamIn(CheckpointIn &cp, const std::string &name, std::set<T> &param)
-{
-    const std::string &section(Serializable::currentSection());
-    std::string str;
-    if (!cp.find(section, name, str)) {
-        fatal("Can't unserialize '%s:%s'\n", section, name);
-    }
-    param.clear();
-
-    std::vector<std::string> tokens;
-    tokenize(tokens, str, ' ');
-
- for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
-        T scalar_value;
-        if (!parseParam(tokens[i], scalar_value)) {
-            std::string err("could not parse \"");
-
-            err += str;
-            err += "\"";
-
-            fatal(err);
-        }
-
-        // assign parsed value to vector
-        param.insert(scalar_value);
-    }
+    arrayParamIn<T>(cp, name, insert_it, size);
 }

 void
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 4b44616..4954af6 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -42,6 +42,7 @@
 #ifndef __SYSTEM_HH__
 #define __SYSTEM_HH__

+#include <set>
 #include <string>
 #include <unordered_map>
 #include <utility>

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/36277
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I6ec4fe3bb900603bbb4e35c4efa620c249942452
Gerrit-Change-Number: 36277
Gerrit-PatchSet: 4
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Ciro Santilli <[email protected]>
Gerrit-Reviewer: Gabe Black <[email protected]>
Gerrit-Reviewer: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-CC: Jason Lowe-Power <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to