2 #ifndef ENIGMA_STRING_UTILS_H
3 #define ENIGMA_STRING_UTILS_H
26 template<
typename StringType>
27 static void Trim(StringType& str) {
36 template<
typename StringType>
38 str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](
const auto& c) {
39 return !std::isspace(c);
47 template<
typename StringType>
49 str.erase(std::find_if(str.rbegin(), str.rend(), [](
const auto& c) {
50 return !std::isspace(c);
59 template<
typename StringType>
60 static void Lower(StringType& str) {
61 std::transform(str.begin(), str.end(), str.begin(), [](
const auto& c) {
62 return static_cast<typename StringType::value_type>(std::tolower(c));
70 template<
typename StringType>
72 StringType cstr = str;
73 std::transform(cstr.begin(), cstr.end(), cstr.begin(), [](
const auto& c) {
74 return static_cast<typename StringType::value_type>(std::tolower(c));
83 template<
typename StringType>
84 static void Upper(StringType& str) {
85 std::transform(str.begin(), str.end(), str.begin(), [](
const auto& c) {
86 return static_cast<typename StringType::value_type>(std::toupper(c));
94 template<
typename StringType>
96 StringType cstr = str;
97 std::transform(cstr.begin(), cstr.end(), cstr.begin(), [](
const auto& c) {
98 return static_cast<typename StringType::value_type>(std::toupper(c));
107 template<
typename StringType>
108 static bool StartsWith(
const StringType& str,
const StringType& prefix) {
109 return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0;
116 template<
typename StringType>
117 static bool EndsWith(
const StringType& str,
const StringType& suffix) {
118 return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
124 template<
typename StringType>
125 static std::vector<StringType>
Split(
const StringType& str,
const typename std::string::value_type delimiter) {
126 std::vector<StringType> parts{};
127 std::stringstream ss(str);
129 while (std::getline(ss, line, delimiter)) {
130 parts.push_back(line);
138 template<
typename StringType>
139 static bool Contains(
const StringType& str,
const StringType& other) {
140 return str.find(other) != StringType::npos;
148 using convert_type = std::codecvt_utf8<wchar_t>;
149 static std::wstring_convert<convert_type, wchar_t> converter;
150 return converter.from_bytes(str);
158 using convert_type = std::codecvt_utf8<wchar_t>;
159 static std::wstring_convert<convert_type, wchar_t> converter;
160 return converter.to_bytes(wstr);
167 template<
typename T,
typename StringType>
168 static T To(
const StringType& str) {
170 std::basic_stringstream<typename StringType::value_type> ss(str);
180 static std::string Cleanup(
const std::string& expr,
const std::string& remove)
182 const std::size_t
N = expr.size();
183 const std::size_t
K = remove.size();
184 std::string result(
N,
'\000');
185 std::size_t srcIndex = 0;
186 std::size_t dstIndex = 0;
189 std::size_t matchIndex = 0;
190 while (matchIndex <
K - 1 && srcIndex + matchIndex <
N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
193 if (matchIndex ==
K - 1)
194 srcIndex += matchIndex;
196 result[dstIndex++] = expr[srcIndex] ==
'"' ?
'\'' : expr[srcIndex];
199 result.resize(dstIndex,
'\000');
202 static std::wstring Cleanup(
const std::wstring& expr,
const std::wstring& remove)
204 const std::size_t
N = expr.size();
205 const std::size_t
K = remove.size();
206 std::wstring result(
N,
L'\000');
207 std::size_t srcIndex = 0;
208 std::size_t dstIndex = 0;
211 std::size_t matchIndex = 0;
212 while (matchIndex <
K - 1 && srcIndex + matchIndex <
N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
214 if (matchIndex ==
K - 1)
215 srcIndex += matchIndex;
216 result[dstIndex++] = expr[srcIndex] ==
'"' ?
'\'' : expr[srcIndex];
219 result.resize(dstIndex,
L'\000');
223 template <std::
size_t N>
228 template <std::
size_t N, std::
size_t K>
229 static auto Cleanup(
const char(&expr)[
N],
const char(&remove)[
K])
231 CleanupResult<N> result{};
232 std::size_t srcIndex = 0;
233 std::size_t dstIndex = 0;
237 std::size_t matchIndex = 0;
238 while (matchIndex <
K - 1 && srcIndex + matchIndex <
N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
240 if (matchIndex ==
K - 1)
241 srcIndex += matchIndex;
242 result.data[dstIndex++] = expr[srcIndex] ==
'"' ?
'\'' : expr[srcIndex];
#define NS_ENIGMA_BEGIN
Enable/Disable Assertions.
static std::vector< StringType > Split(const StringType &str, const typename std::string::value_type delimiter)
static T To(const StringType &str)
static void Upper(StringType &str)
static std::wstring StringToWString(const std::string &str)
static auto LowerCopy(const StringType &str)
static void Lower(StringType &str)
static auto UpperCopy(const StringType &str)
static std::string WStringToString(const std::wstring &wstr)
static void Trim(StringType &str)
static bool Contains(const StringType &str, const StringType &other)
static void TrimRight(StringType &str)
static bool EndsWith(const StringType &str, const StringType &suffix)
static void TrimLeft(StringType &str)
static bool StartsWith(const StringType &str, const StringType &prefix)