2017-04-18 18:11:25 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cctype>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include <iterator>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2017-04-24 22:01:00 +08:00
|
|
|
#include "utils/exceptions.hpp"
|
|
|
|
|
2017-04-18 18:11:25 +08:00
|
|
|
namespace utils {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes whitespace characters from the start and from the end of a string.
|
|
|
|
*
|
|
|
|
* @param str string that is going to be trimmed
|
|
|
|
*
|
|
|
|
* @return trimmed string
|
|
|
|
*/
|
2017-04-24 22:01:00 +08:00
|
|
|
inline std::string Trim(const std::string& s) {
|
2017-04-18 18:11:25 +08:00
|
|
|
auto begin = s.begin();
|
|
|
|
auto end = s.end();
|
|
|
|
if (begin == end) {
|
|
|
|
// Need to check this to be sure that prev(end) exists.
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
while (begin != end && isspace(*begin)) {
|
|
|
|
++begin;
|
|
|
|
}
|
|
|
|
while (prev(end) != begin && isspace(*prev(end))) {
|
|
|
|
--end;
|
|
|
|
}
|
|
|
|
return std::string(begin, end);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return string with all lowercased characters (locale independent).
|
|
|
|
*/
|
2017-04-24 22:01:00 +08:00
|
|
|
inline std::string ToLowerCase(std::string s) {
|
2017-04-18 18:11:25 +08:00
|
|
|
std::transform(s.begin(), s.end(), s.begin(),
|
|
|
|
[](char c) { return tolower(c); });
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return string with all uppercased characters (locale independent).
|
|
|
|
*/
|
2017-04-24 22:01:00 +08:00
|
|
|
inline std::string ToUpperCase(std::string s) {
|
2017-04-18 18:11:25 +08:00
|
|
|
std::string s2(s.size(), ' ');
|
|
|
|
std::transform(s.begin(), s.end(), s.begin(),
|
|
|
|
[](char c) { return toupper(c); });
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Join strings in vector separated by a given separator.
|
|
|
|
*/
|
2017-04-24 22:01:00 +08:00
|
|
|
inline std::string Join(const std::vector<std::string>& strings,
|
|
|
|
const char* separator) {
|
2017-04-18 18:11:25 +08:00
|
|
|
std::ostringstream oss;
|
|
|
|
std::copy(strings.begin(), strings.end(),
|
|
|
|
std::ostream_iterator<std::string>(oss, separator));
|
|
|
|
return oss.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Replaces all occurences of <match> in <src> with <replacement>.
|
|
|
|
*/
|
|
|
|
// TODO: This could be implemented much more efficient.
|
2017-04-24 22:01:00 +08:00
|
|
|
inline std::string Replace(std::string src, const std::string& match,
|
|
|
|
const std::string& replacement) {
|
2017-04-18 18:11:25 +08:00
|
|
|
for (size_t pos = src.find(match); pos != std::string::npos;
|
|
|
|
pos = src.find(match, pos + replacement.size())) {
|
|
|
|
src.erase(pos, match.length()).insert(pos, replacement);
|
|
|
|
}
|
|
|
|
return src;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Split string by delimeter and return vector of results.
|
|
|
|
*/
|
2017-04-24 22:01:00 +08:00
|
|
|
inline std::vector<std::string> Split(const std::string& src,
|
|
|
|
const std::string& delimiter) {
|
2017-04-18 18:11:25 +08:00
|
|
|
size_t index = 0;
|
|
|
|
std::vector<std::string> res;
|
|
|
|
size_t n = src.find(delimiter, index);
|
|
|
|
while (n != std::string::npos) {
|
|
|
|
n = src.find(delimiter, index);
|
|
|
|
res.push_back(src.substr(index, n - index));
|
|
|
|
index = n + delimiter.size();
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2017-04-24 22:01:00 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse double using classic locale, throws BasicException if it wasn't able to
|
|
|
|
* parse whole string.
|
|
|
|
*/
|
|
|
|
inline double ParseDouble(const std::string& s) {
|
|
|
|
// stod would be nicer but it uses current locale so we shouldn't use it.
|
2017-05-17 20:30:12 +08:00
|
|
|
double t = 0.0;
|
2017-04-24 22:01:00 +08:00
|
|
|
std::istringstream iss(s);
|
|
|
|
iss.imbue(std::locale::classic());
|
|
|
|
iss >> t;
|
2017-05-17 20:30:12 +08:00
|
|
|
if (iss.fail() || !iss.eof()) {
|
2017-04-24 22:01:00 +08:00
|
|
|
throw BasicException("Couldn't parse string");
|
|
|
|
}
|
|
|
|
return t;
|
|
|
|
}
|
2017-04-18 18:11:25 +08:00
|
|
|
}
|