27 template <
typename T,
template <
typename...>
class U>
31 template <
template <
typename...>
class T,
typename... Args>
41 template <
typename T,
size_t N>
67 template <
typename T, T>
71 template <
typename T, T t>
76 static inline std::vector<std::string_view> split(
77 const std::string_view& s,
78 const std::string_view& separator =
" ",
79 size_t max_split = SIZE_MAX)
81 std::vector<std::string_view> result;
83 auto separator_end = 0;
84 auto next_separator_start = s.find(separator);
85 while (next_separator_start != std::string_view::npos &&
86 result.size() < max_split)
89 s.substr(separator_end, next_separator_start - separator_end));
91 separator_end = next_separator_start + separator.size();
92 next_separator_start = s.find(separator, separator_end);
95 result.push_back(s.substr(separator_end));
103 static inline std::tuple<std::string_view, std::string_view> split_1(
104 const std::string_view& s,
const std::string_view& separator)
106 const auto v = split(s, separator, 1);
110 return std::make_tuple(v[0],
"");
113 return std::make_tuple(v[0], v[1]);
122 static inline std::vector<std::string_view> rsplit(
123 const std::string_view& s,
124 const std::string_view& separator =
" ",
125 size_t max_split = SIZE_MAX)
127 std::vector<std::string_view> result;
129 auto prev_separator_start = s.size();
130 auto next_separator_start = s.rfind(separator);
131 while (next_separator_start != std::string_view::npos &&
132 result.size() < max_split)
134 auto separator_end = next_separator_start + separator.size();
137 s.substr(separator_end, prev_separator_start - separator_end));
139 prev_separator_start = next_separator_start;
141 if (next_separator_start == 0)
147 next_separator_start = s.rfind(separator, prev_separator_start - 1);
151 result.push_back(s.substr(0, prev_separator_start));
160 static inline std::tuple<std::string_view, std::string_view> rsplit_1(
161 const std::string_view& s,
const std::string_view& separator)
163 const auto v = rsplit(s, separator, 1);
167 return std::make_tuple(
"", v[0]);
170 return std::make_tuple(v[1], v[0]);
175 static inline void to_upper(std::string& s)
177 std::transform(s.begin(), s.end(), s.begin(), [](
unsigned char c) {
178 return std::toupper(c);
181 static inline void to_lower(std::string& s)
183 std::transform(s.begin(), s.end(), s.begin(), [](
unsigned char c) {
184 return std::tolower(c);
189 template <
size_t I = 0,
typename F,
typename... Ts>
190 static void tuple_for_each(
const std::tuple<Ts...>& t,
const F& f)
192 if constexpr (I <
sizeof...(Ts))
195 tuple_for_each<I + 1>(t, f);