15 #include <string_view>
16 #include <type_traits>
18 #if defined(__APPLE__)
19 #include <CoreFoundation/CoreFoundation.h>
43 template<
typename T> [[nodiscard]] std::optional<T>
stringTo(std::string_view s);
48 template<
int BASE,
typename T> [[nodiscard]] std::optional<T>
stringToBase(std::string_view s);
54 void trimRight(std::string& str,
const char* chars);
55 void trimRight(std::string& str,
char chars);
56 void trimRight(std::string_view& str, std::string_view chars);
57 void trimRight(std::string_view& str,
char chars);
58 void trimLeft (std::string& str,
const char* chars);
59 void trimLeft (std::string& str,
char chars);
60 void trimLeft (std::string_view& str, std::string_view chars);
61 void trimLeft (std::string_view& str,
char chars);
62 void trim (std::string_view& str, std::string_view chars);
63 void trim (std::string_view& str,
char chars);
65 [[nodiscard]] std::pair<std::string_view, std::string_view>
splitOnFirst(
66 std::string_view str, std::string_view chars);
67 [[nodiscard]] std::pair<std::string_view, std::string_view>
splitOnFirst(
68 std::string_view str,
char chars);
69 [[nodiscard]] std::pair<std::string_view, std::string_view>
splitOnLast(
70 std::string_view str, std::string_view chars);
71 [[nodiscard]] std::pair<std::string_view, std::string_view>
splitOnLast(
72 std::string_view str,
char chars);
74 unsigned min,
unsigned max);
78 [[nodiscard]]
inline auto split_view(std::string_view str,
char c) {
83 std::string_view::size_type p;
86 Iterator(std::string_view str_,
char c_)
91 [[nodiscard]] std::string_view
operator*()
const {
92 return std::string_view(str.data(), p);
95 Iterator& operator++() {
97 str.remove_prefix(p + 1);
105 [[nodiscard]]
bool operator==(Sentinel)
const {
return str.empty(); }
106 [[nodiscard]]
bool operator!=(Sentinel)
const {
return !str.empty(); }
110 while ((p < str.size()) && (str[p] != c)) ++p;
115 std::string_view str;
118 [[nodiscard]]
auto begin()
const {
return Iterator{str, c}; }
119 [[nodiscard]]
auto end()
const {
return Sentinel{}; }
122 return Splitter{str, c};
127 [[nodiscard]]
bool operator()(std::string_view s1, std::string_view s2)
const {
128 auto m =
std::min(s1.size(), s2.size());
129 int r = strncasecmp(s1.data(), s2.data(), m);
130 return (r != 0) ? (r < 0) : (s1.size() < s2.size());
134 [[nodiscard]]
bool operator()(std::string_view s1, std::string_view s2)
const {
135 if (s1.size() != s2.size())
return false;
136 return strncasecmp(s1.data(), s2.data(), s1.size()) == 0;
140 #if defined(__APPLE__)
141 [[nodiscard]] std::string fromCFString(CFStringRef str);
144 template<
int BASE,
typename T>
149 auto e = s.data() + s.size();
150 if (
auto [p, ec] = std::from_chars(b, e, result, BASE);
151 (ec == std::errc()) && (p == e)) {
158 [[nodiscard]] std::optional<T>
stringTo(std::string_view s)
161 if constexpr (std::is_signed_v<T>) {
168 using U = std::make_unsigned_t<T>;
169 auto tmp = stringTo<U>(s);
181 if (
likely(s[0] !=
'0')) {
182 return stringToBase<10, T>(s);
184 if (s.size() == 1)
return T(0);
185 if (
likely((s[1] ==
'x') || (s[1] ==
'X'))) {
187 return stringToBase<16, T>(s);
188 }
else if ((s[1] ==
'b') || (s[1] ==
'B')) {
190 return stringToBase<2, T>(s);
192 return stringToBase<10, T>(s);
void trim(string_view &str, string_view chars)
IterableBitSet< 64 > parseRange(string_view str, unsigned min, unsigned max)
bool stringToBool(string_view str)
std::optional< T > stringToBase(std::string_view s)
As above, but without dynamic base detection.
std::pair< string_view, string_view > splitOnLast(string_view str, string_view chars)
void trimRight(string &str, const char *chars)
std::optional< T > stringTo(std::string_view s)
Convert a string to an integral type 'T' (int, uint64_t, ...).
std::pair< string_view, string_view > splitOnFirst(string_view str, string_view chars)
void trimLeft(string &str, const char *chars)
auto split_view(std::string_view str, char c)
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
bool operator!=(const Event &x, const Event &y)
bool operator==(const Event &x, const Event &y)
bool operator()(std::string_view s1, std::string_view s2) const
bool operator()(std::string_view s1, std::string_view s2) const
constexpr uint128 operator*(const uint128 &a, const uint128 &b)
constexpr auto begin(const zstring_view &x)
constexpr auto end(const zstring_view &x)