13std::mt19937& getRandomGenerator() {
14 static std::random_device random_device{};
15 static std::mt19937 generator{random_device()};
24 return c ==
'\r' || c ==
'\n';
28 return std::ranges::all_of(str, [](
char c) {
return isNewLine(c); });
32 return std::isspace(c, std::locale::classic());
36 return std::ranges::all_of(str, [](
char c) {
return isWhitespace(c); });
40 return std::isdigit(c, std::locale::classic());
44 return std::ranges::all_of(str, [](
char c) {
return isNumber(c); });
48 return std::isalnum(c, std::locale::classic());
52 return std::ranges::all_of(str, [](
char c) {
return isAlphaNumeric(c); });
56 return std::ranges::find(s, c) != s.end();
59bool string::matches(std::string_view in, std::string_view search,
bool ignoreCase) {
60 int inPos = 0, searchPos = 0;
61 for ( ; inPos < in.length() && searchPos < search.length(); inPos++, searchPos++) {
62 if (search[searchPos] ==
'%') {
63 if (++searchPos == search.length()) {
66 switch (search[searchPos]) {
71 if (!std::isspace(in[inPos]))
return false;
74 if (!(in[inPos] >=
'a' && in[inPos] <=
'z' || in[inPos] >=
'A' && in[inPos] <=
'Z'))
return false;
77 if (!(in[inPos] >=
'A' && in[inPos] <=
'Z'))
return false;
80 if (!(in[inPos] >=
'a' && in[inPos] <=
'z'))
return false;
83 if (!std::isdigit(in[inPos]))
return false;
86 if (in[inPos] !=
'%')
return false;
89 }
else if ((!ignoreCase && in[inPos] != search[searchPos]) || (ignoreCase && std::tolower(in[inPos]) != std::tolower(search[searchPos]))) {
93 return inPos == in.length() && searchPos == search.length();
97 return std::ranges::equal(s1, s2, [](
char a,
char b) {
return std::tolower(a) == std::tolower(b); });
103 s.erase(s.begin(), std::ranges::find_if(s, [](
char c) { return !std::isspace(c); }));
107 while (!s.empty() && std::isspace(s[0])) {
114 s.erase(std::find_if(s.rbegin(), s.rend(), [](
char c) { return !std::isspace(c); }).base(), s.end());
118 while (!s.empty() && std::isspace(s[s.size() - 1])) {
134 s.erase(std::ranges::unique(s, [](
char lhs,
char rhs) {
return lhs == rhs && std::isspace(lhs); }).begin(), s.end());
144 s.erase(s.begin(), std::ranges::find_if(s, [chars](
char c) {
145 return !contains(chars, c);
150 while (!s.empty() &&
contains(chars, s[0])) {
157 s.erase(std::find_if(s.rbegin(), s.rend(), [chars](
char c) {
158 return !contains(chars, c);
163 while (!s.empty() &&
contains(chars, s[s.size() - 1])) {
174std::string_view
string::trim(std::string_view s, std::string_view chars) {
179 s.erase(std::ranges::unique(s, [chars](
char lhs,
char rhs) {
return lhs == rhs && std::ranges::find(chars, lhs) != chars.end(); }).begin(), s.end());
191 std::vector<std::string> result;
192 std::stringstream ss(std::string{s});
194 while (std::getline(ss, item, delim)) {
195 result.push_back(item);
201 std::ranges::transform(input, input.begin(), [](
unsigned char c){ return std::tolower(c); });
205 std::string out{input};
211 std::ranges::transform(input, input.begin(), [](
unsigned char c){ return std::toupper(c); });
215 std::string out{input};
221 auto& generator = ::getRandomGenerator();
222 std::uniform_int_distribution distribution{0,
static_cast<int>(chars.length() - 1)};
225 for (uint16_t i = 0; i < length; i++) {
226 out += chars[distribution(generator)];
233 static constexpr std::string_view chars =
"0123456789abcdef";
235 auto& generator = ::getRandomGenerator();
236 std::uniform_int_distribution distribution{0,
static_cast<int>(chars.length() - 1)};
239 for (uint16_t i = 0; i < 8; i++) {
240 out += chars[distribution(generator)];
243 for (uint16_t i = 0; i < 3; i++) {
244 for (uint16_t j = 0; j < 4; j++) {
245 out += chars[distribution(generator)];
249 for (uint16_t i = 0; i < 12; i++) {
250 out += chars[distribution(generator)];
257 return std::format(
"{:0>{}}", number, width);
261 std::ranges::replace(path,
'\\',
'/');
262 if (stripSlashPrefix && path.starts_with(
'/')) {
263 path = path.substr(1);
265 if (stripSlashSuffix && path.ends_with(
'/')) {
271 std::ranges::replace(path,
'/',
'\\');
272 if (stripSlashPrefix && path.starts_with(
'\\')) {
273 path = path.substr(1);
275 if (stripSlashSuffix && path.ends_with(
'\\')) {
282 const auto [ptr, err] = std::from_chars(number.data(), number.data() + number.size(), tmp, base);
284 return ptr == number.data() + number.size() && err == std::errc{};
289 return toBool(number, tmp, base);
293 static constexpr auto hexChar2Int = [](
char c) -> uint8_t {
294 if (c >=
'0' && c <=
'9') {
297 if (c >=
'a' && c <=
'f') {
300 if (c >=
'A' && c <=
'F') {
306 const bool remainder = hex.size() % 2;
308 std::vector<std::byte> hexData;
309 hexData.reserve(hex.size() / 2 + remainder);
311 hexData.push_back(
static_cast<std::byte
>(hexChar2Int(hex.front())));
313 for (
int i = remainder; i < hex.length(); i += 2) {
314 hexData.push_back(
static_cast<std::byte
>(hexChar2Int(hex[i]) << 4 | hexChar2Int(hex[i + 1])));
321 hexStr.reserve(hex.size() * 2);
322 for (
const auto byte : hex) {
323 hexStr.append(std::format(
"{:02x}",
static_cast<int>(
byte)));
std::string createRandom(uint16_t length=32, std::string_view chars="0123456789_abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ")
std::string padNumber(int64_t number, int width)
std::vector< std::byte > decodeHex(std::string_view hex)
bool contains(std::string_view s, char c)
void normalizeSlashes(std::string &path, bool stripSlashPrefix=false, bool stripSlashSuffix=true)
bool isWhitespace(char c)
If a char is a whitespace character.
bool matches(std::string_view in, std::string_view search, bool ignoreCase=false)
A very basic regex-like pattern checker for ASCII strings.
void ltrim(std::string &s)
bool isNewLine(char c)
If a char is a newline character.
bool toBool(std::string_view number, bool &out, int base=10)
std::vector< std::string > split(std::string_view s, char delim)
void denormalizeSlashes(std::string &path, bool stripSlashPrefix=false, bool stripSlashSuffix=true)
void trimInternal(std::string &s)
bool isBool(std::string_view number, int base=10)
bool isNumber(char c)
If a char is a numerical character (0-9).
void rtrim(std::string &s)
void toUpper(std::string &input)
void trim(std::string &s)
bool iequals(std::string_view s1, std::string_view s2)
void toLower(std::string &input)
std::string generateUUIDv4()
std::string encodeHex(std::span< const std::byte > hex)
bool isAlphaNumeric(char c)
If a char is a letter (a-z, A-Z) or a numerical character (0-9).