Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-string-utils.cc
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
37//
38// Created by lrleon on 23/04/24.
39//
40# include <gtest/gtest.h>
41
42# include <cmath>
43# include <cstdlib>
44# include <limits>
45# include <random>
46# include <sstream>
47# include <stdexcept>
48# include <vector>
49
50# include <ah-string-utils.H>
51
52using namespace std;
53using namespace testing;
54using namespace Aleph;
55
63static DynList<string> reference_split_string(const string & s, const string & delim)
64{
66 if (s.empty())
67 return ret;
68
69 if (delim.empty())
70 {
71 ret.append(s);
72 return ret;
73 }
74
75 string token;
76 for (char c : s)
77 if (delim.find(c) == string::npos)
78 token.push_back(c);
79 else if (not token.empty())
80 {
81 ret.append(token);
82 token.clear();
83 }
84
85 if (not token.empty())
86 ret.append(token);
87
88 return ret;
89}
90
101 const DynList<string> & got)
102{
103 ASSERT_EQ(got.size(), expected.size());
104 for (size_t i = 0; i < expected.size(); ++i)
105 EXPECT_EQ(got.nth(i), expected.nth(i));
106}
107
118 const Array<string> & got)
119{
120 ASSERT_EQ(got.size(), expected.size());
121 for (size_t i = 0; i < expected.size(); ++i)
122 EXPECT_EQ(got[i], expected.nth(i));
123}
124
126{
127 string s1 = "hello";
128 string s2 = "world";
129 string blank = " ";
130 string s3 = "!";
131 string s = concat(s1, blank, s2, s3);
132 ASSERT_EQ(s, "hello world!");
133}
134
136{
137 vector<int> v = {1, 2, 3};
138 EXPECT_EQ(Aleph::to_string(v), "1, 2, 3");
139 vector<int> e;
141}
142
144{
145 Array<int> a;
147 a.append(1);
149 a.append(2);
150 a.append(3);
151 EXPECT_EQ(Aleph::to_string(a), "1, 2, 3");
152}
153
155{
156 {
157 string s = "\t abc \n";
158 EXPECT_EQ(trim(s), "abc");
159 EXPECT_EQ(s, "\t abc \n");
160 }
161
162 {
163 string s = "\t abc \n";
164 EXPECT_EQ(trim_in_place(s), "abc");
165 EXPECT_EQ(s, "abc");
166 }
167
168 {
169 string s = "";
170 EXPECT_EQ(trim(s), "");
171 EXPECT_EQ(trim_in_place(s), "");
172 }
173}
174
176{
177 EXPECT_TRUE(contains("hello world", "world"));
178 EXPECT_FALSE(contains("hello", "xyz"));
179 EXPECT_TRUE(contains("", ""));
180}
181
183{
184 EXPECT_EQ(Aleph::to_string(1.5, 2), "1.50");
185 EXPECT_EQ(Aleph::to_string(1.0, 0), "1");
186 auto s = to_str(1.0 / 3.0);
187 EXPECT_FALSE(s.empty());
188}
189
191{
192 EXPECT_EQ(Aleph::tolower("HeLLo"), "hello");
193 EXPECT_EQ(Aleph::toupper("HeLLo"), "HELLO");
194
195 string s = "HeLLo";
196 EXPECT_EQ(mutable_tolower(s), "hello");
197 EXPECT_EQ(s, "hello");
198 EXPECT_EQ(mutable_toupper(s), "HELLO");
199 EXPECT_EQ(s, "HELLO");
200}
201
203{
204 string s;
205 s.push_back(static_cast<char>(0xFF));
206 s.push_back('A');
207 auto lower = Aleph::to_lower(s);
208 ASSERT_EQ(lower.size(), 2u);
209 EXPECT_EQ(lower[1], 'a');
210}
211
213{
214 EXPECT_EQ(only_alpha("A-bC_9"), "abc9");
215 // Exercise each preserved range and its boundary characters: digits 0-9 and
216 // lowercase a-z are kept verbatim, uppercase A-Z is lowercased, everything
217 // else is dropped.
218 EXPECT_EQ(only_alpha("Hello, World! 123"), "helloworld123");
219 EXPECT_EQ(only_alpha("0123456789"), "0123456789");
220 EXPECT_EQ(only_alpha("AZaz"), "azaz");
221 EXPECT_EQ(only_alpha("@#$%^&*()"), "");
222 EXPECT_EQ(only_alpha(""), "");
223 EXPECT_EQ(remove_spaces(" a\tb\nc "), "abc");
224 EXPECT_EQ(remove_symbols("a-b_c", "-_"), "abc");
225 EXPECT_EQ(remove_symbols("", "-_"), "");
226}
227
229{
231 EXPECT_EQ(join(l, ","), "");
232 l.append(1);
233 l.append(2);
234 l.append(3);
235 EXPECT_EQ(join(l, ","), "1,2,3");
236 EXPECT_EQ(join(l, " - "), "1 - 2 - 3");
237}
238
240{
241 EXPECT_TRUE(is_long("0"));
242 EXPECT_TRUE(is_long("-10"));
244 EXPECT_FALSE(is_long("10x"));
245
247 EXPECT_TRUE(is_size_t("10"));
248 EXPECT_FALSE(is_size_t("-1"));
250 EXPECT_FALSE(is_size_t("10x"));
251
253 EXPECT_TRUE(is_double("-1.25"));
254 EXPECT_TRUE(is_double("1e3"));
256 EXPECT_FALSE(is_double("1.2x"));
257 EXPECT_FALSE(is_double("1e309"));
258
259 EXPECT_TRUE(is_float("0"));
260 EXPECT_TRUE(is_float("-1.25"));
262 EXPECT_FALSE(is_float("1.2x"));
263}
264
266{
267 EXPECT_TRUE(is_prefix("foobar", "foo"));
268 EXPECT_FALSE(is_prefix("foo", "foobar"));
269
270 string s = "prefix_value";
271 EXPECT_EQ(remove_prefix(s, "prefix_"), "value");
272 EXPECT_EQ(s, "value");
273}
274
276{
277 EXPECT_EQ(to_name(""), "");
278 EXPECT_EQ(to_name("hello"), "Hello");
279 EXPECT_EQ(to_name("Hello"), "Hello");
280}
281
283{
284 {
285 auto parts = split_camel_case("");
286 EXPECT_TRUE(parts.is_empty());
287 }
288
289 {
290 auto parts = split_camel_case("camelCaseString");
291 ASSERT_EQ(parts.size(), 3u);
292 EXPECT_EQ(parts.nth(0), "camel");
293 EXPECT_EQ(parts.nth(1), "Case");
294 EXPECT_EQ(parts.nth(2), "String");
295 }
296}
297
299{
300 {
301 auto v = split("a,b,,c", ',');
302 ASSERT_EQ(v.size(), 4u);
303 EXPECT_EQ(v[0], "a");
304 EXPECT_EQ(v[1], "b");
305 EXPECT_EQ(v[2], "");
306 EXPECT_EQ(v[3], "c");
307 }
308
309 {
310 auto l = split_to_list("a--b---c", "-");
311 ASSERT_EQ(l.size(), 3u);
312 EXPECT_EQ(l.nth(0), "a");
313 EXPECT_EQ(l.nth(1), "b");
314 EXPECT_EQ(l.nth(2), "c");
315 }
316
317 {
318 auto l = split_to_list("a b-c__d", " _-");
319 ASSERT_EQ(l.size(), 4u);
320 EXPECT_EQ(l.nth(0), "a");
321 EXPECT_EQ(l.nth(1), "b");
322 EXPECT_EQ(l.nth(2), "c");
323 EXPECT_EQ(l.nth(3), "d");
324 }
325
326 {
327 auto l = split_to_list("abc", "");
328 ASSERT_EQ(l.size(), 1u);
329 EXPECT_EQ(l.nth(0), "abc");
330 }
331}
332
334{
335 {
336 auto out = split_to_list("", ",");
337 EXPECT_TRUE(out.is_empty());
338 }
339
340 {
341 auto out = split_to_list(",,,,", ",");
342 EXPECT_TRUE(out.is_empty());
343 }
344
345 {
346 auto expected = reference_split_string(",a,,b,,,c,", ",");
347 auto list_out = split_to_list(",a,,b,,,c,", ",");
348 auto array_out = split_to_array(",a,,b,,,c,", ",");
351 }
352
353 {
354 auto expected = reference_split_string("alpha||beta,gamma;;;delta", "|,;");
355 auto list_out = split_to_list("alpha||beta,gamma;;;delta", "|,;");
356 auto array_out = split_to_array("alpha||beta,gamma;;;delta", "|,;");
359 }
360
361 {
362 auto expected = reference_split_string(" keep everything ", "");
363 auto list_out = split_to_list(" keep everything ", "");
364 auto array_out = split_to_array(" keep everything ", "");
367 }
368}
369
371{
372 EXPECT_EQ(to_Pascalcase("hello_world"), "HelloWorld");
373 EXPECT_EQ(to_Pascalcase("alreadyPascal"), "AlreadyPascal");
374}
375
377{
378 string s = "abcd";
379 EXPECT_EQ(split_pos(s, 0), (pair<string, string>("", "abcd")));
380 EXPECT_EQ(split_pos(s, 2), (pair<string, string>("ab", "cd")));
381 EXPECT_EQ(split_pos(s, 4), (pair<string, string>("abcd", "")));
382 EXPECT_THROW(split_pos(s, 5), range_error);
383}
384
386{
387 EXPECT_THROW(split_n("abc", 0), range_error);
388 EXPECT_THROW(split_n("abc", 4), range_error);
389
390 auto l = split_n("abcdef", 4);
391 ASSERT_EQ(l.size(), 4u);
392 EXPECT_EQ(l.nth(0), "a");
393 EXPECT_EQ(l.nth(1), "b");
394 EXPECT_EQ(l.nth(2), "c");
395 EXPECT_EQ(l.nth(3), "def");
396}
397
399{
401 DynList<int> r1; r1.append(1); r1.append(2);
402 DynList<int> r2; r2.append(3);
403 m.append(r1);
404 m.append(r2);
405
406 auto out = complete_rows(m);
407 ASSERT_EQ(out.size(), 2u);
408 ASSERT_EQ(out.nth(0).size(), 2u);
409 ASSERT_EQ(out.nth(1).size(), 2u);
410 EXPECT_EQ(out.nth(1).nth(0), 3);
411 EXPECT_EQ(out.nth(1).nth(1), 0);
412}
413
415{
417 DynList<string> r1; r1.append("abcd"); r1.append("x");
418 DynList<string> r2; r2.append("ab"); r2.append("xyz");
419 mat.append(r1);
420 mat.append(r2);
421
422 DynList<size_t> lens; lens.append(2); lens.append(1);
423 auto formatted = Aleph::format_string(lens, mat);
424 ASSERT_EQ(formatted.size(), 2u);
425 ASSERT_EQ(formatted.nth(0).size(), 2u);
426}
427
429{
431 DynList<string> r1; r1.append("a"); r1.append("b"); r1.append("c");
432 mat.append(r1);
433 auto csv = format_string_csv(mat);
434 ASSERT_EQ(csv.size(), 1u);
435 EXPECT_EQ(csv.nth(0).nth(0), "a,");
436 EXPECT_EQ(csv.nth(0).nth(1), "b,");
437 EXPECT_EQ(csv.nth(0).nth(2), "c");
438}
439
441{
442 const string text = "one two three four five";
443 auto j = justify_text(text, 10, 2);
444 EXPECT_TRUE(contains(j, " "));
445
446 auto a = align_text_to_left(text, 10, 1);
447 EXPECT_TRUE(contains(a, " one"));
448
449 auto shifted = shift_lines_to_left("a\nb", 3);
450 EXPECT_EQ(shifted, " a\n b");
451}
452
458
469
471{
472 string s = "secret";
473 fill_string(s, 'x');
474 EXPECT_EQ(s, "xxxxxx");
475
476 string e;
477 fill_string(e, 'x');
478 EXPECT_TRUE(e.empty());
479}
480
482{
483 auto a = split_to_array("a b-c__d", " _-");
484 ASSERT_EQ(a.size(), 4u);
485 EXPECT_EQ(a[0], "a");
486 EXPECT_EQ(a[1], "b");
487 EXPECT_EQ(a[2], "c");
488 EXPECT_EQ(a[3], "d");
489}
490
492{
494 DynList<string> r1; r1.append("abcd"); r1.append("x");
495 DynList<string> r2; r2.append("ab"); r2.append("xyz");
496 mat.append(r1);
497 mat.append(r2);
498
500 ASSERT_EQ(formatted.size(), 2u);
501 ASSERT_EQ(formatted.nth(0).size(), 2u);
502 ASSERT_EQ(formatted.nth(1).size(), 2u);
503}
504
506{
508 DynList<string> r1; r1.append("id"); r1.append("value");
509 DynList<string> r2; r2.append("7"); r2.append("abc");
510 DynList<string> r3; r3.append("42"); r3.append("x");
511 mat.append(r1);
512 mat.append(r2);
513 mat.append(r3);
514
515 auto by_max = Aleph::format_string(mat);
516 ASSERT_EQ(by_max.size(), 3u);
517 EXPECT_EQ(by_max.nth(0).nth(0), "id ");
518 EXPECT_EQ(by_max.nth(0).nth(1), "value ");
519 EXPECT_EQ(by_max.nth(1).nth(0), " 7 ");
520 EXPECT_EQ(by_max.nth(1).nth(1), " abc ");
521 EXPECT_EQ(by_max.nth(2).nth(0), "42 ");
522 EXPECT_EQ(by_max.nth(2).nth(1), " x ");
523
524 DynList<size_t> lens;
525 lens.append(3);
526 lens.append(6);
527 auto by_lens = Aleph::format_string(lens, mat);
528 ASSERT_EQ(by_lens.size(), 3u);
529 EXPECT_EQ(by_lens.nth(0).nth(0), " id ");
530 EXPECT_EQ(by_lens.nth(0).nth(1), " value ");
531 EXPECT_EQ(by_lens.nth(1).nth(0), " 7 ");
532 EXPECT_EQ(by_lens.nth(1).nth(1), " abc ");
533 EXPECT_EQ(by_lens.nth(2).nth(0), " 42 ");
534 EXPECT_EQ(by_lens.nth(2).nth(1), " x ");
535
536 std::ostringstream out;
537 Aleph::format_string(out, lens, mat);
538 EXPECT_EQ(out.str(), " id value \n 7 abc \n 42 x \n");
539}
540
542{
544 DynList<string> r1; r1.append("a"); r1.append("b");
545 DynList<string> r2; r2.append("c"); r2.append("d");
546 mat.append(r1);
547 mat.append(r2);
548 auto s = Aleph::to_string(mat);
549 EXPECT_TRUE(contains(s, "a"));
550 EXPECT_TRUE(contains(s, "d"));
551
553 lines.append("x");
554 lines.append("y");
556}
557
559{
560 const auto justified = justify_text("a bb c ddd e", 7, 2);
561 EXPECT_EQ(justified, " a bb c\n ddd e");
562
564 ASSERT_EQ(lines.size(), 2u);
565 EXPECT_EQ(lines.nth(0).size(), 9u); // width + margin
566 EXPECT_EQ(lines.nth(1), " ddd e");
567
568 EXPECT_EQ(justify_text("encyclopedia x", 5), "encyclopedia\nx");
569 EXPECT_EQ(justify_text(" one\t two\nthree ", 6), "one\ntwo\nthree");
570}
571
573{
575 EXPECT_TRUE(is_double("-1.25"));
576 EXPECT_TRUE(is_double("6.022e23"));
577 EXPECT_TRUE(is_double(" +3.5"));
578
580 EXPECT_FALSE(is_double("1.2x"));
581 EXPECT_FALSE(is_double("3.14 "));
582 EXPECT_FALSE(is_double("1e309"));
583 EXPECT_FALSE(is_double("1e-5000"));
584 EXPECT_FALSE(is_double("nan"));
585 EXPECT_FALSE(is_double("inf"));
586
587 EXPECT_DOUBLE_EQ(safe_atof("0"), 0.0);
588 EXPECT_NEAR(safe_atof("-1.25e2"), -125.0, 1e-12);
589 EXPECT_NEAR(safe_atof(" +3.5"), 3.5, 1e-12);
590
591 EXPECT_THROW(safe_atof(""), runtime_error);
592 EXPECT_THROW(safe_atof("abc"), runtime_error);
593 EXPECT_THROW(safe_atof("1.2x"), runtime_error);
594 EXPECT_THROW(safe_atof("3.5 "), runtime_error);
595 EXPECT_THROW(safe_atof("1e309"), runtime_error);
596 EXPECT_THROW(safe_atof("1e-5000"), runtime_error);
597 EXPECT_THROW(safe_atof("nan"), runtime_error);
598 EXPECT_THROW(safe_atof("inf"), runtime_error);
599}
600
602{
603 auto w = split_text_into_words(" a\t b\n c ");
604 ASSERT_EQ(w.size(), 3u);
605 EXPECT_EQ(w.nth(0), "a");
606 EXPECT_EQ(w.nth(1), "b");
607 EXPECT_EQ(w.nth(2), "c");
608
609 auto l = split_text_into_lines("a\nb\n");
610 ASSERT_EQ(l.size(), 2u);
611 EXPECT_EQ(l.nth(0), "a");
612 EXPECT_EQ(l.nth(1), "b");
613}
614
616{
617 const string text = "one two three four five";
618 auto j = justify_line_except_first(text, 10, 4);
619 EXPECT_TRUE(contains(j, "one"));
620 EXPECT_TRUE(contains(j, "\n"));
621
622 auto a = align_text_to_left_except_first(text, 10, 3);
623 EXPECT_TRUE(contains(a, "one"));
624 EXPECT_TRUE(contains(a, "\n"));
625}
626
628{
629 const auto max_st = std::numeric_limits<size_t>::max();
630 EXPECT_TRUE(is_size_t(::std::to_string(max_st)));
631 EXPECT_FALSE(is_size_t(::std::to_string(max_st) + "0"));
632
633 const auto max_l = std::numeric_limits<long>::max();
634 const auto min_l = std::numeric_limits<long>::min();
635 EXPECT_TRUE(is_long(::std::to_string(max_l)));
636 EXPECT_TRUE(is_long(::std::to_string(min_l)));
637 EXPECT_FALSE(is_long(::std::to_string(max_l) + "0"));
638}
639
641{
642 const char *v = std::getenv("ALEPH_STRESS");
643 if (v == nullptr or *v == '\0')
644 return 1;
645
646 char *end = nullptr;
647 const long m = std::strtol(v, &end, 10);
648 if (end == v or *end != '\0')
649 return 1;
650
651 if (m < 1)
652 return 1;
653
654 if (m > 50)
655 return 50;
656
657 return int(m);
658}
659
660static string random_string(std::mt19937 & rng, size_t len)
661{
662 std::uniform_int_distribution<int> byte_dist(0, 255);
663 string s;
664 s.reserve(len);
665 for (size_t i = 0; i < len; ++i)
666 s.push_back(static_cast<char>(byte_dist(rng)));
667 return s;
668}
669
670static string random_ascii_token(std::mt19937 & rng, size_t len)
671{
672 static constexpr char alphabet[] =
673 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
674 std::uniform_int_distribution<int> pick(0, int(sizeof(alphabet) - 2));
675 string s;
676 s.reserve(len);
677 for (size_t i = 0; i < len; ++i)
678 s.push_back(alphabet[pick(rng)]);
679 return s;
680}
681
683{
684 std::mt19937 rng(12345);
685 for (int iter = 0; iter < 2000*stress_multiplier(); ++iter)
686 {
687 const auto s = random_ascii_token(rng, size_t(iter % 64));
688 for (size_t pos = 0; pos <= s.size(); ++pos)
689 {
690 auto p = split_pos(s, pos);
691 EXPECT_EQ(p.first + p.second, s);
692 EXPECT_EQ(p.first.size(), pos);
693 }
694 }
695}
696
698{
699 std::mt19937 rng(54321);
700 for (int iter = 0; iter < 1500*stress_multiplier(); ++iter)
701 {
702 const auto s = random_ascii_token(rng, 1 + size_t(iter % 128));
703 const size_t n = 1 + (size_t(iter) % std::min<size_t>(16, s.size()));
704 auto parts = split_n(s, n);
705 ASSERT_EQ(parts.size(), n);
706 string recomposed;
707 parts.for_each([&](const string &x) { recomposed += x; });
709
710 const size_t base = s.size() / n;
711 for (size_t i = 0; i + 1 < n; ++i)
712 EXPECT_EQ(parts.nth(i).size(), base);
713 }
714}
715
717{
718 std::mt19937 rng(999);
719 static const string delims = " _-";
720 for (int iter = 0; iter < 2000*stress_multiplier(); ++iter)
721 {
722 string s;
723 const size_t tokens = 1 + (size_t(iter) % 12);
724 for (size_t i = 0; i < tokens; ++i)
725 {
726 if (i)
727 s.push_back(delims[size_t(iter + int(i)) % delims.size()]);
728 s += random_ascii_token(rng, 1 + (size_t(iter + int(i)) % 10));
729 }
730
731 auto out = split_to_list(s, delims);
732 ASSERT_FALSE(out.is_empty());
733 out.for_each([&](const string &t)
734 {
735 EXPECT_FALSE(t.empty());
736 for (char c : delims)
737 EXPECT_EQ(t.find(c), string::npos);
738 });
739 }
740}
741
743{
744 std::mt19937 rng(1337);
745 static const string delim_pool = " ,;|/_-\t\n";
746 static const string token_pool =
747 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
748
749 std::uniform_int_distribution<int> delim_size_dist(0, 4);
750 std::uniform_int_distribution<int> delim_pick(0, int(delim_pool.size() - 1));
751 std::uniform_int_distribution<int> token_pick(0, int(token_pool.size() - 1));
752 std::uniform_int_distribution<int> text_len_dist(0, 128);
753 std::bernoulli_distribution use_delim(0.30);
754
755 for (int iter = 0; iter < 2000*stress_multiplier(); ++iter)
756 {
757 string delims;
758 const int dsz = delim_size_dist(rng);
759 for (int i = 0; i < dsz; ++i)
760 delims.push_back(delim_pool[size_t(delim_pick(rng))]);
761
762 string text;
763 const int len = text_len_dist(rng);
764 text.reserve(size_t(len));
765 for (int i = 0; i < len; ++i)
766 if (not delims.empty() and use_delim(rng))
767 text.push_back(delims[size_t(delim_pick(rng)) % delims.size()]);
768 else
769 text.push_back(token_pool[size_t(token_pick(rng))]);
770
771 const auto expected = reference_split_string(text, delims);
772 const auto list_out = split_to_list(text, delims);
773 const auto array_out = split_to_array(text, delims);
774
777 }
778}
779
781{
782 std::mt19937 rng(2024);
783 for (int iter = 0; iter < 3000*stress_multiplier(); ++iter)
784 {
785 auto s = random_string(rng, size_t(iter % 128));
786 auto lo = Aleph::to_lower(s);
787 auto up = Aleph::to_upper(s);
788 EXPECT_EQ(lo.size(), s.size());
789 EXPECT_EQ(up.size(), s.size());
790 }
791}
792
794{
795 std::mt19937 rng(77);
796 std::uniform_int_distribution<int> dist(-100000, 100000);
797
798 for (int iter = 0; iter < 2000*stress_multiplier(); ++iter)
799 {
800 const int a = dist(rng);
801 const int b = dist(rng);
802 const int c = dist(rng);
803
804 const auto got = ::Aleph::build_pars_list(a, b, c);
805 const auto expected = ::std::to_string(a) + ", " + ::std::to_string(b) + ", " + ::std::to_string(c);
807 }
808}
String manipulation utilities.
static string random_ascii_token(std::mt19937 &rng, size_t len)
static string random_string(std::mt19937 &rng, size_t len)
static DynList< string > reference_split_string(const string &s, const string &delim)
Splits a string into non-empty tokens using a set of delimiter characters.
static void expect_tokens_eq(const DynList< string > &expected, const DynList< string > &got)
Asserts that two DynList<string> contain the same tokens in the same order.
static int stress_multiplier()
long double w
Definition btreepic.C:153
size_t size_t int32_t * out
Definition ca-c-api.h:120
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
T & append(const T &data)
Append a copy of data
Definition tpl_array.H:250
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1065
Minimal std::expected-style result type for C++20.
Type & nth(const size_t n)
Return the n-th item of the container.
Definition ah-dry.H:308
Key * append(const Key &key)
Alias for insert() (copy version).
Definition hashDry.H:389
#define TEST(name)
static mt19937 rng
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
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.
std::string remove_prefix(std::string &str, const std::string &prefix)
Remove prefix from str if present.
std::string concat(const Args &...args)
Concatenate multiple arguments into a single std::string.
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.
and
Check uniqueness with explicit hash + equality functors.
bool contains(const std::string_view &str, const std::string_view &substr)
Check if substr appears inside str.
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).
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.
std::pair< First, Second > pair
Alias to std::pair kept for backwards compatibility.
Definition ahPair.H:89
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.
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.
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.
std::string & mutable_toupper(std::string &str)
Convert a std::string to upper-case in-place.
std::string only_alpha(const std::string &str)
Extract alphanumeric ASCII characters and normalize letters to lower-case.
STL namespace.
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
DynList< int > l