Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-string-utils.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
31
49# ifndef AH_STRING_UTILS_H
50# define AH_STRING_UTILS_H
51
52# include <algorithm>
53# include <cctype>
54# include <cerrno>
55# include <cstdlib>
56# include <iomanip>
57# include <limits>
58# include <stdexcept>
59# include <string_view>
60# include <type_traits>
61# include <cstring>
62# include <memory>
63# include <string>
64# include <sstream>
65# include <iterator>
66# include <vector>
67# include <htlist.H>
68# include <tpl_array.H>
69# include <ah-zip.H>
70
71namespace Aleph
72{
79 template <typename T>
80 std::string to_string(const std::vector<T> & v)
81 {
82 std::ostringstream s;
83 for (size_t i = 0; i < v.size(); ++i)
84 {
85 s << v[i];
86 if (i < v.size() - 1)
87 s << ", ";
88 }
89 return s.str();
90 }
91
98 template <typename T>
99 std::string to_string(const Array<T> & v)
100 {
101 std::ostringstream s;
102 for (auto it = v.get_it(); it.has_curr(); it.next_ne())
103 {
104 s << it.get_curr();
105 if (not it.is_last())
106 s << ", ";
107 }
108 return s.str();
109 }
110
111 // left trim
118 inline void ltrim(std::string & s)
119 {
120 s.erase(s.begin(), std::find_if(s.begin(), s.end(),
121 [](const unsigned char ch)
122 {
123 return not std::isspace(ch);
124 }));
125 }
126
127 // trim from end
134 inline void rtrim(std::string & s)
135 {
136 s.erase(std::find_if(s.rbegin(), s.rend(),
137 [](const unsigned char ch)
138 {
139 return not std::isspace(ch);
140 }).base(), s.end());
141 }
142
143 // fast concatenation of several strings
152 template <class... Args>
153 inline std::string concat(const Args &... args)
154 {
155 std::ostringstream s;
156 (s << ... << args);
157 return s.str();
158 }
159
160 // trim from both ends (in place)
166 inline std::string trim(const std::string & s)
167 {
168 std::string ret = s;
169 ltrim(ret);
170 rtrim(ret);
171 return ret;
172 }
173
179 inline std::string &trim_in_place(std::string & s)
180 {
181 ltrim(s);
182 rtrim(s);
183 return s;
184 }
185
192 inline bool contains(const std::string_view & str, const std::string_view & substr)
193 {
194 return str.find(substr) != std::string::npos;
195 }
196
203 inline std::string to_string(const double d, const size_t precision)
204 {
205 std::ostringstream s;
206 s.precision(precision);
207 s << std::fixed << d;
208 return s.str();
209 }
210
218 inline std::string to_str(const double d)
219 {
220 return to_string(d, std::numeric_limits<double>::max_digits10);
221 }
222
228 inline std::string tolower(const char *str)
229 {
230 std::string ret;
231 for (const char *ptr = str; *ptr; ++ptr)
232 ret.push_back(static_cast<char>(std::tolower(static_cast<unsigned char>(*ptr))));
233 return ret;
234 }
235
241 inline std::string toupper(const char *str)
242 {
243 std::string ret;
244 for (const char *ptr = str; *ptr; ++ptr)
245 ret.push_back(static_cast<char>(std::toupper(static_cast<unsigned char>(*ptr))));
246 return ret;
247 }
248
254 inline std::string tolower(const std::string & str)
255 {
256 return tolower(str.c_str());
257 }
258
264 inline std::string toupper(const std::string & str)
265 {
266 return toupper(str.c_str());
267 }
268
274 inline std::string &mutable_tolower(std::string & str)
275 {
276 for (auto & c: str)
277 c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
278 return str;
279 }
280
286 inline std::string &mutable_toupper(std::string & str)
287 {
288 for (auto & c: str)
289 c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
290 return str;
291 }
292
303 inline std::string only_alpha(const std::string & str)
304 {
305 std::string ret;
306 ret.reserve(str.size() + 1);
307 for (const char c: str)
308 switch (c)
309 {
310 case '0'...'9':
311 case 'a'...'z':
312 ret.push_back(c);
313 break;
314 case 'A'...'Z':
315 ret.push_back(static_cast<char>(std::tolower(static_cast<unsigned char>(c))));
316 break;
317 default:
318 break;
319 }
320
321 return ret;
322 }
323
331 inline std::string remove_spaces(const std::string & str)
332 {
333 const size_t n = str.size();
334 std::string ret;
335 ret.reserve(n + 1);
336 for (const auto c: str)
337 if (not std::isspace(static_cast<unsigned char>(c)))
338 ret.push_back(c);
339 return ret;
340 }
341
348 inline std::string remove_symbols(const std::string & str, const std::string & symbols)
349 {
350 const size_t n = str.size();
351 std::string ret;
352 ret.reserve(n + 1);
353 for (const auto c: str)
354 if (symbols.find(c) == std::string::npos)
355 ret.push_back(c);
356
357 return ret;
358 }
359
371 template <class C>
372 inline std::ostream &join(const C & c, const std::string & sep, std::ostream & out)
373 {
374 if (c.is_empty())
375 return out;
376
377 auto & last = c.get_last();
378 for (auto it = c.get_it(); it.has_curr(); it.next_ne())
379 {
380 auto & curr = it.get_curr();
381 out << curr;
382 if (&curr != &last)
383 out << sep;
384 }
385 return out;
386 }
387
395 template <class C>
396 inline std::string join(const C & c, const std::string & sep = " ")
397 {
398 std::ostringstream s;
399 join(c, sep, s);
400 return s.str();
401 }
402
403 // return true if str can be converted to a double
412 inline bool is_double(const std::string & str)
413 {
414 const char *begin = str.c_str();
415 char *endptr = nullptr;
416 errno = 0;
417 (void) std::strtod(begin, &endptr);
418 if (endptr == begin or *endptr != '\0')
419 return false;
420 return errno != ERANGE;
421 }
422
431 inline bool is_float(const std::string & str)
432 {
433 const char *begin = str.c_str();
434 char *endptr = nullptr;
435 errno = 0;
436 (void) std::strtof(begin, &endptr);
437 if (endptr == begin or *endptr != '\0')
438 return false;
439 return errno != ERANGE;
440 }
441
450 inline bool is_long(const std::string & str)
451 {
452 const char *begin = str.c_str();
453 char *endptr = nullptr;
454 errno = 0;
455 (void) std::strtol(begin, &endptr, 10);
456 if (endptr == begin or *endptr != '\0')
457 return false;
458 return errno != ERANGE;
459 }
460
469 inline bool is_size_t(const std::string & str)
470 {
471 if (str.empty() or str[0] == '-')
472 return false;
473
474 const char *begin = str.c_str();
475 char *endptr = nullptr;
476 errno = 0;
477 const auto val = std::strtoull(begin, &endptr, 10);
478 if (endptr == begin or *endptr != '\0')
479 return false;
480 if (errno == ERANGE)
481 return false;
483 }
484
485
492 inline long safe_atol(const std::string & s)
493 {
494 errno = 0;
495 char *endptr = nullptr;
496 const auto val = std::strtol(s.c_str(), &endptr, 10);
497 const bool invalid =
498 (errno == ERANGE and (val == LONG_MAX or val == LONG_MIN)) or
499 (errno != 0 and val == 0) or
500 endptr == s.c_str();
501
502 ah_runtime_error_if(invalid) << "invalid std::string for long: " << s;
503 return val;
504 }
505
512 inline double safe_atof(const std::string & s)
513 {
514 errno = 0;
515 char *endptr = nullptr;
516 const auto val = std::strtod(s.c_str(), &endptr);
517 const bool invalid =
518 (errno == ERANGE and (val == HUGE_VAL or val == HUGE_VALF or val == HUGE_VALL)) ||
519 (errno != 0 && val == 0) ||
520 endptr == s.c_str();
521
522 ah_runtime_error_if(invalid) << "invalid std::string for double: " << s;
523 return val;
524 }
525
532 inline bool is_prefix(const std::string & str, const std::string & prefix)
533 {
534 if (str.size() < prefix.size())
535 return false;
536 return strncmp(str.data(), prefix.data(), prefix.size()) == 0;
537 }
538
545 inline std::string remove_prefix(std::string & str, const std::string & prefix)
546 {
547 if (is_prefix(str, prefix))
548 str = str.substr(prefix.size());
549 return str;
550 }
551
557 inline std::string to_lower(const std::string & str)
558 {
559 std::string ret;
560 for (const char c: str)
561 ret.push_back(static_cast<char>(std::tolower(static_cast<unsigned char>(c))));
562 return ret;
563 }
564
570 inline std::string to_upper(const std::string & str)
571 {
572 std::string ret;
573 for (const char c: str)
574 ret.push_back(static_cast<char>(std::toupper(static_cast<unsigned char>(c))));
575 return ret;
576 }
577
583 inline std::string to_name(const std::string & str)
584 {
585 if (str.empty())
586 return str;
587
588 std::string ret;
589 ret.push_back(static_cast<char>(std::toupper(static_cast<unsigned char>(str[0]))));
590
591 for (size_t i = 1; i < str.size(); ++i)
592 ret.push_back(str[i]);
593
594 return ret;
595 }
596
604 inline DynList<std::string> split_camel_case(const char *const str)
605 {
607 if (str == nullptr or *str == '\0')
608 return ret;
609 const char *ptr = str;
610 std::string curr(1, *ptr);
611 while (*++ptr)
612 if (std::isupper(static_cast<unsigned char>(*ptr)))
613 {
614 ret.append(curr);
615 curr = std::string(1, *ptr);
616 }
617 else
618 curr.push_back(*ptr);
619
620 if (not curr.empty())
621 ret.append(curr);
622
623 return ret;
624 }
625
631 inline DynList<std::string> split_camel_case(const std::string & str)
632 {
633 return split_camel_case(str.data());
634 }
635
641 inline void fill_string(std::string & str, char sym)
642 {
643 for (char & c: str)
644 c = sym;
645 }
646
656 inline std::vector<std::string> &
657 split(const std::string & s, const char delim, std::vector<std::string> & elems)
658 {
659 std::stringstream ss(s);
660 std::string item;
661 while (getline(ss, item, delim))
662 elems.push_back(item);
663
664 return elems;
665 }
666
673 inline std::vector<std::string> split(const std::string & s, const char delim)
674 {
675 std::vector<std::string> elems;
676 split(s, delim, elems);
677 return elems;
678 }
679
691 template <template <typename> class Container = DynList>
692 inline Container<std::string> split_string(const std::string & s, const std::string & delim)
693 {
695 if (s.empty())
696 return elems;
697
698 if (delim.empty())
699 {
700 elems.append(s);
701 return elems;
702 }
703
704 char *saveptr = nullptr;
705 char **p = &saveptr;
706
707 std::string data = s;
708 const char *d = delim.data();
709 const auto str = data.data();
710
711 for (char *token = strtok_r(str, d, p); token;
712 token = strtok_r(nullptr, d, p))
714
715 return elems;
716 }
717
724 inline DynList<std::string> split_to_list(const std::string & s,
725 const std::string & delim)
726 {
727 return split_string<DynList>(s, delim);
728 }
729
738 inline std::string to_Pascalcase(const std::string & str)
739 {
741
742 tokens.mutable_for_each([](std::string & token)
743 {
744 token[0] = ::toupper(token[0]);
745 });
746
747 return tokens.foldl<std::string>("", [](const std::string & acu, const std::string & token)
748 {
749 return acu + token;
750 });
751 }
752
759 inline Array<std::string> split_to_array(const std::string & s,
760 const std::string & delim)
761 {
762 return split_string<Array>(s, delim);
763 }
764
772 inline std::pair<std::string, std::string> split_pos(const std::string & str, const size_t pos)
773 {
774 ah_range_error_if(pos > str.size())
775 << "split_pos(" << str << ", " << pos << "): position " << pos
776 << " is larger than std::string size " << str.size();
777
778
779 const char *ptr = str.data();
780 const char *end1 = ptr + pos;
781
782 std::string s1;
783 while (ptr != end1)
784 s1.push_back(*ptr++);
785
786 std::string s2;
787 while (*ptr)
788 s2.push_back(*ptr++);
789
790 return {s1, s2};
791 }
792
803 inline DynList<std::string> split_n(const std::string & str, const size_t n)
804 {
805 ah_range_error_if(n == 0) << "split_n(): number of parts cannot be 0";
806
807 ah_range_error_if(n > str.size())
808 << "split_n(" << str << ", " << n << "): number of parts " << n
809 << " is larger than std::string size " << str.size();
810
811 const size_t sz = str.size() / n;
812
813 const char *ptr = str.data();
814
816
817 for (size_t i = 0; i < n; ++i)
818 {
819 std::string s;
820 if (i + 1 == n)
821 while (*ptr)
822 s.push_back(*ptr++);
823 else
824 for (size_t k = 0; k < sz and *ptr; ++k)
825 s.push_back(*ptr++);
826
827 ret.append(s);
828 }
829
830 return ret;
831 }
832
842 template <typename T>
844 {
845 size_t max_sz = 0;
847 m.template maps<size_t>([&max_sz](auto & l)
848 {
849 const size_t sz = l.size();
850 max_sz = std::max(max_sz, sz);
851 return sz;
852 });
853
855 for (auto it = zip_it(m, sizes); it.has_curr(); it.next_ne())
856 {
857 auto t = it.get_curr();
858 DynList<T> & l = get<0>(t);
859 const size_t sz = get<1>(t);
860 const long n = max_sz - sz;
861 for (auto i = 0; i < n; ++i)
862 l.append(T());
863 ret.append(std::move(l));
864 }
865
866 return ret;
867 }
868
876 const DynList<DynList<std::string>> & mat)
877 {
878 return mat.maps<DynList<std::string>>([&lens](const DynList<std::string> & l)
879 {
880 return zip(lens, l).template maps<std::string>([](const auto & p)
881 {
882 const std::string blanks(p.first > p.second.size() ?
883 p.first - p.second.size() :
884 0, ' ');
885 return blanks + p.second + " ";
886 });
887 });
888 }
889
897 inline std::ostream &format_string(std::ostream & out, const DynList<size_t> & lens,
898 const DynList<DynList<std::string>> & mat)
899 {
900 for (auto it = mat.get_it(); it.has_curr(); it.next_ne())
901 {
902 const auto & row = it.get_curr();
903 auto line = zip(lens, row).
904 template maps<std::string>([](const auto & p)
905 {
906 const std::string blanks(p.first > p.second.size() ?
907 p.first - p.second.size() :
908 0, ' ');
909 return blanks + p.second + " ";
910 });
911 line.for_each([&out](const auto & s)
912 {
913 out << s;
914 });
915 out << '\n';
916 }
917
918 return out;
919 }
920
928 {
929 if (mat.is_empty())
930 return mat;
931
932 const DynList<size_t> ilens = rep<size_t>(mat.nth(0).size(), 0);
933 const DynList<size_t> maxs =
934 mat.foldl(ilens, [](const DynList<size_t> & acu,
935 const DynList<std::string> & l)
936 {
937 return zip(acu, l).
938 maps<size_t>([](const auto & p)
939 {
940 return std::max(p.first, p.second.size());
941 });
942 });
943
944 return format_string(maxs, mat);
945 }
946
954 {
956 for (auto row_it = mat.get_it(); row_it.has_curr(); row_it.next_ne())
957 {
958 const DynList<std::string> & curr_row = row_it.get_curr();
959 const std::string & last = curr_row.get_last();
961 for (auto it = curr_row.get_it(); it.has_curr(); it.next_ne())
962 {
963 const std::string & s = it.get_curr();
964 if (&s == &last)
965 row.append(s);
966 else
967 row.append(s + ",");
968 }
969 ret.append(row);
970 }
971
972 return ret;
973 }
974
982 inline std::string to_string(const DynList<DynList<std::string>> & mat)
983 {
984 std::ostringstream s;
985 mat.for_each([&s](const auto & row)
986 {
987 row.for_each([&s](const std::string & str)
988 {
989 s << str;
990 });
991 s << '\n';
992 });
993 return s.str();
994 }
995
1002 {
1004 std::istringstream in(text);
1005 for (std::string word; in >> word;)
1006 words.append(word);
1007 return words;
1008 }
1009
1016 {
1017 return split_to_list(text, "\n");
1018 }
1019
1025 inline std::string to_string(const DynList<std::string> & lines)
1026 {
1027 std::ostringstream s;
1028 for (auto it = lines.get_it(); it.has_curr(); it.next_ne())
1029 {
1030 const auto & line = it.get_curr();
1031 s << line;
1032 if (line != lines.get_last())
1033 s << '\n';
1034 }
1035
1036 return s.str();
1037 }
1038
1045 inline std::string justify_line(std::string line, const size_t page_width)
1046 {
1047 if (size_t pos = line.find_first_of(' '); pos != std::string::npos)
1048 while (line.size() < page_width)
1049 {
1050 pos = line.find_first_not_of(' ', pos);
1051 if (pos == std::string::npos)
1052 break;
1053 line.insert(pos, " ");
1054 pos = line.find_first_of(' ', pos + 1);
1055 if (pos == std::string::npos)
1056 pos = line.find_first_of(' ');
1057 }
1058
1059 return line;
1060 }
1061
1069 inline std::string justify_text(const std::string & text,
1070 const size_t width,
1071 const size_t left_margin = 0)
1072 {
1073 auto words = split_text_into_words(text);
1074
1075 std::ostringstream s;
1076 std::string line;
1077 for (const std::string & word: words)
1078 if (line.size() + word.size() + 1 > width)
1079 {
1080 // next word doesn't fit into the line
1081 if (not line.empty())
1082 {
1083 s << std::string(left_margin, ' ') << justify_line(line, width) << '\n';
1084 line.clear();
1085 }
1086 line = word;
1087 }
1088 else
1089 {
1090 if (not line.empty())
1091 line.append(" ");
1092 line.append(word);
1093 }
1094
1095 s << std::string(left_margin, ' ') << line;
1096
1097 return s.str();
1098 }
1099
1107 inline std::string justify_line_except_first(const std::string & text,
1108 const size_t width,
1109 const size_t left_margin = 0)
1110 {
1111 const auto formatted = justify_text(text, width);
1113 std::ostringstream s;
1114 s << lines.remove_first() << '\n';
1115 s << justify_text(to_string(lines), width, left_margin);
1116 return s.str();
1117 }
1118
1126 inline std::string align_text_to_left(const std::string & text,
1127 const size_t page_width,
1128 const size_t left_margin = 0)
1129 {
1130 auto words = split_text_into_words(text);
1131
1132 const std::string margin(left_margin, ' ');
1133 std::ostringstream s;
1134 std::string line;
1135 for (const std::string & word: words)
1136 if (line.size() + word.size() + 1 > page_width)
1137 {
1138 // next word doesn't fit into the line
1139 if (not line.empty())
1140 {
1141 s << margin << line << '\n';
1142 line.clear();
1143 }
1144 line = word;
1145 }
1146 else
1147 {
1148 if (not line.empty())
1149 line.append(" ");
1150 line.append(word);
1151 }
1152
1153 s << margin << line;
1154
1155 return s.str();
1156 }
1157
1165 inline std::string align_text_to_left_except_first(const std::string & text,
1166 const size_t width,
1167 const size_t left_margin = 0)
1168 {
1169 const auto formatted = align_text_to_left(text, width);
1171 std::ostringstream s;
1172 s << lines.remove_first() << '\n';
1174 return s.str();
1175 }
1176
1183 inline std::string shift_lines_to_left(const std::string & str, const size_t n)
1184 {
1185 std::ostringstream s;
1186 const std::string fill(n, ' ');
1187 const auto lines = split_to_list(str, "\n");
1188 for (auto it = lines.get_it(); it.has_curr(); it.next_ne())
1189 {
1190 const auto & line = it.get_curr();
1191 s << fill << line;
1192 if (line != lines.get_last())
1193 s << '\n';
1194 }
1195 return s.str();
1196 }
1197
1202 inline void build_pars_list(std::string & unused)
1203 {
1204 (void) unused;
1205 }
1206
1207 template <typename T>
1208 requires requires(std::ostream & out, const T & v)
1209 {
1210 out << v;
1211 }
1212
1219 inline void build_pars_list(std::string & str, const T & item)
1220 {
1221 std::ostringstream s;
1222 if (not str.empty())
1223 s << ", ";
1224 s << item;
1225 str.append(s.str());
1226 }
1227
1236 template <class T, class... Args>
1237 inline void build_pars_list(std::string & str, const T & item, Args... args)
1238 {
1239 build_pars_list(str, item);
1240 build_pars_list(str, args...);
1241 }
1242
1246 template <class First, class... Rest>
1247 requires (not requires(const std::remove_reference_t<First> & c)
1248 {
1249 c.is_empty();
1250 c.get_last();
1251 c.get_it();
1252 })
1263 inline std::string build_pars_list(const First & first, const Rest &... rest)
1264 {
1265 std::string ret;
1266 build_pars_list(ret, first, rest...);
1267 return ret;
1268 }
1269
1270 template <class C>
1271 requires requires(const C & c)
1272 {
1273 c.is_empty();
1274 c.get_last();
1275 c.get_it();
1276 }
1284 inline std::string build_pars_list(const C & c, const std::string & sep = ",")
1285 {
1286 if (c.is_empty())
1287 return "";
1288
1289 auto & last = c.get_last();
1290 std::ostringstream s;
1291 for (auto it = c.get_it(); it.has_curr(); it.next_ne())
1292 {
1293 auto & curr = it.get_curr();
1294 s << curr;
1295 if (&curr != &last)
1296 s << sep;
1297 }
1298 return s.str();
1299 }
1300}
1301
1302# endif // AH_STRING_UTILS_H
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
Definition ah-errors.H:266
#define ah_range_error_if(C)
Throws std::range_error if condition holds.
Definition ah-errors.H:207
Zip iterators and functional operations for multiple containers.
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
T & get_last() const
Return the last item of the list.
Definition htlist.H:1663
void empty() noexcept
empty the list
Definition htlist.H:1689
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
void mutable_for_each(Operation &operation)
Definition ah-dry.H:787
__T foldl(const __T &init, Op &op) const
Fold the elements of the container to a specific result.
Definition ah-dry.H:1034
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:685
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
Definition ah-dry.H:904
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::string tolower(const char *str)
Convert a C std::string to lower-case.
bool is_prefix(const std::string &str, const std::string &prefix)
Check whether prefix is a prefix of str.
std::string remove_symbols(const std::string &str, const std::string &symbols)
Remove any character appearing in symbols.
std::string to_upper(const std::string &str)
Convert a std::string to upper-case (byte-wise).
DynList< std::string > split_text_into_lines(const std::string &text)
Split a text into lines by "\n".
std::string justify_line_except_first(const std::string &text, const size_t width, const size_t left_margin=0)
Justify all lines except the first one.
DynList< std::string > split_text_into_words(const std::string &text)
Split a text into whitespace-separated words.
Array< std::string > split_to_array(const std::string &s, const std::string &delim)
Split a std::string into an Aleph::Array<std::string>.
std::pair< std::string, std::string > split_pos(const std::string &str, const size_t pos)
Split a std::string at a fixed position.
long safe_atol(const std::string &s)
Convert a std::string to long and throw on parse errors.
void ltrim(std::string &s)
Remove leading whitespace from a std::string in-place.
std::string remove_prefix(std::string &str, const std::string &prefix)
Remove prefix from str if present.
std::string & trim_in_place(std::string &s)
Trim a std::string in-place (leading + trailing whitespace removed).
std::string align_text_to_left(const std::string &text, const size_t page_width, const size_t left_margin=0)
Align text to the left by wrapping lines at page_width.
DynList< std::pair< typename Container1::Item_Type, typename Container2::Item_Type > > zip(const Container1 &a, const Container2 &b)
Zip two containers into a list of pairs.
void fill(Itor beg, const Itor &end, const T &value)
Fill a range with a value.
Definition ahAlgo.H:707
Container< std::string > split_string(const std::string &s, const std::string &delim)
Split a std::string by a set of delimiter characters.
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:107
bool contains(const std::string_view &str, const std::string_view &substr)
Check if substr appears inside str.
std::string justify_line(std::string line, const size_t page_width)
Justify a single line by inserting extra spaces.
std::string to_Pascalcase(const std::string &str)
Convert an identifier-like std::string to PascalCase.
DynList< DynList< std::string > > format_string_csv(const DynList< DynList< std::string > > &mat)
Produce a CSV-like matrix (commas added to all but last element in each row).
static void prefix(Node *root, DynList< Node * > &acc)
bool is_long(const std::string &str)
Check whether a std::string fully parses as a long.
DynList< std::string > split_n(const std::string &str, const size_t n)
Split a std::string into n parts.
std::string to_name(const std::string &str)
Uppercase the first character of str and return the resulting copy.
bool is_float(const std::string &str)
Check whether a std::string fully parses as a finite float.
bool is_size_t(const std::string &str)
Check whether a std::string fully parses as a non-negative size_t.
std::string trim(const std::string &s)
Return a trimmed copy of a std::string (leading + trailing whitespace removed).
DynList< std::string > split_camel_case(const char *const str)
Split a camelCase / PascalCase std::string into tokens.
void build_pars_list(std::string &unused)
Base case for build_pars_list(std::string&, ...).
std::string remove_spaces(const std::string &str)
Remove all whitespace characters from a std::string.
std::string to_string(const time_t t, const std::string &format)
Format a time_t value into a string using format.
Definition ah-date.H:140
std::string to_str(const double d)
Convert double to a std::string with maximum round-trip precision.
std::string justify_text(const std::string &text, const size_t width, const size_t left_margin=0)
Justify a text to a target width.
bool is_double(const std::string &str)
Check whether a std::string fully parses as a finite double.
DynList< std::string > split_to_list(const std::string &s, const std::string &delim)
Split a std::string into an Aleph::DynList<std::string>.
std::string shift_lines_to_left(const std::string &str, const size_t n)
Indent every line in a multi-line std::string by n spaces.
std::string concat(const Args &... args)
Concatenate multiple streamable arguments into a single std::string.
DynList< DynList< T > > complete_rows(DynList< DynList< T > > &m)
Pad all rows of a matrix to the maximum row length.
std::string align_text_to_left_except_first(const std::string &text, const size_t width, const size_t left_margin=0)
Align all lines except the first one.
std::string toupper(const char *str)
Convert a C std::string to upper-case.
std::ostream & join(const C &c, const std::string &sep, std::ostream &out)
Join elements of an Aleph-style container into a stream.
void rtrim(std::string &s)
Remove trailing whitespace from a std::string in-place.
std::vector< std::string > & split(const std::string &s, const char delim, std::vector< std::string > &elems)
Split a std::string by a single delimiter character.
DynList< DynList< std::string > > format_string(const DynList< size_t > &lens, const DynList< DynList< std::string > > &mat)
double safe_atof(const std::string &s)
Convert a std::string to double and throw on parse errors.
std::string to_lower(const std::string &str)
Convert a std::string to lower-case (byte-wise).
void fill_string(std::string &str, char sym)
Fill all the content of std::string with a defined char.
std::string & mutable_tolower(std::string &str)
Convert a std::string to lower-case in-place.
ZipIterator< Cs... > zip_it(const Cs &... cs)
Alias for get_zip_it.
Definition ah-zip.H:275
std::string & mutable_toupper(std::string &str)
Convert a std::string to upper-case in-place.
DynList< T > maps(const C &c, Op op)
Classic map operation.
std::string only_alpha(const std::string &str)
Extract alphanumeric ASCII characters and normalize letters to lower-case.
Dynamic array container with automatic resizing.
DynList< int > l