summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2014-09-20 17:17:49 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2014-09-20 17:17:49 -0400
commit0fa128bbd0a53a3428fa2028b8754e15c9ef7c38 (patch)
tree30e2598a67f540e97cdbaf1cf7f5092b974d9d3c /src
parentb2c2e67468bba6dbbbfb6856ca94fdcfa1492258 (diff)
downloadgem5-0fa128bbd0a53a3428fa2028b8754e15c9ef7c38.tar.xz
base: Clean up redundant string functions and use C++11
This patch does a bit of housekeeping on the string helper functions and relies on the C++11 standard library where possible. It also does away with our custom string hash as an implementation is already part of the standard library.
Diffstat (limited to 'src')
-rw-r--r--src/base/statistics.hh6
-rw-r--r--src/base/stats/text.cc8
-rw-r--r--src/base/str.cc272
-rw-r--r--src/base/str.hh116
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh2
-rw-r--r--src/dev/uart8250.cc1
-rw-r--r--src/sim/serialize.cc19
7 files changed, 97 insertions, 327 deletions
diff --git a/src/base/statistics.hh b/src/base/statistics.hh
index 7e5f1f5b9..1b3d0fc54 100644
--- a/src/base/statistics.hh
+++ b/src/base/statistics.hh
@@ -741,7 +741,7 @@ class ScalarBase : public DataWrap<Derived, ScalarInfoProxy>
class ProxyInfo : public ScalarInfo
{
public:
- std::string str() const { return to_string(value()); }
+ std::string str() const { return std::to_string(value()); }
size_type size() const { return 1; }
bool check() const { return true; }
void prepare() { }
@@ -2170,7 +2170,7 @@ class ConstNode : public Node
const VResult &result() const { return vresult; }
Result total() const { return vresult[0]; };
size_type size() const { return 1; }
- std::string str() const { return to_string(vresult[0]); }
+ std::string str() const { return std::to_string(vresult[0]); }
};
template <class T>
@@ -2200,7 +2200,7 @@ class ConstVectorNode : public Node
size_type size = this->size();
std::string tmp = "(";
for (off_type i = 0; i < size; i++)
- tmp += csprintf("%s ",to_string(vresult[i]));
+ tmp += csprintf("%s ", std::to_string(vresult[i]));
tmp += ")";
return tmp;
}
diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc
index 2c5b004be..efe43c602 100644
--- a/src/base/stats/text.cc
+++ b/src/base/stats/text.cc
@@ -284,7 +284,7 @@ VectorPrint::operator()(std::ostream &stream) const
// the case where there are no subnames) and append it to the
// base name.
if (forceSubnames)
- print.name = base + (havesub ? subnames[0] : to_string(0));
+ print.name = base + (havesub ? subnames[0] : std::to_string(0));
print.value = vec[0];
print(stream);
return;
@@ -300,7 +300,7 @@ VectorPrint::operator()(std::ostream &stream) const
if (havesub && (i >= subnames.size() || subnames[i].empty()))
continue;
- print.name = base + (havesub ? subnames[i] : to_string(i));
+ print.name = base + (havesub ? subnames[i] : std::to_string(i));
print.desc = subdescs.empty() ? desc : subdescs[i];
print.update(vec[i], _total);
@@ -355,7 +355,7 @@ DistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i)
init(text, info);
name = info.name + "_" +
- (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]);
+ (info.subnames[i].empty() ? (std::to_string(i)) : info.subnames[i]);
if (!info.subdescs[i].empty())
desc = info.subdescs[i];
@@ -605,7 +605,7 @@ Text::visit(const Vector2dInfo &info)
}
print.name = info.name + "_" +
- (havesub ? info.subnames[i] : to_string(i));
+ (havesub ? info.subnames[i] : std::to_string(i));
print.desc = info.desc;
print.vec = yvec;
print.total = total;
diff --git a/src/base/str.cc b/src/base/str.cc
index 45d3107b0..849bc8afa 100644
--- a/src/base/str.cc
+++ b/src/base/str.cc
@@ -28,14 +28,9 @@
* Authors: Nathan Binkert
*/
-#include <cctype>
-#include <cstring>
-#include <iostream>
-#include <limits>
#include <string>
#include <vector>
-#include "base/intmath.hh"
#include "base/str.hh"
using namespace std;
@@ -106,270 +101,3 @@ tokenize(vector<string>& v, const string &s, char token, bool ignore)
v.push_back(s.substr(first));
}
-
-/**
- * @todo This function will not handle the smallest negative decimal
- * value for a signed type
- */
-
-template <class T>
-inline bool
-__to_number(string value, T &retval)
-{
- static const T maxnum = ((T)-1);
- static const bool sign = numeric_limits<T>::is_signed;
- static const int bits = numeric_limits<T>::digits;
- static const T hexmax = maxnum & (((T)1 << (bits - 4)) - 1);
- static const T octmax = maxnum & (((T)1 << (bits - 3)) - 1);
- static const T signmax = numeric_limits<T>::max();
- static const T decmax = signmax / 10;
-
-#if 0
- cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n"
- << "sign = 0x" << hex << (unsigned long long)sign << "\n"
- << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n"
- << "octmax = 0x" << hex << (unsigned long long)octmax << "\n"
- << "signmax = 0x" << hex << (unsigned long long)signmax << "\n"
- << "decmax = 0x" << hex << (unsigned long long)decmax << "\n";
-#endif
-
- eat_white(value);
-
- bool negative = false;
- bool hex = false;
- bool oct = false;
- int last = value.size() - 1;
- retval = 0;
- int i = 0;
-
- char c = value[i];
- if (!isDec(c)) {
- if (c == '-' && sign)
- negative = true;
- else
- return false;
- }
- else {
- retval += c - '0';
- if (last == 0) return true;
- }
-
- if (c == '0')
- oct = true;
-
- c = value[++i];
- if (oct) {
- if (sign && negative)
- return false;
-
- if (!isOct(c)) {
- if (c == 'X' || c == 'x') {
- hex = true;
- oct = false;
- } else
- return false;
- }
- else
- retval += c - '0';
- } else if (!isDec(c))
- goto multiply;
- else {
- if (sign && negative && c == '0')
- return false;
-
- retval *= 10;
- retval += c - '0';
- if (last == 1) {
- if (sign && negative) retval = -retval;
- return true;
- }
- }
-
- if (hex) {
- if (last == 1)
- return false;
-
- for (i = 2; i <= last ; i++) {
- c = value[i];
- if (!isHex(c))
- return false;
-
- if (retval > hexmax) return false;
- retval *= 16;
- retval += hex2Int(c);
- }
- return true;
- } else if (oct) {
- for (i = 2; i <= last ; i++) {
- c = value[i];
- if (!isOct(c))
- return false;
-
- if (retval > octmax) return false;
- retval *= 8;
- retval += (c - '0');
- }
- return true;
- }
-
- for (i = 2; i < last ; i++) {
- c = value[i];
- if (!isDec(c))
- goto multiply;
-
- if (retval > decmax) return false;
- bool atmax = retval == decmax;
- retval *= 10;
- retval += c - '0';
- if (atmax && retval < decmax) return false;
- if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1))))
- return false;
- }
-
- c = value[last];
- if (isDec(c)) {
-
- if (retval > decmax) return false;
- bool atmax = retval == decmax;
- retval *= 10;
- retval += c - '0';
- if (atmax && retval < decmax) return false;
- if (sign && negative) {
- if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) &&
- retval >= (T)-signmax)
- return false;
- retval = -retval;
- }
- else
- if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1))))
- return false;
- return true;
- }
-
- multiply:
- signed long long mult = 1;
- T val;
- switch (c) {
- case 'k':
- case 'K':
- if (i != last) return false;
- mult = 1024;
- val = signmax / mult;
- break;
- case 'm':
- case 'M':
- if (i != last) return false;
- mult = 1024 * 1024;
- val = signmax / mult;
- break;
- case 'g':
- case 'G':
- if (i != last) return false;
- mult = 1024 * 1024 * 1024;
- val = signmax / mult;
- break;
- case 'e':
- case 'E':
- if (i >= last) return false;
-
- mult = 0;
- for (i++; i <= last; i++) {
- c = value[i];
- if (!isDec(c))
- return false;
-
- mult *= 10;
- mult += c - '0';
- }
-
- for (i = 0; i < mult; i++) {
- if (retval > signmax / 10)
- return false;
- retval *= 10;
- if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1))))
- return false;
- }
- if (sign && negative) {
- if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) &&
- retval >= (T)-signmax)
- return false;
- retval = -retval;
- }
- else
- if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1))))
- return false;
-
- return true;
-
- default:
- return false;
- }
-
- if (sign && negative)
- return false;
-
- if (mult > (unsigned long long)signmax)
- return false;
-
- if (retval > val)
- return false;
-
- retval *= mult;
-
- return true;
-}
-
-#define STN(type) \
-template<> \
-bool to_number<type>(const string &value, type &retval) \
-{ return __to_number(value, retval); }
-
-STN(unsigned long long)
-STN(signed long long)
-STN(unsigned long)
-STN(signed long)
-STN(unsigned int)
-STN(signed int)
-STN(unsigned short)
-STN(signed short)
-STN(unsigned char)
-STN(signed char)
-STN(char)
-
-template<>
-bool to_number<bool>(const string &value, bool &retval)
-{
- string lowered = to_lower(value);
-
- if (value == "0") {
- retval = false;
- return true;
- }
-
- if (value == "1"){
- retval = true;
- return true;
- }
-
- if (lowered == "false") {
- retval = false;
- return true;
- }
-
- if (lowered == "true"){
- retval = true;
- return true;
- }
-
- if (lowered == "no") {
- retval = false;
- return true;
- }
-
- if (lowered == "yes"){
- retval = true;
- return true;
- }
-
- return false;
-}
diff --git a/src/base/str.hh b/src/base/str.hh
index b3f3153ec..d73058bc0 100644
--- a/src/base/str.hh
+++ b/src/base/str.hh
@@ -29,31 +29,16 @@
* Steve Reinhardt
*/
-#ifndef __STR_HH__
-#define __STR_HH__
+#ifndef __BASE_STR_HH__
+#define __BASE_STR_HH__
-#include <cctype>
#include <cstring>
-#include <sstream>
+#include <limits>
+#include <locale>
+#include <stdexcept>
#include <string>
#include <vector>
-template<class> class Hash;
-template<>
-class Hash<std::string> {
-public:
- unsigned operator()(const std::string &s) {
- std::string::const_iterator i = s.begin();
- std::string::const_iterator end = s.end();
- unsigned hash = 5381;
-
- while (i < end)
- hash = ((hash << 5) + hash) + *i++;
-
- return hash;
- }
-};
-
inline void
eat_lead_white(std::string &s)
{
@@ -87,8 +72,8 @@ to_lower(const std::string &s)
lower.reserve(len);
- for (int i = 0; i < len; ++i)
- lower.push_back(tolower(s[i]));
+ for (const auto &c : s)
+ lower.push_back(std::tolower(c));
return lower;
}
@@ -111,16 +96,87 @@ void
tokenize(std::vector<std::string> &vector, const std::string &s,
char token, bool ign = true);
-template <class T> bool
-to_number(const std::string &value, T &retval);
+/**
+ * @{
+ *
+ * @name String to number helper functions for signed and unsigned
+ * integeral type, as well as floating-point types.
+ */
+template <class T>
+typename std::enable_if<std::is_integral<T>::value &&
+ std::is_signed<T>::value, T>::type
+__to_number(const std::string &value)
+{
+ // start big and narrow it down if needed, determine the base dynamically
+ long long r = std::stoll(value, nullptr, 0);
+ if (r < std::numeric_limits<T>::min() || r > std::numeric_limits<T>::max())
+ throw std::out_of_range("Out of range");
+ return static_cast<T>(r);
+}
+
+template <class T>
+typename std::enable_if<std::is_integral<T>::value &&
+ !std::is_signed<T>::value, T>::type
+__to_number(const std::string &value)
+{
+ // start big and narrow it down if needed, determine the base dynamically
+ unsigned long long r = std::stoull(value, nullptr, 0);
+ if (r > std::numeric_limits<T>::max())
+ throw std::out_of_range("Out of range");
+ return static_cast<T>(r);
+}
template <class T>
-inline std::string
-to_string(const T &value)
+typename std::enable_if<std::is_floating_point<T>::value, T>::type
+__to_number(const std::string &value)
{
- std::stringstream str;
- str << value;
- return str.str();
+ // start big and narrow it down if needed
+ long double r = std::stold(value);
+ if (r < std::numeric_limits<T>::min() || r > std::numeric_limits<T>::max())
+ throw std::out_of_range("Out of range");
+ return static_cast<T>(r);
+}
+/** @} */
+
+/**
+ * Turn a string representation of a number, either integral or
+ * floating point, into an actual number.
+ *
+ * @param value The string representing the number
+ * @param retval The resulting value
+ * @return True if the parsing was successful
+ */
+template <class T>
+inline bool
+to_number(const std::string &value, T &retval)
+{
+ try {
+ retval = __to_number<T>(value);
+ return true;
+ } catch (const std::out_of_range&) {
+ return false;
+ } catch (const std::invalid_argument&) {
+ return false;
+ }
+}
+
+/**
+ * Turn a string representation of a boolean into a boolean value.
+ */
+inline bool
+to_bool(const std::string &value, bool &retval)
+{
+ std::string s = to_lower(value);
+
+ if (s == "true") {
+ retval = true;
+ return true;
+ } else if (s == "false") {
+ retval = false;
+ return true;
+ }
+
+ return false;
}
// Put quotes around string arg if it contains spaces.
@@ -172,4 +228,4 @@ startswith(const std::string &s, const std::string &prefix)
}
-#endif //__STR_HH__
+#endif //__BASE_STR_HH__
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index b63a590fb..0be4f57c4 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -215,7 +215,7 @@ LSQUnit<Impl>::name() const
if (Impl::MaxThreads == 1) {
return iewStage->name() + ".lsq";
} else {
- return iewStage->name() + ".lsq.thread" + to_string(lsqID);
+ return iewStage->name() + ".lsq.thread" + std::to_string(lsqID);
}
}
diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc
index dfaf9088d..40ee7d38f 100644
--- a/src/dev/uart8250.cc
+++ b/src/dev/uart8250.cc
@@ -36,7 +36,6 @@
#include <vector>
#include "base/inifile.hh"
-#include "base/str.hh" // for to_number
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "debug/Uart.hh"
diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc
index 18af044d0..27bf87254 100644
--- a/src/sim/serialize.cc
+++ b/src/sim/serialize.cc
@@ -111,38 +111,25 @@ showParam(ostream &os, const unsigned char &value)
}
-// Use sscanf() for FP types as to_number() only handles integers
template <>
bool
parseParam(const string &s, float &value)
{
- return (sscanf(s.c_str(), "%f", &value) == 1);
+ return to_number(s, value);
}
template <>
bool
parseParam(const string &s, double &value)
{
- return (sscanf(s.c_str(), "%lf", &value) == 1);
+ return to_number(s, value);
}
template <>
bool
parseParam(const string &s, bool &value)
{
- const string &ls = to_lower(s);
-
- if (ls == "true") {
- value = true;
- return true;
- }
-
- if (ls == "false") {
- value = false;
- return true;
- }
-
- return false;
+ return to_bool(s, value);
}
// Display bools as strings