27template <
typename T,
typename... Args>
32template <
class... Args>
41 return str.length() >=
sl && str.compare(0,
sl,
prefix) == 0;
44template<
size_t N>
bool starts_with(
const char* a,
const char (&b)[
N]) {
45 return std::strncmp(a, b,
N-1) == 0;
50 return str.length() >=
sl && str.compare(str.length() -
sl,
sl,
suffix) == 0;
55 if (c >=
'A' && c <=
'Z')
61inline char alpha_up(
char c) {
return c & ~0x20; }
65 if (c >=
'A' && c <=
'Z')
72 if (c >=
'a' && c <=
'z')
78inline bool isame(
char a,
char b) {
79 return a == b || ((a^b) == 0x20 && (a|0x20) >=
'a' && (a|0x20) <=
'z');
85 return str.length() ==
low.length() +
offset &&
86 std::equal(std::begin(
low), std::end(
low), str.begin() +
offset,
87 [](
char c1,
char c2) { return c1 == lower(c2); });
90inline bool iequal(
const std::string& str,
const std::string&
low) {
95 return str.length() >=
prefix.length() &&
96 std::equal(std::begin(
prefix), std::end(
prefix), str.begin(),
97 [](
char c1,
char c2) { return c1 == lower(c2); });
101 return str.length() >=
sl &&
103 [](
char c1,
char c2) { return c1 == lower(c2); });
110inline std::string
trim_str(
const std::string& str) {
111 const std::string
ws =
" \r\n\t";
112 std::string::size_type first = str.find_first_not_of(
ws);
113 if (first == std::string::npos)
114 return std::string{};
115 std::string::size_type
last = str.find_last_not_of(
ws);
116 return str.substr(first,
last - first + 1);
120 std::string::size_type
last = str.find_last_not_of(
" \r\n\t");
121 return str.substr(0,
last == std::string::npos ? 0 :
last + 1);
125inline const char*
rtrim_cstr(
const char* start,
const char* end=
nullptr) {
133 while (end > start && std::isspace(end[-1]))
139inline size_t length(
char) {
return 1; }
140inline size_t length(
const std::string& s) {
return s.length(); }
147 std::vector<std::string>&
result) {
148 std::size_t start = 0, end;
149 while ((end = str.find(
sep, start)) != std::string::npos) {
150 result.emplace_back(str, start, end - start);
151 start = end + impl::length(
sep);
153 result.emplace_back(str, start);
158 std::vector<std::string>
result;
166 std::vector<std::string>&
result) {
167 std::size_t start = str.find_first_not_of(
seps);
168 while (start != std::string::npos) {
169 std::size_t end = str.find_first_of(
seps, start);
170 result.emplace_back(str, start, end - start);
171 start = str.find_first_not_of(
seps, end);
176 const char*
seps=
" \t") {
177 std::vector<std::string>
result;
182template<
typename T,
typename S,
typename F>
186 for (
T i = begin;
i != end; ++
i) {
195template<
typename T,
typename S>
197 return join_str(begin, end,
sep, [](
const std::string&
t) {
return t; });
200template<
typename T,
typename S,
typename F>
205template<
typename T,
typename S>
210template<
typename T,
typename S>
218 const std::string &
old,
const std::string &
new_) {
219 std::string::size_type pos = 0;
220 while ((pos = s.find(
old, pos)) != std::string::npos) {
221 s.replace(pos,
old.size(),
new_);
227inline bool is_in_list(
const std::string& name,
const std::string& list,
229 if (name.length() >= list.length())
231 for (
size_t start=0, end=0; end != std::string::npos; start=end+1) {
232 end = list.find(
sep, start);
233 if (list.compare(start, end - start, name) == 0)
243 return std::find(v.begin(), v.end(), x) != v.end();
246template <
typename F,
typename T>
248 return std::find_if(v.begin(), v.end(), f) != v.end();
261 dst.insert(
dst.end(), std::make_move_iterator(
src.begin()),
262 std::make_move_iterator(
src.end()));
266template <
class T,
typename F>
268 v.erase(std::remove_if(v.begin(), v.end(),
condition), v.end());
275 size_t length,
size_t n,
size_t pos,
const T&
new_value) {
278 data.resize(data.size() + n * length);
279 typename std::vector<T>::iterator
dst = data.end();
280 for (
size_t i = length;
i-- != 0; ) {
283 for (
size_t j = n;
j-- != 0; )
285 for (
size_t j = pos;
j-- != 0; )
295 for (
size_t source = pos + 1; source < data.size(); ++source)
296 for (
size_t i = 0;
i <
new_width && source < data.size(); ++
i)
297 data[pos++] = data[source++];
307 return (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]) & ~0x20202020;
311 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)
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)
void vector_insert_columns(std::vector< T > &data, size_t old_width, size_t length, size_t n, size_t pos, const T &new_value)
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)