gostrings/gostrings.hpp

347 lines
9.5 KiB
C++
Raw Normal View History

2025-11-30 17:56:18 -05:00
#ifndef __GOSTRINGS_HPP__
#define __GOSTRINGS_HPP__
#include <string>
#include <vector>
namespace gostrings {
inline int Compare(const std::string &a, const std::string &b) {
if (a == b) return 0;
return (a < b) ? -1 : 1;
}
inline bool Contains(const std::string &s, const std::string &substr) {
return s.find(substr) != std::string::npos;
}
inline bool ContainsAny(const std::string &s, const std::string &chars) {
return s.find_first_of(chars) != std::string::npos;
}
inline bool ContainsFunc(const std::string &s, bool (*f)(char)) {
for (char c : s) {
if (f(c)) {
return true;
}
}
return false;
}
inline int Count(const std::string &s, const std::string &substr) {
if (substr.empty()) {
return static_cast<int>(s.size()) + 1;
}
int count = 0;
size_t pos = 0;
while ((pos = s.find(substr, pos)) != std::string::npos) {
++count;
pos += substr.length();
}
return count;
}
struct CutPrefixResult {
std::string after;
bool found;
};
struct CutSuffixResult {
std::string before;
bool found;
};
struct CutResult {
CutPrefixResult prefix;
CutSuffixResult suffix;
inline bool found() const {
return prefix.found && suffix.found;
}
};
inline CutResult Cut(const std::string &s, const std::string &sep) {
size_t pos = s.find(sep);
if (pos == std::string::npos) {
return {{"", false}, {"", false}};
}
return { {s.substr(pos + sep.length()), true}, {s.substr(0, pos), true} };
}
inline CutPrefixResult CutPrefix(const std::string &s, const std::string &prefix) {
if (s.substr(0, prefix.length()) == prefix) {
return {s.substr(prefix.length()), true};
}
return {"", false};
}
inline CutSuffixResult CutSuffix(const std::string &s, const std::string &suffix) {
if (s.length() >= suffix.length() &&
s.substr(s.length() - suffix.length()) == suffix) {
return {s.substr(0, s.length() - suffix.length()), true};
}
return {"", false};
}
inline std::vector<std::string> Fields(const std::string &s) {
std::vector<std::string> result;
size_t start = s.find_first_not_of(" \t\n\r\f\v");
while (start != std::string::npos) {
size_t end = s.find_first_of(" \t\n\r\f\v", start);
result.push_back(s.substr(start, end - start));
start = s.find_first_not_of(" \t\n\r\f\v", end);
}
return result;
}
inline std::vector<std::string> FieldsFunc(const std::string &s, bool (*f)(char)) {
std::vector<std::string> result;
size_t start = 0;
while (start < s.length()) {
while (start < s.length() && f(s[start])) {
++start;
}
if (start >= s.length()) break;
size_t end = start;
while (end < s.length() && !f(s[end])) {
++end;
}
result.push_back(s.substr(start, end - start));
start = end;
}
return result;
}
inline bool HasPrefix(const std::string &s, const std::string &prefix) {
return s.substr(0, prefix.length()) == prefix;
}
inline bool HasSuffix(const std::string &s, const std::string &suffix) {
return s.length() >= suffix.length() &&
s.substr(s.length() - suffix.length()) == suffix;
}
inline size_t Index(const std::string &s, const std::string &substr) {
size_t pos = s.find(substr);
return (pos == std::string::npos) ? -1 : pos;
}
inline size_t IndexAny(const std::string &s, const std::string &chars) {
size_t pos = s.find_first_of(chars);
return (pos == std::string::npos) ? -1 : pos;
}
inline size_t IndexByte(const std::string &s, char c) {
size_t pos = s.find(c);
return (pos == std::string::npos) ? -1 : pos;
}
inline size_t IndexFunc(const std::string &s, bool (*f)(char)) {
for (size_t i = 0; i < s.length(); ++i) {
if (f(s[i])) {
return i;
}
}
return -1;
}
inline std::string Join(const std::vector<std::string> &elems, const std::string &sep) {
std::string result;
for (size_t i = 0; i < elems.size(); ++i) {
result += elems[i];
if (i < elems.size() - 1) {
result += sep;
}
}
return result;
}
inline size_t LastIndex(const std::string &s, const std::string &substr) {
size_t pos = s.rfind(substr);
return (pos == std::string::npos) ? -1 : pos;
}
inline size_t LastIndexAny(const std::string &s, const std::string &chars) {
size_t pos = s.find_last_of(chars);
return (pos == std::string::npos) ? -1 : pos;
}
inline size_t LastIndexByte(const std::string &s, char c) {
size_t pos = s.rfind(c);
return (pos == std::string::npos) ? -1 : pos;
}
inline size_t LastIndexFunc(const std::string &s, bool (*f)(char)) {
for (size_t i = s.length(); i-- > 0;) {
if (f(s[i])) {
return i;
}
}
return -1;
}
inline std::string Repeat(const std::string &s, int count) {
if (count <= 0) return "";
std::string result;
for (int i = 0; i < count; ++i) {
result += s;
}
return result;
}
inline std::string Replace(const std::string &s, const std::string &old, const std::string &newstr, int n) {
std::string result = s;
size_t pos = 0;
int count = 0;
while ((pos = result.find(old, pos)) != std::string::npos) {
if (n != -1 && count >= n) break;
result.replace(pos, old.length(), newstr);
pos += newstr.length();
++count;
}
return result;
}
inline std::string ReplaceAll(const std::string &s, const std::string &old, const std::string &newstr) {
return Replace(s, old, newstr, -1);
}
inline std::vector<std::string> Split(const std::string &s, const std::string &sep) {
std::vector<std::string> result;
size_t start = 0;
size_t end;
while ((end = s.find(sep, start)) != std::string::npos) {
result.push_back(s.substr(start, end - start));
start = end + sep.length();
}
result.push_back(s.substr(start));
return result;
}
inline std::vector<std::string> SplitAfter(const std::string &s, const std::string &sep) {
std::vector<std::string> result;
size_t start = 0;
size_t end;
while ((end = s.find(sep, start)) != std::string::npos) {
result.push_back(s.substr(start, end + sep.length() - start));
start = end + sep.length();
}
result.push_back(s.substr(start));
return result;
}
inline std::vector<std::string> SplitAfterN(const std::string &s, const std::string &sep, int n) {
std::vector<std::string> result;
size_t start = 0;
size_t end;
int count = 0;
while (count < n - 1 && (end = s.find(sep, start)) != std::string::npos) {
result.push_back(s.substr(start, end + sep.length() - start));
start = end + sep.length();
++count;
}
result.push_back(s.substr(start));
return result;
}
inline std::vector<std::string> SplitN(const std::string &s, const std::string &sep, int n) {
std::vector<std::string> result;
size_t start = 0;
size_t end;
int count = 0;
while (count < n - 1 && (end = s.find(sep, start)) != std::string::npos) {
result.push_back(s.substr(start, end - start));
start = end + sep.length();
++count;
}
result.push_back(s.substr(start));
return result;
}
inline std::string ToLower(const std::string &s) {
std::string result = s;
for (char &c : result) {
c = static_cast<char>(tolower(static_cast<unsigned char>(c)));
}
return result;
}
inline std::string ToUpper(const std::string &s) {
std::string result = s;
for (char &c : result) {
c = static_cast<char>(toupper(static_cast<unsigned char>(c)));
}
return result;
}
inline std::string Trim(const std::string &s, const std::string &cutset) {
size_t start = s.find_first_not_of(cutset);
if (start == std::string::npos) return "";
size_t end = s.find_last_not_of(cutset);
return s.substr(start, end - start + 1);
}
inline std::string TrimFunc(const std::string &s, bool (*f)(char)) {
size_t start = 0;
while (start < s.length() && f(s[start])) {
++start;
}
if (start == s.length()) return "";
size_t end = s.length() - 1;
while (end > start && f(s[end])) {
--end;
}
return s.substr(start, end - start + 1);
}
inline std::string TrimLeft(const std::string &s, const std::string &cutset) {
size_t start = s.find_first_not_of(cutset);
if (start == std::string::npos) return "";
return s.substr(start);
}
inline std::string TrimLeftFunc(const std::string &s, bool (*f)(char)) {
size_t start = 0;
while (start < s.length() && f(s[start])) {
++start;
}
return s.substr(start);
}
inline std::string TrimPrefix(const std::string &s, const std::string &prefix) {
if (s.substr(0, prefix.length()) == prefix) {
return s.substr(prefix.length());
}
return s;
}
inline std::string TrimRight(const std::string &s, const std::string &cutset) {
size_t end = s.find_last_not_of(cutset);
if (end == std::string::npos) return "";
return s.substr(0, end + 1);
}
inline std::string TrimRightFunc(const std::string &s, bool (*f)(char)) {
size_t end = s.length();
while (end > 0 && f(s[end - 1])) {
--end;
}
return s.substr(0, end);
}
inline std::string TrimSpace(const std::string &s) {
return Trim(s, " \t\n\r\f\v");
}
inline std::string TrimSuffix(const std::string &s, const std::string &suffix) {
if (s.length() >= suffix.length() &&
s.substr(s.length() - suffix.length()) == suffix) {
return s.substr(0, s.length() - suffix.length());
}
return s;
}
} // namespace gostrings
#endif // __GOSTRINGS_HPP__