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:
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user