26 template<
typename StringType>
27 static void Trim(StringType& str) {
36 template<
typename StringType>
38 if (std::empty(str))
return;
39 str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](
const auto& c) {
40 return !std::isspace(c);
48 template<
typename StringType>
50 if (std::empty(str))
return;
51 str.erase(std::find_if(str.rbegin(), str.rend(), [](
const auto& c) {
52 return !std::isspace(c);
61 template<
typename StringType>
62 static void Lower(StringType& str) {
63 std::transform(str.begin(), str.end(), str.begin(), [](
const auto& c) {
64 return static_cast<typename StringType::value_type>(std::tolower(c));
72 template<
typename StringType>
74 StringType cstr = str;
75 std::transform(cstr.begin(), cstr.end(), cstr.begin(), [](
const auto& c) {
76 return static_cast<typename StringType::value_type>(std::tolower(c));
85 template<
typename StringType>
86 static void Upper(StringType& str) {
87 std::transform(str.begin(), str.end(), str.begin(), [](
const auto& c) {
88 return static_cast<typename StringType::value_type>(std::toupper(c));
96 template<
typename StringType>
98 StringType cstr = str;
99 std::transform(cstr.begin(), cstr.end(), cstr.begin(), [](
const auto& c) {
100 return static_cast<typename StringType::value_type>(std::toupper(c));
109 template<
typename StringType>
110 static bool StartsWith(
const StringType& str,
const StringType& prefix) {
111 return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0;
118 template<
typename StringType>
119 static bool EndsWith(
const StringType& str,
const StringType& suffix) {
120 return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
126 template<
typename StringType>
127 static std::vector<StringType>
Split(
const StringType& str,
const typename std::string::value_type delimiter) {
128 std::vector<StringType> parts{};
129 std::stringstream ss(str);
131 while (std::getline(ss, line, delimiter)) {
132 parts.push_back(line);
140 template<
typename StringType>
141 static bool Contains(
const StringType& str,
const StringType& other) {
142 return str.find(other) != StringType::npos;
150 using convert_type = std::codecvt_utf8<wchar_t>;
151 static std::wstring_convert<convert_type, wchar_t> converter;
152 return converter.from_bytes(str);
160 using convert_type = std::codecvt_utf8<wchar_t>;
161 static std::wstring_convert<convert_type, wchar_t> converter;
162 return converter.to_bytes(wstr);
169 template<
typename T,
typename StringType>
170 static T To(
const StringType& str) {
172 std::basic_stringstream<typename StringType::value_type> ss(str);
182 static std::string Cleanup(
const std::string& expr,
const std::string& remove)
184 const std::size_t
N = expr.size();
185 const std::size_t
K = remove.size();
186 std::string result(
N,
'\000');
187 std::size_t srcIndex = 0;
188 std::size_t dstIndex = 0;
191 std::size_t matchIndex = 0;
192 while (matchIndex <
K - 1 && srcIndex + matchIndex <
N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
195 if (matchIndex ==
K - 1)
196 srcIndex += matchIndex;
198 result[dstIndex++] = expr[srcIndex] ==
'"' ?
'\'' : expr[srcIndex];
201 result.resize(dstIndex,
'\000');
204 static std::wstring Cleanup(
const std::wstring& expr,
const std::wstring& remove)
206 const std::size_t
N = expr.size();
207 const std::size_t
K = remove.size();
208 std::wstring result(
N,
L'\000');
209 std::size_t srcIndex = 0;
210 std::size_t dstIndex = 0;
213 std::size_t matchIndex = 0;
214 while (matchIndex <
K - 1 && srcIndex + matchIndex <
N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
216 if (matchIndex ==
K - 1)
217 srcIndex += matchIndex;
218 result[dstIndex++] = expr[srcIndex] ==
'"' ?
'\'' : expr[srcIndex];
221 result.resize(dstIndex,
L'\000');
225 template <std::
size_t N>
230 template <std::
size_t N, std::
size_t K>
231 static auto Cleanup(
const char(&expr)[
N],
const char(&remove)[
K])
233 CleanupResult<N> result{};
234 std::size_t srcIndex = 0;
235 std::size_t dstIndex = 0;
239 std::size_t matchIndex = 0;
240 while (matchIndex <
K - 1 && srcIndex + matchIndex <
N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
242 if (matchIndex ==
K - 1)
243 srcIndex += matchIndex;
244 result.data[dstIndex++] = expr[srcIndex] ==
'"' ?
'\'' : expr[srcIndex];