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.
This commit is contained in:
parent
b2c2e67468
commit
0fa128bbd0
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
272
src/base/str.cc
272
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;
|
||||
}
|
||||
|
|
116
src/base/str.hh
116
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>
|
||||
inline std::string
|
||||
to_string(const T &value)
|
||||
typename std::enable_if<std::is_integral<T>::value &&
|
||||
!std::is_signed<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, 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>
|
||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||
__to_number(const std::string &value)
|
||||
{
|
||||
// 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__
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue