From 0fa128bbd0a53a3428fa2028b8754e15c9ef7c38 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Sat, 20 Sep 2014 17:17:49 -0400 Subject: 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. --- src/base/str.hh | 116 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 30 deletions(-) (limited to 'src/base/str.hh') 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 #include -#include +#include +#include +#include #include #include -template class Hash; -template<> -class Hash { -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 &vector, const std::string &s, char token, bool ign = true); -template 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 +typename std::enable_if::value && + std::is_signed::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::min() || r > std::numeric_limits::max()) + throw std::out_of_range("Out of range"); + return static_cast(r); +} + +template +typename std::enable_if::value && + !std::is_signed::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::max()) + throw std::out_of_range("Out of range"); + return static_cast(r); +} template -inline std::string -to_string(const T &value) +typename std::enable_if::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::min() || r > std::numeric_limits::max()) + throw std::out_of_range("Out of range"); + return static_cast(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 +inline bool +to_number(const std::string &value, T &retval) +{ + try { + retval = __to_number(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__ -- cgit v1.2.3