#ifndef __GOSTRINGS_HPP__ #define __GOSTRINGS_HPP__ #include #include 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(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 Fields(const std::string &s) { std::vector 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 FieldsFunc(const std::string &s, bool (*f)(char)) { std::vector 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 &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 Split(const std::string &s, const std::string &sep) { std::vector 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 SplitAfter(const std::string &s, const std::string &sep) { std::vector 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 SplitAfterN(const std::string &s, const std::string &sep, int n) { std::vector 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 SplitN(const std::string &s, const std::string &sep, int n) { std::vector 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(tolower(static_cast(c))); } return result; } inline std::string ToUpper(const std::string &s) { std::string result = s; for (char &c : result) { c = static_cast(toupper(static_cast(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__