26template <
typename T,
typename... Args>
31template <
class... Args>
40 return str.length() >=
sl && str.compare(0,
sl,
prefix) == 0;
43template<
size_t N>
bool starts_with(
const char* a,
const char (&b)[
N]) {
44 return std::strncmp(a, b,
N-1) == 0;
49 return str.length() >=
sl && str.compare(str.length() -
sl,
sl,
suffix) == 0;
54 if (c >=
'A' && c <=
'Z')
60inline char alpha_up(
char c) {
return c & ~0x20; }
64 if (c >=
'A' && c <=
'Z')
71 if (c >=
'a' && c <=
'z')
77inline bool isame(
char a,
char b) {
78 return a == b || ((a^b) == 0x20 && (a|0x20) >=
'a' && (a|0x20) <=
'z');
84 return str.length() ==
low.length() +
offset &&
85 std::equal(std::begin(
low), std::end(
low), str.begin() +
offset,
86 [](
char c1,
char c2) { return c1 == lower(c2); });
89inline bool iequal(
const std::string& str,
const std::string&
low) {
94 return str.length() >=
prefix.length() &&
95 std::equal(std::begin(
prefix), std::end(
prefix), str.begin(),
96 [](
char c1,
char c2) { return c1 == lower(c2); });
100 return str.length() >=
sl &&
102 [](
char c1,
char c2) { return c1 == lower(c2); });
109inline std::string
trim_str(
const std::string& str) {
110 const std::string
ws =
" \r\n\t";
111 std::string::size_type first = str.find_first_not_of(
ws);
112 if (first == std::string::npos)
113 return std::string{};
114 std::string::size_type
last = str.find_last_not_of(
ws);
115 return str.substr(first,
last - first + 1);
119 std::string::size_type
last = str.find_last_not_of(
" \r\n\t");
120 return str.substr(0,
last == std::string::npos ? 0 :
last + 1);
124inline const char*
rtrim_cstr(
const char* start,
const char* end=
nullptr) {
132 while (end > start && std::isspace(end[-1]))
138inline size_t length(
char) {
return 1; }
139inline size_t length(
const std::string& s) {
return s.length(); }
146 std::vector<std::string>&
result) {
147 std::size_t start = 0, end;
148 while ((end = str.find(
sep, start)) != std::string::npos) {
149 result.emplace_back(str, start, end - start);
150 start = end + impl::length(
sep);
152 result.emplace_back(str, start);
157 std::vector<std::string>
result;
165 std::vector<std::string>&
result) {
166 std::size_t start = str.find_first_not_of(
seps);
167 while (start != std::string::npos) {
168 std::size_t end = str.find_first_of(
seps, start);
169 result.emplace_back(str, start, end - start);
170 start = str.find_first_not_of(
seps, end);
175 const char*
seps=
" \t") {
176 std::vector<std::string>
result;
181template<
typename T,
typename S,
typename F>
185 for (
T i = begin;
i != end; ++
i) {
194template<
typename T,
typename S>
196 return join_str(begin, end,
sep, [](
const std::string&
t) {
return t; });
199template<
typename T,
typename S,
typename F>
204template<
typename T,
typename S>
209template<
typename T,
typename S>
217 const std::string &old,
const std::string &new_) {
218 std::string::size_type pos = 0;
219 while ((pos = s.find(old, pos)) != std::string::npos) {
220 s.replace(pos, old.size(), new_);
226inline bool is_in_list(
const std::string& name,
const std::string& list,
228 if (name.length() >= list.length())
230 for (
size_t start=0, end=0; end != std::string::npos; start=end+1) {
231 end = list.find(
sep, start);
232 if (list.compare(start, end - start, name) == 0)
242 return std::find(v.begin(), v.end(), x) != v.end();
245template <
typename F,
typename T>
247 return std::find_if(v.begin(), v.end(), f) != v.end();
260 dst.insert(
dst.end(), std::make_move_iterator(
src.begin()),
261 std::make_move_iterator(
src.end()));
265template <
class T,
typename F>
267 v.erase(std::remove_if(v.begin(), v.end(),
condition), v.end());
274 size_t length,
size_t n,
size_t pos,
T new_value) {
277 data.resize(data.size() + n * length);
278 typename std::vector<T>::iterator
dst = data.end();
279 for (
size_t i = length;
i-- != 0; ) {
282 for (
size_t j = n;
j-- != 0; )
284 for (
size_t j = pos;
j-- != 0; )
294 for (
size_t source = pos + 1; source < data.size(); ++source)
295 for (
size_t i = 0;
i <
new_width && source < data.size(); ++
i)
296 data[pos++] = data[source++];
306 return (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]) & ~0x20202020;
310 return (s[0] << 16 | s[1] << 8 | s[2]) & ~0x20202020;
T * vector_end_ptr(std::vector< T > &v)
void append_to_str(std::string &out, int v)
bool iequal_from(const std::string &str, size_t offset, const std::string &low)
bool ends_with(const std::string &str, const std::string &suffix)
void vector_remove_if(std::vector< T > &v, F &&condition)
bool isame(char a, char b)
const char * rtrim_cstr(const char *start, const char *end=nullptr)
constexpr int ialpha3_id(const char *s)
bool in_vector_f(F f, const std::vector< T > &v)
bool istarts_with(const std::string &str, const std::string &prefix)
std::string rtrim_str(const std::string &str)
void vector_insert_columns(std::vector< T > &data, size_t old_width, size_t length, size_t n, size_t pos, T new_value)
std::string join_str(T begin, T end, const S &sep, const F &getter)
bool in_vector(const T &x, const std::vector< T > &v)
bool iends_with(const std::string &str, const std::string &suffix)
void split_str_into_multi(const std::string &str, const char *seps, std::vector< std::string > &result)
std::string to_lower(std::string str)
void string_append_sep(std::string &str, S sep, const T &item)
std::string to_upper(std::string str)
std::string cat(Args const &... args)
bool is_in_list(const std::string &name, const std::string &list, char sep=',')
bool giends_with(const std::string &str, const std::string &suffix)
void cat_to(std::string &)
bool starts_with(const std::string &str, const std::string &prefix)
std::vector< std::string > split_str_multi(const std::string &str, const char *seps=" \t")
std::vector< std::string > split_str(const std::string &str, S sep)
void vector_remove_column(std::vector< T > &data, size_t new_width, size_t pos)
void split_str_into(const std::string &str, S sep, std::vector< std::string > &result)
bool iequal(const std::string &str, const std::string &low)
std::string trim_str(const std::string &str)
void replace_all(std::string &s, const std::string &old, const std::string &new_)
constexpr int ialpha4_id(const char *s)
void vector_move_extend(std::vector< T > &dst, std::vector< T > &&src)