13#include "ll/api/base/Concepts.h"
14#include "ll/api/base/Macro.h"
15#include "ll/api/base/StdInt.h"
17#include "ll/api/Expected.h"
19namespace ll::inline utils::string_utils {
22template <std::invocable<std::
string_view> Fn>
23constexpr void splitByPattern(Fn&& fn, std::string_view s, std::string_view pattern,
bool keepEmpty =
false) {
24 if (s.empty())
return;
26 while ((pos = s.find(pattern)) != std::string::npos) {
27 if (keepEmpty || pos != 0) {
28 if (!std::invoke(std::forward<Fn>(fn), s.substr(0, pos)))
return;
30 s = s.substr(pos + pattern.size());
32 if (keepEmpty || !s.empty()) std::invoke(std::forward<Fn>(fn), s);
34template <concepts::IsString T>
35[[nodiscard]]
constexpr decltype(
auto) splitByPattern(T&& str, std::string_view pattern,
bool keepEmpty =
false) {
36 using ReturnTypeElement = std::conditional_t<std::is_same_v<T&&, std::string&&>, std::string, std::string_view>;
37 std::vector<ReturnTypeElement> ret;
39 [&](std::string_view sv) {
40 ret.push_back(ReturnTypeElement{sv});
57constexpr std::string& replaceAll(std::string& str, std::string_view oldValue, std::string_view newValue) {
58 for (std::string::size_type pos(0); pos != std::string::npos; pos += newValue.length()) {
59 if ((pos = str.find(oldValue, pos)) != std::string::npos) str.replace(pos, oldValue.length(), newValue);
65[[nodiscard]]
constexpr std::string
66replaceAll(std::string
const& str, std::string_view oldValue, std::string_view newValue) {
67 std::string ret = str;
68 replaceAll(ret, oldValue, newValue);
73replaceContent(std::string& str, std::string_view before, std::string_view after, std::string_view relplaceWith) {
74 auto startOffset = str.find(before);
75 if (startOffset == std::string::npos)
return false;
76 startOffset += before.size();
77 auto endOffset = after.empty() ? std::string::npos : str.find(after, startOffset);
78 str.replace(startOffset, endOffset - startOffset, relplaceWith);
82constexpr inline uchar digitFromByte[] = {
83 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
84 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
85 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10,
86 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
87 33, 34, 35, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
88 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 255, 255, 255, 255, 255, 255, 255, 255, 255,
89 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
91 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
92 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
93 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
94 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
96static_assert(
sizeof(digitFromByte) == 256);
98[[nodiscard]]
constexpr uchar digitFromChar(
char chr)
noexcept {
return digitFromByte[
static_cast<uchar
>(chr)]; }
100constexpr inline char charconvDigits[2][37] = {
101 "0123456789abcdefghijklmnopqrstuvwxyz",
102 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
105[[nodiscard]]
constexpr char charFromInt(
bool upper, uchar i) {
return charconvDigits[upper][i]; }
123 requires std::is_integral_v<T>
124[[nodiscard]]
constexpr std::string
125intToHexStr(T value,
bool upperCase =
true,
bool no0x =
true,
bool noLeadingZero =
true) {
127 if (value < 0) result +=
'-';
128 if (!no0x) result +=
"0x";
129 bool leadingZero =
true;
130 for (
int i =
sizeof(T) * 2; i > 0; --i) {
131 auto hex =
static_cast<uchar
>((value >> (i - 1) * 4) & 0xF);
132 if (noLeadingZero && leadingZero && hex == 0)
continue;
134 result += charFromInt(upperCase, hex);
139[[nodiscard]]
constexpr std::string strToHexStr(std::string_view value,
bool upperCase =
false,
bool addSpace =
false) {
141 hex.reserve(value.size() * (addSpace ? 3 : 2));
142 for (uchar x : value) {
143 hex += charFromInt(upperCase, x / 16);
144 hex += charFromInt(upperCase, x % 16);
145 if (addSpace) hex +=
' ';
147 if (addSpace && hex.ends_with(
' ')) hex.pop_back();
151LLNDAPI std::string removeEscapeCode(std::string_view str);
153LLNDAPI std::string replaceAnsiToMcCode(std::string_view str);
155LLNDAPI std::string replaceMcToAnsiCode(std::string_view str);
157LLNDAPI
bool isu8str(std::string_view str)
noexcept;
159LLNDAPI std::string tou8str(std::string_view str);
161LLNDAPI std::string toSnakeCase(std::string_view str);
163LLNDAPI std::string toLowerCase(std::string_view str);
175LLNDAPI std::wstring str2wstr(std::string_view str, uint codePage = CodePage::UTF8);
177LLNDAPI std::string wstr2str(std::wstring_view wstr, uint codePage = CodePage::UTF8);
180 str2str(std::string_view str, uint fromCodePage = CodePage::DefaultACP, uint toCodePage = CodePage::UTF8);
182[[nodiscard]]
inline std::string u8str2str(std::u8string str) {
183 std::string& tmp = *
reinterpret_cast<std::string*
>(&str);
184 return {std::move(tmp)};
187[[nodiscard]]
inline std::u8string str2u8str(std::string str) {
188 std::u8string& tmp = *
reinterpret_cast<std::u8string*
>(&str);
189 return {std::move(tmp)};
192[[nodiscard]]
inline std::string
const& u8str2strConst(std::u8string
const& str) {
193 return *
reinterpret_cast<std::string const*
>(&str);
196[[nodiscard]]
inline std::u8string
const& str2u8strConst(std::string
const& str) {
197 return *
reinterpret_cast<std::u8string const*
>(&str);
200[[nodiscard]]
inline std::string_view u8sv2sv(std::u8string_view str) {
201 return {
reinterpret_cast<char const*
>(str.data()), str.size()};
204[[nodiscard]]
inline std::u8string_view sv2u8sv(std::string_view str) {
205 return {
reinterpret_cast<char8_t const*
>(str.data()), str.size()};
208LLNDAPI Expected<bool> svtobool(std::string_view);
210template <
class T,
class... Args>
211[[nodiscard]] LL_CONSTEXPR23 Expected<T> svtonum(std::string_view str,
size_t* idx, Args&&... args) {
213 const auto ans = ::std::from_chars(&*str.begin(), &*str.end(), result, std::forward<Args>(args)...);
214 if (ans.ec != std::errc{}) {
215 return makeErrorCodeError(ans.ec);
218 *idx =
static_cast<size_t>(ans.ptr - &*str.begin());
222[[nodiscard]]
inline decltype(
auto) svtoc(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
223 return svtonum<schar>(str, idx, base);
225[[nodiscard]]
inline decltype(
auto) svtouc(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
226 return svtonum<uchar>(str, idx, base);
228[[nodiscard]]
inline decltype(
auto) svtos(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
229 return svtonum<short>(str, idx, base);
231[[nodiscard]]
inline decltype(
auto) svtous(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
232 return svtonum<ushort>(str, idx, base);
234[[nodiscard]]
inline decltype(
auto) svtoi(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
235 return svtonum<int>(str, idx, base);
237[[nodiscard]]
inline decltype(
auto) svtoui(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
238 return svtonum<uint>(str, idx, base);
240[[nodiscard]]
inline decltype(
auto) svtol(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
241 return svtonum<long>(str, idx, base);
243[[nodiscard]]
inline decltype(
auto) svtoul(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
244 return svtonum<ulong>(str, idx, base);
246[[nodiscard]]
inline decltype(
auto) svtoll(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
247 return svtonum<int64>(str, idx, base);
249[[nodiscard]]
inline decltype(
auto) svtoull(std::string_view str,
size_t* idx =
nullptr,
int base = 10) {
250 return svtonum<uint64>(str, idx, base);
252[[nodiscard]]
inline decltype(
auto)
253svtof(std::string_view str,
size_t* idx =
nullptr, std::chars_format format = std::chars_format::general) {
254 return svtonum<float>(str, idx, format);
256[[nodiscard]]
inline decltype(
auto)
257svtod(std::string_view str,
size_t* idx =
nullptr, std::chars_format format = std::chars_format::general) {
258 return svtonum<double>(str, idx, format);
260[[nodiscard]]
inline decltype(
auto)
261svtold(std::string_view str,
size_t* idx =
nullptr, std::chars_format format = std::chars_format::general) {
262 return svtonum<ldouble>(str, idx, format);