32,33c32,33
< #ifndef __STR_HH__
< #define __STR_HH__
---
> #ifndef __BASE_STR_HH__
> #define __BASE_STR_HH__
35d34
< #include <cctype>
37c36,38
< #include <sstream>
---
> #include <limits>
> #include <locale>
> #include <stdexcept>
41,56d41
< 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;
< }
< };
<
90,91c75,76
< for (int i = 0; i < len; ++i)
< lower.push_back(tolower(s[i]));
---
> for (const auto &c : s)
> lower.push_back(std::tolower(c));
114,115c99,115
< 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);
> }
118,119c118,120
< 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)
121,123c122,126
< 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);
125a129,181
> 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;
> }
>
175c231
< #endif //__STR_HH__
---
> #endif //__BASE_STR_HH__