13 #include <string_view>
14 #include <type_traits>
17 #if defined(__APPLE__)
18 #include <CoreFoundation/CoreFoundation.h>
42 template<
typename T> [[nodiscard]] std::optional<T>
stringTo(std::string_view s);
47 template<
int BASE,
typename T> [[nodiscard]] std::optional<T>
stringToBase(std::string_view s);
53 [[nodiscard]]
bool startsWith(std::string_view total, std::string_view part);
54 [[nodiscard]]
bool startsWith(std::string_view total,
char part);
55 [[nodiscard]]
bool endsWith (std::string_view total, std::string_view part);
56 [[nodiscard]]
bool endsWith (std::string_view total,
char part);
58 void trimRight(std::string& str,
const char* chars);
59 void trimRight(std::string& str,
char chars);
60 void trimRight(std::string_view& str, std::string_view chars);
61 void trimRight(std::string_view& str,
char chars);
62 void trimLeft (std::string& str,
const char* chars);
63 void trimLeft (std::string& str,
char chars);
64 void trimLeft (std::string_view& str, std::string_view chars);
65 void trimLeft (std::string_view& str,
char chars);
66 void trim (std::string_view& str, std::string_view chars);
67 void trim (std::string_view& str,
char chars);
69 [[nodiscard]] std::pair<std::string_view, std::string_view>
splitOnFirst(
70 std::string_view str, std::string_view chars);
71 [[nodiscard]] std::pair<std::string_view, std::string_view>
splitOnFirst(
72 std::string_view str,
char chars);
73 [[nodiscard]] std::pair<std::string_view, std::string_view>
splitOnLast(
74 std::string_view str, std::string_view chars);
75 [[nodiscard]] std::pair<std::string_view, std::string_view>
splitOnLast(
76 std::string_view str,
char chars);
77 [[nodiscard]] std::vector<unsigned>
parseRange(std::string_view str,
78 unsigned min,
unsigned max);
80 [[nodiscard]] std::vector<std::string_view>
split(std::string_view str,
char chars);
82 [[nodiscard]]
inline auto split_view(std::string_view str,
char c) {
87 std::string_view::size_type p;
90 [[nodiscard]] Iterator(std::string_view str_,
char c_)
95 [[nodiscard]] std::string_view
operator*()
const {
96 return std::string_view(str.data(), p);
99 Iterator& operator++() {
100 if (p < str.size()) {
101 str.remove_prefix(p + 1);
109 [[nodiscard]]
bool operator==(Sentinel)
const {
return str.empty(); }
110 [[nodiscard]]
bool operator!=(Sentinel)
const {
return !str.empty(); }
114 while ((p < str.size()) && (str[p] != c)) ++p;
119 std::string_view str;
122 [[nodiscard]]
auto begin()
const {
return Iterator{str, c}; }
123 [[nodiscard]]
auto end()
const {
return Sentinel{}; }
126 return Splitter{str, c};
131 [[nodiscard]]
bool operator()(std::string_view s1, std::string_view s2)
const {
132 auto m =
std::min(s1.size(), s2.size());
133 int r = strncasecmp(s1.data(), s2.data(), m);
134 return (r != 0) ? (r < 0) : (s1.size() < s2.size());
138 [[nodiscard]]
bool operator()(std::string_view s1, std::string_view s2)
const {
139 if (s1.size() != s2.size())
return false;
140 return strncasecmp(s1.data(), s2.data(), s1.size()) == 0;
144 #if defined(__APPLE__)
145 [[nodiscard]] std::string fromCFString(CFStringRef str);
148 template<
int BASE,
typename T>
153 auto e = s.data() + s.size();
154 if (
auto [p, ec] = std::from_chars(b, e, result, BASE);
155 (ec == std::errc()) && (p == e)) {
162 [[nodiscard]] std::optional<T>
stringTo(std::string_view s)
165 if constexpr (std::is_signed_v<T>) {
172 using U = std::make_unsigned_t<T>;
173 auto tmp = stringTo<U>(s);
185 if (
likely(s[0] !=
'0')) {
186 return stringToBase<10, T>(s);
188 if (s.size() == 1)
return T(0);
189 if (
likely((s[1] ==
'x') || (s[1] ==
'X'))) {
191 return stringToBase<16, T>(s);
192 }
else if ((s[1] ==
'b') || (s[1] ==
'B')) {
194 return stringToBase<2, T>(s);
196 return stringToBase<10, T>(s);