diff --git a/src/sim/fd_array.hh b/src/sim/fd_array.hh index 5b9265d370..5295566471 100644 --- a/src/sim/fd_array.hh +++ b/src/sim/fd_array.hh @@ -35,6 +35,7 @@ #define __FD_ARRAY_HH__ #include +#include #include #include diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 5aa933d2e3..e502d9aa77 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 6c06eeb25c..22c40aac03 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -48,10 +48,9 @@ #include #include -#include -#include +#include #include -#include +#include #include #include "base/bitunion.hh" @@ -524,18 +523,18 @@ paramIn(CheckpointIn &cp, const std::string &name, T ¶m) /** * @ingroup api_serialize */ -template +template void arrayParamOut(CheckpointOut &os, const std::string &name, - const std::vector ¶m) + InputIterator start, InputIterator end) { - typename std::vector::size_type size = param.size(); os << name << "="; - if (size > 0) - showParam(os, param[0]); - for (typename std::vector::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 @@ arrayParamOut(CheckpointOut &os, const std::string &name, * @ingroup api_serialize */ template -void +decltype(std::begin(std::declval()), + std::end(std::declval()), void()) arrayParamOut(CheckpointOut &os, const std::string &name, - const std::list ¶m) + const T ¶m) { - typename std::list::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 -void -arrayParamOut(CheckpointOut &os, const std::string &name, - const std::set ¶m) -{ - typename std::set::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 @@ void 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 @@ arrayParamOut(CheckpointOut &os, const std::string &name, * * @ingroup api_serialize */ + +template +void +arrayParamIn(CheckpointIn &cp, const std::string &name, + InsertIterator inserter, ssize_t fixed_size=-1) +{ + const std::string §ion = Serializable::currentSection(); + std::string str; + fatal_if(!cp.find(section, name, str), + "Can't unserialize '%s:%s'.", section, name); + + std::vector 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 +decltype(std::declval().insert(std::declval()), + void()) +arrayParamIn(CheckpointIn &cp, const std::string &name, T ¶m) +{ + param.clear(); + arrayParamIn( + cp, name, std::inserter(param, param.begin())); +} + +/** + * @ingroup api_serialize + */ +template +decltype(std::declval().push_back(std::declval()), + void()) +arrayParamIn(CheckpointIn &cp, const std::string &name, T ¶m) +{ + param.clear(); + arrayParamIn(cp, name, std::back_inserter(param)); +} + +/** + * @ingroup api_serialize + */ template void arrayParamIn(CheckpointIn &cp, const std::string &name, T *param, unsigned size) { - const std::string §ion(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::parse(). - // it would be nice to unify these somehow... - - std::vector 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::size_type i = 0; i < tokens.size(); i++) { - // need to parse into local variable to handle vector, - // 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 -void -arrayParamIn(CheckpointIn &cp, const std::string &name, std::vector ¶m) -{ - const std::string §ion(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::parse(). - // it would be nice to unify these somehow... - - std::vector tokens; - - tokenize(tokens, str, ' '); - - // Need this if we were doing a vector - // value.resize(tokens.size()); - - param.resize(tokens.size()); - - for (std::vector::size_type i = 0; i < tokens.size(); i++) { - // need to parse into local variable to handle vector, - // 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 -void -arrayParamIn(CheckpointIn &cp, const std::string &name, std::list ¶m) -{ - const std::string §ion(Serializable::currentSection()); - std::string str; - if (!cp.find(section, name, str)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } - param.clear(); - - std::vector tokens; - tokenize(tokens, str, ' '); - - for (std::vector::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 -void -arrayParamIn(CheckpointIn &cp, const std::string &name, std::set ¶m) -{ - const std::string §ion(Serializable::currentSection()); - std::string str; - if (!cp.find(section, name, str)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } - param.clear(); - - std::vector tokens; - tokenize(tokens, str, ' '); - - for (std::vector::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(cp, name, insert_it, size); } void diff --git a/src/sim/system.hh b/src/sim/system.hh index 4b44616866..4954af68f4 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -42,6 +42,7 @@ #ifndef __SYSTEM_HH__ #define __SYSTEM_HH__ +#include #include #include #include