/* * ver. 1.7.3 * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com * Тесты simstr * (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com * Test of simstr */ #include #include using namespace std::literals; namespace simstr::tests { class Tstringa: public stringa { public: using stringa::stringa; bool isLocalString() const { return type_ == Local; } bool isConstantString() const { return type_ == Constant; } bool isSharedString() const { return type_ == Shared; } size_t sharedCount() const { return type_ == Shared ? SharedStringData::from_str(sstr_)->ref_.load() : 0u; } }; TEST(SimStr, CreateSimpleEmpty) { ssa testa{nullptr, 0}; EXPECT_TRUE(testa.is_empty()); EXPECT_EQ(testa.length(), 0u); ssw testw{nullptr, 0}; EXPECT_TRUE(testw.is_empty()); EXPECT_EQ(testw.length(), 0u); ssu testu{nullptr, 0}; EXPECT_TRUE(testu.is_empty()); EXPECT_EQ(testu.length(), 0u); ssuu testuu{nullptr, 0}; EXPECT_TRUE(testuu.is_empty()); EXPECT_EQ(testuu.length(), 0u); } TEST(SimStr, CompareSimpleEmptyEqual) { ssa testa{nullptr, 0}; EXPECT_TRUE(testa == ""); EXPECT_TRUE(testa != "test"); ssw testw{nullptr, 0}; EXPECT_TRUE(testw == L""); EXPECT_TRUE(testw != L"test"); ssu testu{nullptr, 0}; EXPECT_TRUE(testu == u""); EXPECT_TRUE(testu != u"test"); ssuu testuu{nullptr, 0}; EXPECT_TRUE(testuu == U""); EXPECT_TRUE(testuu != U"test"); } TEST(SimStr, CompareSimpleNonEmptyEqual) { ssa testa{"test"}; EXPECT_TRUE(testa == "test"); EXPECT_TRUE(testa != ""); ssw testw{L"test"}; EXPECT_TRUE(testw == L"test"); EXPECT_TRUE(testw != L""); ssu testu{u"test"}; EXPECT_TRUE(testu == u"test"); EXPECT_TRUE(testu != u""); ssuu testuu{U"test"}; EXPECT_TRUE(testuu == U"test"); EXPECT_TRUE(testuu != U""); } TEST(SimStr, CreateSimple) { ssa testa = "test"; EXPECT_EQ(testa, "test"); EXPECT_FALSE(testa.is_empty()); ssu testu = u"test"; EXPECT_EQ(testu, u"test"); EXPECT_FALSE(testu.is_empty()); ssw testw = L"test"; EXPECT_EQ(testw, L"test"); EXPECT_FALSE(testw.is_empty()); } TEST(SimStr, At) { ssa testa = "test"; EXPECT_EQ(testa.at(1), 'e'); EXPECT_EQ(testa.at(-1), 't'); EXPECT_EQ(testa.at(2), 's'); EXPECT_EQ(testa.at(-2), 's'); ssu testu{u"test"}; EXPECT_EQ(testu.at(1), u'e'); EXPECT_EQ(testu.at(-1), u't'); EXPECT_EQ(testu.at(2), u's'); EXPECT_EQ(testu.at(-2), u's'); ssw testw{L"test"}; EXPECT_EQ(testw.at(1), L'e'); EXPECT_EQ(testw.at(-1), L't'); EXPECT_EQ(testw.at(2), L's'); EXPECT_EQ(testw.at(-2), L's'); } TEST(SimStr, CompareSimpleAll) { ssa testa1{"test"}, testa2{"testa"}; EXPECT_TRUE(testa1 < "testa"); EXPECT_TRUE(testa1 < testa2); EXPECT_TRUE(testa2 > testa1); EXPECT_TRUE(testa1 > ""); EXPECT_TRUE(testa1 > "te"); EXPECT_TRUE("" < testa1); EXPECT_TRUE("te" < testa1); EXPECT_TRUE("test" == testa1); EXPECT_TRUE(testa1 != ""); EXPECT_TRUE(testa1 != testa2); EXPECT_EQ(testa1.compare(testa2), -1); EXPECT_EQ(testa2.compare(testa1), 1); EXPECT_EQ(testa1.compare(testa1), 0); testa2.len = testa1.length(); EXPECT_TRUE(testa1 == testa2); ssu testu1{u"test"}, testu2{u"testa"}; EXPECT_TRUE(testu1 < u"testa"); EXPECT_TRUE(testu1 < testu2); EXPECT_TRUE(testu2 > testu1); EXPECT_TRUE(testu1 > u""); EXPECT_TRUE(testu1 > u"te"); EXPECT_TRUE(u"" < testu1); EXPECT_TRUE(u"te" < testu1); EXPECT_TRUE(u"test" == testu1); EXPECT_TRUE(testu1 != u""); EXPECT_TRUE(testu1 != testu2); EXPECT_EQ(testu1.compare(testu2), -1); EXPECT_EQ(testu2.compare(testu1), 1); EXPECT_EQ(testu1.compare(testu1), 0); testu2.len = testu1.length(); EXPECT_TRUE(testu1 == testu2); ssw testw1{L"test"}, testw2{L"testa"}; EXPECT_TRUE(testw1 < L"testa"); EXPECT_TRUE(testw1 < testw2); EXPECT_TRUE(testw2 > testw1); EXPECT_TRUE(testw1 > L""); EXPECT_TRUE(testw1 > L"te"); EXPECT_TRUE(L"" < testw1); EXPECT_TRUE(L"te" < testw1); EXPECT_TRUE(L"test" == testw1); EXPECT_TRUE(testw1 != L""); EXPECT_TRUE(testw1 != testw2); EXPECT_EQ(testw1.compare(testw2), -1); EXPECT_EQ(testw2.compare(testw1), 1); EXPECT_EQ(testw1.compare(testw1), 0); testw2.len = testw1.length(); EXPECT_TRUE(testw1 == testw2); } TEST(SimStr, CompareSimpleAllIA) { ssa testa1{"tEst"}, testa2{"Testa"}; EXPECT_TRUE(testa1.equal_ia("test")); EXPECT_TRUE(testa1 > testa2); EXPECT_TRUE(testa1.compare_ia(testa2) < 0); ssu testu1{u"tEst"}, testu2{u"Testa"}; EXPECT_TRUE(testu1.equal_ia(u"test")); EXPECT_TRUE(testu1 > testu2); EXPECT_TRUE(testu1.compare_ia(testu2) < 0); ssw testw1{L"tEst"}, testw2{L"Testa"}; EXPECT_TRUE(testw1.equal_ia(L"test")); EXPECT_TRUE(testw1 > testw2); EXPECT_TRUE(testw1.compare_ia(testw2) < 0); ssuu testuu1{U"tEst"}, testuu2{U"Testa"}; EXPECT_TRUE(testuu1.equal_ia(U"test")); EXPECT_TRUE(testuu1 > testuu2); EXPECT_TRUE(testuu1.compare_ia(testuu2) < 0); } TEST(SimStr, CompareSimpleAllIU) { ssa testa1{"шоРох"}, testa2{"ШороХа"}; EXPECT_TRUE(testa1.equal_iu("Шорох")); EXPECT_TRUE(testa1 > testa2); EXPECT_TRUE(testa1.compare_iu(testa2) < 0); ssu testu1{u"шоРох"}, testu2{u"ШороХа"}; EXPECT_TRUE(testu1.equal_iu(u"Шорох")); EXPECT_TRUE(testu1 > testu2); EXPECT_TRUE(testu1.compare_iu(testu2) < 0); ssw testw1{L"шоРох"}, testw2{L"ШороХа"}; EXPECT_TRUE(testw1.equal_iu(L"Шорох")); EXPECT_TRUE(testw1 > testw2); EXPECT_TRUE(testw1.compare_iu(testw2) < 0); ssuu testuu1{U"шоРох"}, testuu2{U"ШороХа"}; EXPECT_TRUE(testuu1.equal_iu(U"Шорох")); EXPECT_TRUE(testuu1 > testuu2); EXPECT_TRUE(testuu1.compare_iu(testuu2) < 0); } TEST(SimStr, SimpleFind) { ssa testa = "Find a needle in a haystack"; EXPECT_EQ(testa.find("diamond"), str::npos); EXPECT_EQ(testa.find("needle"), 7u); EXPECT_EQ(testa.find("a"), 5u); EXPECT_EQ(testa.find("a", 8), 17u); EXPECT_EQ(testa.find('a'), 5u); EXPECT_EQ(testa.find('a', 8), 17u); EXPECT_EQ(testa.find_last('d'), 10u); auto res = testa.find_all("i"); EXPECT_EQ(res.size(), 2u); EXPECT_EQ(res[0], 1u); EXPECT_EQ(res[1], 14u); res = testa.find_all("i", 8); EXPECT_EQ(res.size(), 1u); EXPECT_EQ(res[0], 14u); res = testa.find_all("i", 1, 1); EXPECT_EQ(res.size(), 1u); EXPECT_EQ(res[0], 1u); ssu testu = u"Find a needle in a haystack"; EXPECT_EQ(testu.find(u"diamond"), str::npos); EXPECT_EQ(testu.find(u"needle"), 7u); EXPECT_EQ(testu.find(u"a"), 5u); EXPECT_EQ(testu.find(u"a", 8), 17u); EXPECT_EQ(testu.find(u'a'), 5u); EXPECT_EQ(testu.find(u'a', 8), 17u); EXPECT_EQ(testu.find_last(u'd'), 10u); res = testu.find_all(u"i"); EXPECT_EQ(res.size(), 2u); EXPECT_EQ(res[0], 1u); EXPECT_EQ(res[1], 14u); ssw testw = L"Find a needle in a haystack"; EXPECT_EQ(testw.find(L"diamond"), str::npos); EXPECT_EQ(testw.find(L"needle"), 7u); EXPECT_EQ(testw.find(L"a"), 5u); EXPECT_EQ(testw.find(L"a", 8), 17u); EXPECT_EQ(testw.find(L'a'), 5u); EXPECT_EQ(testw.find(L'a', 8), 17u); EXPECT_EQ(testw.find_last(L'd'), 10u); res = testw.find_all(L"i"); EXPECT_EQ(res.size(), 2u); EXPECT_EQ(res[0], 1u); EXPECT_EQ(res[1], 14u); EXPECT_EQ("cccabcccab"_ss.find_last("ab"), 8); EXPECT_EQ("cccabcccab"_ss.find_last("abc"), 3); EXPECT_EQ("cccabcccabcc"_ss.find_last("ab"), 8); EXPECT_EQ("cccabccccc"_ss.find_last("ab"), 3); EXPECT_EQ("cccabcccabcc"_ss.find_last("ab", 6), 3); EXPECT_EQ("abccccc"_ss.find_last("ab"), 0); } TEST(SimStr, SubPiece) { ssa testa{"test"}; EXPECT_EQ(testa(1), "est"); EXPECT_EQ(testa(1, 2), "es"); EXPECT_EQ(testa(1, -1), "es"); EXPECT_EQ(testa(1, -10), ""); ssu testu{u"test"}; EXPECT_EQ(testu(1), u"est"); EXPECT_EQ(testu(1, 2), u"es"); ssw testw{L"test"}; EXPECT_EQ(testw(1), L"est"); EXPECT_EQ(testw(1, 2), L"es"); } TEST(SimStr, SimpleSubstr) { ssa testa = "test"; EXPECT_EQ(testa.substr(1, 0), "est"); EXPECT_EQ(testa.substr(1, 2), "es"); EXPECT_EQ(testa.substr(0, -1), "tes"); EXPECT_EQ(testa.substr(-2), "st"); EXPECT_EQ(testa.substr(-3, 2), "es"); EXPECT_EQ(testa.substr(-3, -1), "es"); EXPECT_EQ(testa.str_mid(1), "est"); EXPECT_EQ(testa.str_mid(1, 0), ""); EXPECT_EQ(testa.str_mid(1, 2), "es"); EXPECT_EQ(testa.str_mid(2, 2), "st"); ssu testu = u"test"; EXPECT_EQ(testu.substr(1, 0), u"est"); EXPECT_EQ(testu.substr(1, 2), u"es"); EXPECT_EQ(testu.substr(0, -1), u"tes"); EXPECT_EQ(testu.substr(-2), u"st"); EXPECT_EQ(testu.substr(-3, 2), u"es"); EXPECT_EQ(testu.substr(-3, -1), u"es"); EXPECT_EQ(testu.str_mid(1), u"est"); EXPECT_EQ(testu.str_mid(1, 0), u""); EXPECT_EQ(testu.str_mid(1, 2), u"es"); EXPECT_EQ(testu.str_mid(2, 2), u"st"); ssw testw = L"test"; EXPECT_EQ(testw.substr(1, 0), L"est"); EXPECT_EQ(testw.substr(1, 2), L"es"); EXPECT_EQ(testw.substr(0, -1), L"tes"); EXPECT_EQ(testw.substr(-2), L"st"); EXPECT_EQ(testw.substr(-3, 2), L"es"); EXPECT_EQ(testw.substr(-3, -1), L"es"); EXPECT_EQ(testw.str_mid(1), L"est"); EXPECT_EQ(testw.str_mid(1, 0), L""); EXPECT_EQ(testw.str_mid(1, 2), L"es"); EXPECT_EQ(testw.str_mid(2, 2), L"st"); } TEST(SimStr, ToInt) { EXPECT_EQ(ssa{" 123"}.as_int(), 123); EXPECT_EQ(ssa{" 123"}(0, -1).as_int(), 12); EXPECT_EQ(ssa{"+123"}.as_int(), 123); EXPECT_EQ(ssa{" -123aa"}.as_int(), -123); EXPECT_EQ(ssa{"123"}.as_int(), 123u); EXPECT_EQ(ssa{"-123"}.as_int(), 0u); EXPECT_EQ(ssa{" 0123 "}.as_int(), 0123); EXPECT_EQ(ssa{"-0x123"}.as_int(), -0x123); { auto [number, err, len] = ssa{"asd"}.to_int(); EXPECT_EQ(number, 0); EXPECT_EQ(err, IntConvertResult::NotNumber); EXPECT_EQ(len, 0u); } { auto [number, err, len] = ssa{"0"}.to_int(); EXPECT_EQ(number, 0); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 1u); } { auto [number, err, len] = ssa{"1"}.to_int(); EXPECT_EQ(number, 1); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 1u); } { auto [number, err, len] = ssa{"-"}.to_int(); EXPECT_EQ(number, 0); EXPECT_EQ(err, IntConvertResult::NotNumber); EXPECT_EQ(len, 1u); } { auto [number, err, len] = ssa{"+"}.to_int(); EXPECT_EQ(number, 0); EXPECT_EQ(err, IntConvertResult::NotNumber); EXPECT_EQ(len, 1u); } { auto [number, err, len] = ssa{"-0"}.to_int(); EXPECT_EQ(number, 0); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 2u); } { auto [number, err, len] = ssa{"+0"}.to_int(); EXPECT_EQ(number, 0); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 2u); } { auto [number, err, len] = ssa{"-0sd"}.to_int(); EXPECT_EQ(number, 0); EXPECT_EQ(err, IntConvertResult::BadSymbolAtTail); EXPECT_EQ(len, 2u); } { auto [number, err, len] = ssa{"1234"}.to_int(); EXPECT_EQ(err, IntConvertResult::Overflow); EXPECT_EQ(len, 4u); } { auto [number, err, len] = ssa{"128"}.to_int(); EXPECT_EQ(err, IntConvertResult::Overflow); EXPECT_EQ(len, 3u); } { auto [number, err, len] = ssa{"127"}.to_int(); EXPECT_EQ(number, 127); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 3u); } { auto [number, err, len] = ssa{"-128"}.to_int(); EXPECT_EQ(number, -128); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 4u); } { auto [number, err, len] = ssa{"0xFFFfffFF"}.to_int(); EXPECT_EQ(number, 0xFFFFFFFF); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 10u); } { auto [number, err, len] = ssa{"0x"}.to_int(); EXPECT_EQ(number, 0u); EXPECT_EQ(err, IntConvertResult::NotNumber); EXPECT_EQ(len, 2u); } { auto [number, err, len] = ssa{"0xS"}.to_int(); EXPECT_EQ(number, 0u); EXPECT_EQ(err, IntConvertResult::NotNumber); EXPECT_EQ(len, 2u); } { auto [number, err, len] = ssa{"-0x80000000"}.to_int(); EXPECT_EQ(number, -2147483648); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 11u); } { auto [number, err, len] = ssa{"-0x80000001"}.to_int(); EXPECT_EQ(err, IntConvertResult::Overflow); EXPECT_EQ(len, 11u); } { auto [number, err, len] = ssa{"-0x80000001"}.to_int(); EXPECT_EQ(number, -2147483649); EXPECT_EQ(err, IntConvertResult::Success); EXPECT_EQ(len, 11u); } EXPECT_EQ(ssu{u" 123"}.as_int(), 123); EXPECT_EQ(ssu{u"+123"}.as_int(), 123); EXPECT_EQ(ssu{u" -123aa"}.as_int(), -123); EXPECT_EQ(ssu{u"123"}.as_int(), 123u); EXPECT_EQ(ssu{u"-123"}.as_int(), 0u); EXPECT_EQ(ssu{u" 0123 "}.as_int(), 0123); EXPECT_EQ(ssu{u"-0x123"}.as_int(), -0x123); EXPECT_EQ(ssw{L" 123"}.as_int(), 123); EXPECT_EQ(ssw{L"+123"}.as_int(), 123); EXPECT_EQ(ssw{L" -123aa"}.as_int(), -123); EXPECT_EQ(ssw{L"123"}.as_int(), 123u); EXPECT_EQ(ssw{L"-123"}.as_int(), 0u); EXPECT_EQ(ssw{L" 0123 "}.as_int(), 0123); EXPECT_EQ(ssw{L"-0x123"}.as_int(), -0x123); int num1; uint64_t num2; double num3; ssa{"-10"}.as_number(num1); EXPECT_EQ(num1, -10); ssa{"0xDeadBeef"}.as_number(num2); EXPECT_EQ(num2, 0xdeadbeef); ssa{"0.128"}.as_number(num3); EXPECT_EQ(num3, 0.128); } TEST(SimStr, to_double) { EXPECT_EQ(ssa{" 123"}.to_double(), 123.0); EXPECT_EQ(ssa{" 123.1"}.to_double(), 123.1); EXPECT_EQ(ssb{u8" 123"}.to_double(), 123.0); EXPECT_EQ(ssb{u8" 123.1"}.to_double(), 123.1); EXPECT_EQ(ssu{u" 123.13434"}.to_double(), 123.13434); EXPECT_EQ(ssuu{U" 123.13434"}.to_double(), 123.13434); EXPECT_EQ(ssw{L" 123.13434"}.to_double(), 123.13434); EXPECT_EQ(ssa{" -123"}.to_double(), -123.0); EXPECT_EQ(ssa{" +123.12"}.to_double(), 123.12); EXPECT_EQ(ssu{u" 123.134e5"}.to_double(), 123.134e5); EXPECT_EQ(ssuu{U" 123.13E-2"}.to_double(), 123.13e-2); EXPECT_EQ(ssa{" ab.1fp4"}.to_double_hex(), 0xab.1fp4); } TEST(SimStr, Split) { auto res = ssa{"1,2,3"}.split>(","); EXPECT_EQ(res.size(), 3u); EXPECT_EQ(res[0], "1"); EXPECT_EQ(res[1], "2"); EXPECT_EQ(res[2], "3"); } TEST(SimStr, Parts) { ssa test = "prefixВСтрокеSuffix"; EXPECT_TRUE(test.starts_with("prefix")); EXPECT_TRUE(test.ends_with("Suffix")); EXPECT_TRUE(ssa{"prefix"}.prefix_in(test)); EXPECT_FALSE(ssa{"prefix"}.starts_with("prefixa")); EXPECT_FALSE(test.starts_with("predix")); EXPECT_FALSE(test.ends_with("suffex")); EXPECT_FALSE(ssa{"predix"}.prefix_in(test)); EXPECT_TRUE(test.starts_with_ia("Prefix")); EXPECT_TRUE(test.ends_with_ia("suffix")); EXPECT_TRUE(test.starts_with_iu("Prefixвс")); EXPECT_TRUE(test.ends_with_iu("КЕsuffix")); } TEST(SimStr, IsAscii) { ssa test = "prefixВСтрокеSuffix"; EXPECT_FALSE(test.is_ascii()); EXPECT_TRUE(ssa{"1234567812345678124"}.is_ascii()); EXPECT_TRUE(ssa{"asldkafjk^%&*&623216187263&^hjgaiu&&!^@*^?>"}.is_ascii()); } TEST(SimStr, ChangeCase) { EXPECT_EQ(ssa{"TEST"}.upperred_only_ascii(), "TEST"); EXPECT_EQ(ssa{"Test"}.upperred_only_ascii(), "TEST"); EXPECT_EQ(ssa{"test"}.lowered_only_ascii(), "test"); EXPECT_EQ(ssa{"Test"}.lowered_only_ascii(), "test"); EXPECT_EQ(ssa{"TestПрОвЕрКа"}.upperred_only_ascii(), "TESTПрОвЕрКа"); EXPECT_EQ(ssa{"TestПрОвЕрКа"}.lowered_only_ascii(), "testПрОвЕрКа"); EXPECT_EQ(ssa{"TestПрОвЕрКа"}.upperred(), "TESTПРОВЕРКА"); EXPECT_EQ(ssa{"tesTПрОвЕрКа"}.lowered(), "testпроверка"); EXPECT_EQ(ssa{"TEST"}.upperred(), "TEST"); EXPECT_EQ(ssa{"test"}.lowered(), "test"); EXPECT_EQ(ssa{"TESTПРОВЕРКА"}.upperred(), "TESTПРОВЕРКА"); EXPECT_EQ(ssa{"testпроверка"}.lowered(), "testпроверка"); EXPECT_EQ(ssa{"tesTİiȺⱥȾⱦẞßΩФывAsd"}.lowered(), "testiiⱥⱥⱦⱦßßωфывasd"); EXPECT_EQ(ssa{"testⱢɱⱮɽⱤWas"}.upperred(), "TESTⱢⱮⱮⱤⱤWAS"); EXPECT_EQ(ssu{u"TEST"}.upperred_only_ascii(), u"TEST"); EXPECT_EQ(ssu{u"test"}.lowered_only_ascii(), u"test"); EXPECT_EQ(ssu{u"Test"}.upperred_only_ascii(), u"TEST"); EXPECT_EQ(ssu{u"Test"}.lowered_only_ascii(), u"test"); EXPECT_EQ(ssu{u"TestПрОвЕрКа"}.upperred_only_ascii(), u"TESTПрОвЕрКа"); EXPECT_EQ(ssu{u"TestПрОвЕрКа"}.lowered_only_ascii(), u"testПрОвЕрКа"); EXPECT_EQ(ssu{u"TestПрОвЕрКа"}.upperred(), u"TESTПРОВЕРКА"); EXPECT_EQ(ssu{u"tesTПрОвЕрКа"}.lowered(), u"testпроверка"); EXPECT_EQ(ssu{u"tesTİiȺⱥȾⱦẞßΩФывAsd"}.lowered(), u"testiiⱥⱥⱦⱦßßωфывasd"); EXPECT_EQ(ssu{u"testⱢɱⱮɽⱤWas"}.upperred(), u"TESTⱢⱮⱮⱤⱤWAS"); EXPECT_EQ(ssw{L"TEST"}.upperred_only_ascii(), L"TEST"); EXPECT_EQ(ssw{L"test"}.lowered_only_ascii(), L"test"); EXPECT_EQ(ssw{L"Test"}.upperred_only_ascii(), L"TEST"); EXPECT_EQ(ssw{L"Test"}.lowered_only_ascii(), L"test"); EXPECT_EQ(ssw{L"TestПрОвЕрКа"}.upperred_only_ascii(), L"TESTПрОвЕрКа"); EXPECT_EQ(ssw{L"TestПрОвЕрКа"}.lowered_only_ascii(), L"testПрОвЕрКа"); EXPECT_EQ(ssw{L"TestПрОвЕрКа"}.upperred(), L"TESTПРОВЕРКА"); EXPECT_EQ(ssw{L"tesTПрОвЕрКа"}.lowered(), L"testпроверка"); EXPECT_EQ(ssw{L"tesTİiȺⱥȾⱦẞßΩФывAsd"}.lowered(), L"testiiⱥⱥⱦⱦßßωфывasd"); EXPECT_EQ(ssw{L"testⱢɱⱮɽⱤWas"}.upperred(), L"TESTⱢⱮⱮⱤⱤWAS"); } TEST(SimStr, Replace) { EXPECT_EQ(ssa{"testing"}.replaced("t", "--"), "--es--ing"); EXPECT_EQ(ssa{"testing"}.replaced("t", ""), "esing"); EXPECT_EQ(stringa{e_repl(ssa{"testing"}, "t", "--")}, "--es--ing"); } TEST(SimStr, Trim) { EXPECT_EQ(ssa{"testing"}.trimmed(), "testing"); EXPECT_EQ(ssa{" \ttesting "}.trimmed(), "testing"); EXPECT_EQ(ssa{" \ttesting "}.trimmed_left(), "testing "); EXPECT_EQ(ssa{" \ttesting "}.trimmed_right(), " \ttesting"); EXPECT_EQ(ssa{"testing"}.trimmed("tg"), "estin"); EXPECT_EQ(ssa{"testing"}.trimmed_left("tg"), "esting"); EXPECT_EQ(ssa{"testing"}.trimmed_right("tg"), "testin"); EXPECT_EQ(ssa{" \ttesting "}.trimmed_with_spaces("tg"), "estin"); EXPECT_EQ(ssa{" \ttesting "}.trimmed_left_with_spaces("tg"), "esting "); EXPECT_EQ(ssa{" \ttesting "}.trimmed_right_with_spaces("tg"), " \ttestin"); EXPECT_EQ(ssa{"testing"}.trimmed(ssa{"tg"}), "estin"); EXPECT_EQ(ssa{"testing"}.trimmed_left(ssa{"tg"}), "esting"); EXPECT_EQ(ssa{"testing"}.trimmed_right(ssa{"tg"}), "testin"); EXPECT_EQ(ssa{" \ttesting "}.trimmed_with_spaces(ssa{"tg"}), "estin"); EXPECT_EQ(ssa{" \ttesting "}.trimmed_left_with_spaces(ssa{"tg"}), "esting "); EXPECT_EQ(ssa{" \ttesting "}.trimmed_right_with_spaces(ssa{"tg"}), " \ttestin"); } TEST(SimStr, CreateSstringEmpty) { stringa testa; EXPECT_EQ(testa.length(), 0u); EXPECT_EQ(testa, ""); EXPECT_TRUE(testa.is_empty()); stringu testu; EXPECT_EQ(testu.length(), 0u); EXPECT_EQ(testu, u""); EXPECT_TRUE(testu.is_empty()); stringw testw; EXPECT_EQ(testw.length(), 0u); EXPECT_EQ(testw, L""); EXPECT_TRUE(testw.is_empty()); } TEST(SimStr, CreateSstringFromLiteral) { stringa testa{"testФыва"}; EXPECT_EQ(testa, "testФыва"); EXPECT_FALSE(testa.is_empty()); stringu testu{u"test"}; EXPECT_EQ(testu, u"test"); EXPECT_FALSE(testu.is_empty()); stringw testw{L"test"}; EXPECT_EQ(testw, L"test"); EXPECT_FALSE(testw.is_empty()); } TEST(SimStr, CreateSstringCopy) { stringa testa{"test"}; stringa copya{testa}; EXPECT_EQ(copya, testa); EXPECT_EQ(copya, "test"); EXPECT_FALSE(testa.is_empty()); EXPECT_FALSE(copya.is_empty()); stringu testu{u"test"}; stringu copyw{testu}; EXPECT_EQ(copyw, testu); EXPECT_EQ(copyw, u"test"); EXPECT_FALSE(testu.is_empty()); EXPECT_FALSE(copyw.is_empty()); stringw testw{L"test"}; stringw copyu{testw}; EXPECT_EQ(copyu, testw); EXPECT_EQ(copyu, L"test"); EXPECT_FALSE(testw.is_empty()); EXPECT_FALSE(copyu.is_empty()); } TEST(SimStr, CreateSstringCopy1) { { Tstringa sample = "sample"; stra ptov = sample; EXPECT_TRUE(sample.isConstantString()); Tstringa copy1{sample}; EXPECT_TRUE(copy1.isConstantString()); EXPECT_TRUE(sample.to_str().is_same(copy1.to_str())); EXPECT_EQ(sample.sharedCount(), 0u); EXPECT_EQ(copy1.sharedCount(), 0u); } { Tstringa sample{2, "sample"}; EXPECT_FALSE(sample.isConstantString()); EXPECT_TRUE(sample.isLocalString()); Tstringa copy1{sample}; EXPECT_TRUE(copy1.isLocalString()); EXPECT_FALSE(sample.to_str().is_same(copy1.to_str())); EXPECT_EQ(sample.sharedCount(), 0u); EXPECT_EQ(copy1.sharedCount(), 0u); } { Tstringa sample{10, "sample"}; EXPECT_FALSE(sample.isConstantString()); EXPECT_FALSE(sample.isLocalString()); EXPECT_TRUE(sample.isSharedString()); EXPECT_EQ(sample.sharedCount(), 1u); Tstringa copy1{sample}; EXPECT_TRUE(copy1.isSharedString()); EXPECT_TRUE(sample.to_str().is_same(copy1.to_str())); EXPECT_EQ(sample.sharedCount(), 2u); EXPECT_EQ(copy1.sharedCount(), 2u); } { lstringsa<10> sample{10, "sample"}; EXPECT_FALSE(sample.is_empty()); Tstringa copy1{sample}; EXPECT_FALSE(sample.is_empty()); EXPECT_TRUE(copy1.isSharedString()); EXPECT_EQ(copy1.sharedCount(), 1u); } { lstringsa<10> sample{10, "sample"}; EXPECT_FALSE(sample.is_empty()); Tstringa copy1{std::move(sample)}; EXPECT_TRUE(sample.is_empty()); EXPECT_TRUE(copy1.isSharedString()); EXPECT_EQ(copy1.sharedCount(), 1u); Tstringa new_copy = copy1; EXPECT_TRUE(new_copy.isSharedString()); EXPECT_EQ(copy1.sharedCount(), 2u); EXPECT_EQ(new_copy.sharedCount(), 2u); EXPECT_EQ(copy1.c_str(), new_copy.c_str()); } } TEST(SimStr, CreateSstringMove) { stringa testa{"test"}; stringa copya{std::move(testa)}; EXPECT_NE(copya, testa); EXPECT_EQ(copya, "test"); EXPECT_TRUE(testa.is_empty()); EXPECT_FALSE(copya.is_empty()); stringu testu{u"test"}; stringu copyu{std::move(testu)}; EXPECT_NE(copyu, testu); EXPECT_EQ(copyu, u"test"); EXPECT_TRUE(testu.is_empty()); EXPECT_FALSE(copyu.is_empty()); stringw testw{L"test"}; stringw copyw{std::move(testw)}; EXPECT_NE(copyw, testw); EXPECT_EQ(copyw, L"test"); EXPECT_TRUE(testw.is_empty()); EXPECT_FALSE(copyw.is_empty()); } TEST(SimStr, CreateSstringChars) { stringa testa{4, 'a'}; EXPECT_EQ(testa, "aaaa"); stringu testu{4, u'a'}; EXPECT_EQ(testu, u"aaaa"); stringw testw{4, L'a'}; EXPECT_EQ(testw, L"aaaa"); } TEST(SimStr, CreateSstringsimple_string) { ssa sa{"test"}; stringa testa{sa}; EXPECT_EQ(testa, "test"); ssu sw{u"test"}; stringu testu{sw}; EXPECT_EQ(testu, u"test"); ssw su{L"test"}; stringw testw{su}; EXPECT_EQ(testw, L"test"); } TEST(SimStr, CreateSstringsimple_stringRepeat) { ssa sa{"test"}; stringa testa{3, sa}; EXPECT_EQ(testa, "testtesttest"); ssu sw{u"test"}; stringu testu{3, sw}; EXPECT_EQ(testu, u"testtesttest"); ssw su{L"test"}; stringw testw{3, su}; EXPECT_EQ(testw, L"testtesttest"); } TEST(SimStr, CreateSstringLong) { ssa sa{"test"}; stringa testa{10, sa}; EXPECT_EQ(testa, "testtesttesttesttesttesttesttesttesttest"); } TEST(SimStr, CreateSstringStrExpr) { EXPECT_EQ(stringa{"test"_ss + 101 + e_c(3, 'a')}, "test101aaa"); EXPECT_EQ(stringu{u"test"_ss + 1234 + e_c(3, u'a')}, u"test1234aaa"); EXPECT_EQ(stringw{L"test"_ss + 12345 + e_c(3, L'a')}, L"test12345aaa"); } TEST(SimStr, CreateSstringReplace) { EXPECT_EQ(stringa(ssa("tratata"), "t", ""), "raaa"); EXPECT_EQ(stringa(ssa("tratata"), "t", "-"), "-ra-a-a"); EXPECT_EQ(stringa(ssa("tratata"), "t", ">>"), ">>ra>>a>>a"); EXPECT_EQ(stringu(ssu(u"tratata"), u"t", u""), u"raaa"); EXPECT_EQ(stringu(ssu(u"tratata"), u"t", u"-"), u"-ra-a-a"); EXPECT_EQ(stringu(ssu(u"tratata"), u"t", u">>"), u">>ra>>a>>a"); EXPECT_EQ(stringw(ssw(L"tratata"), L"t", L""), L"raaa"); EXPECT_EQ(stringw(ssw(L"tratata"), L"t", L"-"), L"-ra-a-a"); EXPECT_EQ(stringw(ssw(L"tratata"), L"t", L">>"), L">>ra>>a>>a"); } TEST(SimStr, AssignSstring) { stringa test{"test"}; EXPECT_EQ(test = test, "test"); EXPECT_EQ(test = "next", "next"); EXPECT_EQ(test = ssa{"other"}, "other"); EXPECT_EQ(test = stringa{"trtr"_ss + 10}, "trtr10"); EXPECT_EQ(test = "trtr"_ss + 20, "trtr20"); EXPECT_EQ(test = test(2), "tr20"); EXPECT_EQ(test = lstringa<10>{"func"}, "func"); EXPECT_EQ(test = lstringsa<10>{"func"}, "func"); lstringsa<10> sample{15, "1234"}; Tstringa t = sample; EXPECT_TRUE(t.isSharedString()); EXPECT_EQ(t.sharedCount(), 1u); EXPECT_FALSE(sample.is_empty()); EXPECT_EQ(sample.length(), 60u); EXPECT_EQ(sample, t.to_str()); t = std::move(sample); EXPECT_TRUE(t.isSharedString()); EXPECT_EQ(t.sharedCount(), 1u); EXPECT_TRUE(sample.is_empty()); EXPECT_EQ(sample.symbols()[0], 0); EXPECT_EQ(t.length(), 60u); } TEST(SimStr, StrJoin) { EXPECT_EQ(stringa::join(std::vector{}, "-"), ""); EXPECT_EQ(stringa::join(std::vector{"abc"}, "-"), "abc"); EXPECT_EQ(stringa::join(std::vector{"abc"}, "-", true), "abc-"); EXPECT_EQ(stringa::join(std::vector{"abc", "def", "ghi"}, "-"), "abc-def-ghi"); EXPECT_EQ(stringa::join(std::vector{"abc", "def", "ghi"}, "-", true), "abc-def-ghi-"); } TEST(SimStr, LStringCreate) { lstringa<40> test; EXPECT_TRUE(test.is_empty()); EXPECT_EQ(test, ""); EXPECT_EQ(test.length(), 0u); } TEST(SimStr, LStringCreateLiteral) { lstringa<40> test{"test"}; EXPECT_FALSE(test.is_empty()); EXPECT_EQ(test, "test"); EXPECT_EQ(test.length(), 4u); } TEST(SimStr, LStringCreatesimple_str) { lstringa<40> test{ssa{"test"}}; EXPECT_FALSE(test.is_empty()); EXPECT_EQ(test, "test"); EXPECT_EQ(test.length(), 4u); } TEST(SimStr, LStringCreateCopy) { lstringa<40> test{"test"}; lstringa<40> copy{test}; EXPECT_EQ(test, copy); EXPECT_EQ(copy, "test"); } TEST(SimStr, LStringCreateMove) { lstringa<40> test{"test"}; lstringa<40> copy{std::move(test)}; EXPECT_NE(test, copy); EXPECT_EQ(copy, "test"); EXPECT_TRUE(test.is_empty()); EXPECT_FALSE(copy.is_empty()); EXPECT_EQ(test.symbols()[0], 0); } TEST(SimStr, LStringCreateCopyOtherSize) { lstringa<10> test{"test"}; lstringa<40> copy{test}; EXPECT_EQ(test.to_str(), copy); EXPECT_EQ(copy, "test"); } TEST(SimStr, LStringCreatePad) { lstringa<10> test{5, 'a'}; EXPECT_EQ(test, "aaaaa"); } TEST(SimStr, LStringCreateExpr) { lstringa<40> test{"test" + e_num(10) + "-" + 20 + e_spca<3>()}; EXPECT_FALSE(test.is_empty()); EXPECT_EQ(test, "test10-20 "); } TEST(SimStr, LStringCreateFunc) { EXPECT_EQ(lstringa<20>{[](auto& t) { t = "test";}}, "test"); EXPECT_EQ(lstringa<20>{[](auto p, size_t l) { EXPECT_EQ(l, lstringa<20>::LocalCapacity); memcpy(p, "test", std::size("test") - 1); return std::size("test") - 1; }}, "test"); } TEST(SimStr, LStringCreateSstring) { { lstringa<40> test{stringa{"test"}}; EXPECT_FALSE(test.is_empty()); EXPECT_EQ(test, "test"); EXPECT_EQ(test.length(), 4u); } { stringa t{"test"}; lstringa<40> test{t}; EXPECT_FALSE(test.is_empty()); EXPECT_FALSE(t.is_empty()); EXPECT_EQ(test, "test"); EXPECT_EQ(test.length(), 4u); } } TEST(SimStr, LStringAssign) { { lstringa<40> test{"test"}; EXPECT_EQ(test, "test"); test = ""; EXPECT_EQ(test, ""); test = "test"; EXPECT_EQ(test, "test"); } { lstringa<40> test{"test"}; EXPECT_EQ(test, "test"); const auto& t = test; test = t; EXPECT_EQ(test, "test"); test = lstringa<1>{"next step"}; EXPECT_EQ(test, "next step"); test = test(0); EXPECT_EQ(test, "next step"); test = test(1, 2); EXPECT_EQ(test, "ex"); test = e_c(100, 'a'); EXPECT_EQ(test.length(), 100u); lstringa<40> src{"test"}; test = std::move(src); EXPECT_EQ(test, "test"); EXPECT_TRUE(src.is_empty()); test = e_spca<3>(); EXPECT_EQ(test, " "); } } TEST(SimStr, UtfConvert) { EXPECT_EQ(stringa{ssu{u"testпройден"}}, "testпройден"); EXPECT_EQ(stringa{ssb{u8"testпройден"}}, "testпройден"); EXPECT_EQ(stringa{ssw{L"testпройден"}}, "testпройден"); EXPECT_EQ(stringa{stringu{u"testпройден"}}, "testпройден"); EXPECT_EQ(stringa{stringw{L"testпройден"}}, "testпройден"); EXPECT_EQ(stringa{lstringu<40>{u"testпройден"}}, "testпройден"); EXPECT_EQ(stringa{lstringw<40>{L"testпройден"}}, "testпройден"); EXPECT_EQ(stringb{ssu{u"testпройден"}}, u8"testпройден"); EXPECT_EQ(stringb{ssa{u8"testпройден"}}, u8"testпройден"); EXPECT_EQ(stringb{ssw{L"testпройден"}}, u8"testпройден"); EXPECT_EQ(stringb{stringu{u"testпройден"}}, u8"testпройден"); EXPECT_EQ(stringb{stringw{L"testпройден"}}, u8"testпройден"); EXPECT_EQ(stringb{lstringu<40>{u"testпройден"}}, u8"testпройден"); EXPECT_EQ(stringb{lstringw<40>{L"testпройден"}}, u8"testпройден"); EXPECT_EQ(stringu{ssa{"testпройден"}}, u"testпройден"); EXPECT_EQ(stringu{ssb{u8"testпройден"}}, u"testпройден"); EXPECT_EQ(stringu{ssw{L"testпройден"}}, u"testпройден"); EXPECT_EQ(stringu{stringa{"testпройден"}}, u"testпройден"); EXPECT_EQ(stringu{stringw{L"testпройден"}}, u"testпройден"); EXPECT_EQ(stringu{lstringa<40>{"testпройден"}}, u"testпройден"); EXPECT_EQ(stringu{lstringw<40>{L"testпройден"}}, u"testпройден"); EXPECT_EQ(stringw{ssa{"testпройден"}}, L"testпройден"); EXPECT_EQ(stringw{ssu{u"testпройден"}}, L"testпройден"); EXPECT_EQ(stringw{stringa{"testпройден"}}, L"testпройден"); EXPECT_EQ(stringw{stringu{u"testпройден"}}, L"testпройден"); EXPECT_EQ(stringw{lstringa<40>{"testпройден"}}, L"testпройден"); EXPECT_EQ(stringw{lstringu<40>{u"testпройден"}}, L"testпройден"); EXPECT_EQ(lstringa<10>{ssu{u"testпройден"}}, "testпройден"); EXPECT_EQ(lstringa<10>{ssw{L"testпройден"}}, "testпройден"); EXPECT_EQ(lstringa<10>{stringu{u"testпройден"}}, "testпройден"); EXPECT_EQ(lstringa<10>{stringw{L"testпройден"}}, "testпройден"); EXPECT_EQ(lstringa<10>{lstringu<40>{u"testпройден"}}, "testпройден"); EXPECT_EQ(lstringa<10>{lstringw<40>{L"testпройден"}}, "testпройден"); EXPECT_EQ(lstringu<10>{ssa{"testпройден"}}, u"testпройден"); EXPECT_EQ(lstringu<10>{ssw{L"testпройден"}}, u"testпройден"); EXPECT_EQ(lstringu<10>{stringa{"testпройден"}}, u"testпройден"); EXPECT_EQ(lstringu<10>{stringw{L"testпройден"}}, u"testпройден"); EXPECT_EQ(lstringu<10>{lstringa<40>{"testпройден"}}, u"testпройден"); EXPECT_EQ(lstringu<10>{lstringw<40>{L"testпройден"}}, u"testпройден"); EXPECT_EQ(lstringw<10>{ssa{"testпройден"}}, L"testпройден"); EXPECT_EQ(lstringw<10>{ssu{u"testпройден"}}, L"testпройден"); EXPECT_EQ(lstringw<10>{stringa{"testпройден"}}, L"testпройден"); EXPECT_EQ(lstringw<10>{stringu{u"testпройден"}}, L"testпройден"); EXPECT_EQ(lstringw<10>{lstringa<40>{"testпройден"}}, L"testпройден"); EXPECT_EQ(lstringw<10>{lstringu<40>{u"testпройден"}}, L"testпройден"); } TEST(SimStr, LStrChangeCase) { EXPECT_EQ(lstringa<20>{"Test"}.upper_only_ascii(), "TEST"); EXPECT_EQ(lstringa<20>{"Test"}.lower_only_ascii(), "test"); EXPECT_EQ(lstringa<20>{"TestПрОвЕрКа"}.upper_only_ascii(), "TESTПрОвЕрКа"); EXPECT_EQ(lstringa<20>{"TestПрОвЕрКа"}.lower_only_ascii(), "testПрОвЕрКа"); EXPECT_EQ(lstringa<20>{"TestПрОвЕрКа"}.upper(), "TESTПРОВЕРКА"); EXPECT_EQ(lstringa<20>{"tesTПрОвЕрКа"}.lower(), "testпроверка"); EXPECT_EQ(lstringa<20>{"tesTİiȺⱥȾⱦẞßΩФывAsd"}.lower(), "testiiⱥⱥⱦⱦßßωфывasd"); EXPECT_EQ(lstringa<20>{"testⱢɱⱮɽⱤWas"}.upper(), "TESTⱢⱮⱮⱤⱤWAS"); EXPECT_EQ(lstringu<20>{u"Test"}.upper_only_ascii(), u"TEST"); EXPECT_EQ(lstringu<20>{u"Test"}.lower_only_ascii(), u"test"); EXPECT_EQ(lstringu<20>{u"TestПрОвЕрКа"}.upper_only_ascii(), u"TESTПрОвЕрКа"); EXPECT_EQ(lstringu<20>{u"TestПрОвЕрКа"}.lower_only_ascii(), u"testПрОвЕрКа"); EXPECT_EQ(lstringu<20>{u"TestПрОвЕрКа"}.upper(), u"TESTПРОВЕРКА"); EXPECT_EQ(lstringu<20>{u"tesTПрОвЕрКа"}.lower(), u"testпроверка"); EXPECT_EQ(lstringu<20>{u"tesTİiȺⱥȾⱦẞßΩФывAsd"}.lower(), u"testiiⱥⱥⱦⱦßßωфывasd"); EXPECT_EQ(lstringu<20>{u"testⱢɱⱮɽⱤWas"}.upper(), u"TESTⱢⱮⱮⱤⱤWAS"); } TEST(SimStr, LStrTrim) { EXPECT_EQ(lstringa<20>{"testing"}.trim(), "testing"); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim(), "testing"); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim_left(), "testing "); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim_right(), " \ttesting"); EXPECT_EQ(lstringa<20>{"testing"}.trim("tg"), "estin"); EXPECT_EQ(lstringa<20>{"testing"}.trim_left("tg"), "esting"); EXPECT_EQ(lstringa<20>{"testing"}.trim_right("tg"), "testin"); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim_with_spaces("tg"), "estin"); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim_left_with_spaces("tg"), "esting "); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim_right_with_wpaces("tg"), " \ttestin"); EXPECT_EQ(lstringa<20>{"testing"}.trim(ssa{"tg"}), "estin"); EXPECT_EQ(lstringa<20>{"testing"}.trim_left(ssa{"tg"}), "esting"); EXPECT_EQ(lstringa<20>{"testing"}.trim_right(ssa{"tg"}), "testin"); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim_with_spaces(ssa{"tg"}), "estin"); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim_left_with_spaces(ssa{"tg"}), "esting "); EXPECT_EQ(lstringa<20>{" \ttesting "}.trim_right_with_spaces(ssa{"tg"}), " \ttestin"); } TEST(SimStr, LStrAppend) { EXPECT_EQ(lstringa<20>{"test"}.append("ing"), "testing"); EXPECT_EQ(lstringa<20>{"test"}.append("ing"_ss + 10), "testing10"); EXPECT_EQ(lstringa<20>{"test"}.append_in(3, "ing"), "tesing"); EXPECT_EQ(lstringa<20>{"test"}.append_in(3, "ing"_ss + 10), "tesing10"); EXPECT_EQ(lstringa<20>{"test"} += "ing", "testing"); EXPECT_EQ(lstringa<20>{"test"} += "ing"_ss + 10, "testing10"); } TEST(SimStr, LStrChange) { EXPECT_EQ(lstringa<20>{"test"}.insert(1, "---"), "t---est"); EXPECT_EQ(lstringa<20>{"test"}.insert(1, eea + "---"), "t---est"); EXPECT_EQ(lstringa<20>{"test"}.insert(100, "---"), "test---"); EXPECT_EQ(lstringa<20>{"test"}.prepend("---"), "---test"); EXPECT_EQ(lstringa<3>{"test"}.prepend(eea + "---"), "---test"); EXPECT_EQ(lstringa<4>{"test"}.change(1, 2, "---"), "t---t"); EXPECT_EQ(lstringa<20>{"test"}.change(1, 2, eea + "---"), "t---t"); EXPECT_EQ(lstringa<0>{"test"}.change(100, 20, "---"), "test---"); EXPECT_EQ(lstringa<1>{"test"}.remove(1, 2), "tt"); EXPECT_EQ(lstringa<20>{""}.change(1, 5, "---"), "---"); EXPECT_EQ(lstringu<20>{u"test"}.insert(1, u"---"), u"t---est"); EXPECT_EQ(lstringu<20>{u"test"}.insert(1, eeu + u"---"), u"t---est"); EXPECT_EQ(lstringu<20>{u"test"}.insert(100, u"---"), u"test---"); EXPECT_EQ(lstringu<20>{u"test"}.prepend(u"---"), u"---test"); EXPECT_EQ(lstringu<3>{u"test"}.prepend(eeu + u"---"), u"---test"); EXPECT_EQ(lstringu<4>{u"test"}.change(1, 2, u"---"), u"t---t"); EXPECT_EQ(lstringu<20>{u"test"}.change(1, 2, eeu + u"---"), u"t---t"); EXPECT_EQ(lstringu<0>{u"test"}.change(100, 20, u"---"), u"test---"); EXPECT_EQ(lstringu<1>{u"test"}.remove(1, 2), u"tt"); EXPECT_EQ(lstringu<20>{u""}.change(1, 5, u"---"), u"---"); } TEST(SimStr, ExprNum) { EXPECT_EQ(lstringa<20>{eea + std::numeric_limits::min()}, "-32768"); EXPECT_EQ(lstringa<20>{eea + (std::numeric_limits::min() + 1)}, "-32767"); EXPECT_EQ(lstringa<20>{eea + std::numeric_limits::min()}, "-2147483648"); } TEST(SimStr, LStrSelfReplace) { { lstringa<40> test = "-aaaaaaaaaaaaaaaa--"; test.replace("a", "aa"); EXPECT_EQ(test, "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--"); } { lstringa<40> test = "-aaaaaaaaaaaaaaaaaa--"; test.replace("a", "aa"); EXPECT_EQ(test, "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--"); } { lstringa<40> test = "test string"; ssa before = test; test.replace("aa", "asd"); EXPECT_EQ(test, "test string"); EXPECT_EQ(before.str, test.to_str().str); } { lstringa<40> test = "test string"; ssa before = test; test.replace("st", "asd"); EXPECT_EQ(test, "teasd asdring"); EXPECT_EQ(before.str, test.to_str().str); } { lstringa<40> test = "test string"; ssa before = test; test.replace("st", "a"); EXPECT_EQ(test, "tea aring"); EXPECT_EQ(before.str, test.to_str().str); } { lstringa<40> test = "test string"; ssa before = test; test.replace("st", "--"); EXPECT_EQ(test, "te-- --ring"); EXPECT_EQ(before.str, test.to_str().str); } { lstringa<11> test = "test string1234"; ssa before = test; test.replace("st", "---"); EXPECT_EQ(test, "te--- ---ring1234"); // buffer changed from local to allocated EXPECT_NE(before.str, test.to_str().str); test.replace("---", "s"); EXPECT_EQ(test, "tes sring1234"); // buffer not changed from allocated to local EXPECT_NE(before.str, test.to_str().str); test.shrink_to_fit(); // buffer changed from allocated to local EXPECT_EQ(before.str, test.to_str().str); } { lstringa<0> buffer; buffer.replace_from(ssa{"test string"}, "st", "---"); EXPECT_EQ(buffer, "te--- ---ring"); } { lstringa<40> buffer; buffer.replace_from(ssa{"test string"}, "st", "--"); EXPECT_EQ(buffer, "te-- --ring"); } { lstringa<40> buffer; buffer.replace_from(ssa{"test string"}, "st", "-"); EXPECT_EQ(buffer, "te- -ring"); } } TEST(SimStr, LStrSelfFuncFill) { size_t count = 0, first = 0, second = 0; lstringa<5> test; test << [&](auto p, auto l) { if (!count) { first = l; } else { second = l; } count++; if (l >= 10) { memset(p, 'a', 10); } return 10; }; EXPECT_EQ(count, 2); EXPECT_EQ(first, lstringa<5>::LocalCapacity); EXPECT_EQ(second, 15); EXPECT_EQ(test, "aaaaaaaaaa"); count = 0, first = 0, second = 0; test <<= [&](auto p, auto l) { if (!count) { first = l; } else { second = l; } count++; if (l >= 6) { memset(p, 'b', 6); } return 6; }; EXPECT_EQ(count, 2u); EXPECT_EQ(first, 5u); EXPECT_EQ(second, 21u); EXPECT_EQ(test, "aaaaaaaaaabbbbbb"); } TEST(SimStr, SStrTrimCopy) { stringa sample{"test"}; stringa result = sample.trimmed(); EXPECT_EQ(sample, result); EXPECT_TRUE(sample.to_str().is_same(result.to_str())); stringa yares = sample.trimmed_right("t"); EXPECT_EQ(yares, "tes"); EXPECT_NE(sample.symbols(), yares.symbols()); auto ls = sample.trimmed>(); EXPECT_EQ(ls, "test"); } template void check_printf_u() { lstring text; if constexpr (requires {text.printf(u"%2$c%1$c aaaaaaaaaaaaaa", 'a', 'b');}) { text.printf(u"%2$c%1$c aaaaaaaaaaaaaa", 'a', 'b'); EXPECT_EQ(text, u"ba aaaaaaaaaaaaaa"); } } template void check_printf_uu() { lstring text; if constexpr (requires {text.printf(U"%2$c%1$c aaaaaaaaaaaaaa", 'a', 'b');}) { text.printf(U"%2$c%1$c aaaaaaaaaaaaaa", 'a', 'b'); EXPECT_EQ(text, U"ba aaaaaaaaaaaaaa"); } } TEST(SimStr, LStrPrintf) { { lstringa<2> text; text.printf("%c%c", 'a', 'b'); EXPECT_EQ(text, "ab"); text.printf("%s", "tested"); EXPECT_EQ(text, "tested"); } { lstringw<2> text; text.printf(L"%c%c", 'a', 'b'); EXPECT_EQ(text, L"ab"); text.printf(L"%ls", L"tested"); EXPECT_EQ(text, L"tested"); } { lstringa<40> text = "tested"; text.printf_from(4, "%c%c", 'a', 'b'); EXPECT_EQ(text, "testab"); text.printf_from(1, "%s", "tested"); EXPECT_EQ(text, "ttested"); } { lstringa<40> text = "tested"; text.append_printf("%c%c", 'a', 'b'); EXPECT_EQ(text, "testedab"); text.append_printf("%s", "tested"); EXPECT_EQ(text, "testedabtested"); } { lstringa<2> text; text.printf("%2$c%1$c aaaaaaaaaaaaaa", 'a', 'b'); EXPECT_EQ(text, "ba aaaaaaaaaaaaaa"); } { lstringw<2> text; text.printf(L"%2$c%1$c aaaaaaaaaaaaaa", L'a', L'b'); EXPECT_EQ(text, L"ba aaaaaaaaaaaaaa"); } check_printf_u(); check_printf_uu(); } TEST(SimStr, LStrFormat) { { lstringa<2> text; text.format("{}{}", 'a', 'b'); EXPECT_EQ(text, "ab"); text.format("{}", "tested"); EXPECT_EQ(text, "tested"); lstringa<10> test = "test"; text.format("{}ed", test); text.format("{}", "tested"); stringa stest = "test"; text.format("{}ed", stest); text.format("{}", "tested"); } { lstringa<2> text; text.format("{1}{0}", 'a', 'b'); EXPECT_EQ(text, "ba"); } { lstringw<2> text; text.format(L"{}{}", 'a', 'b'); EXPECT_EQ(text, L"ab"); text.format(L"{}", L"tested"); EXPECT_EQ(text, L"tested"); } #ifdef _WIN32 { // char16_t в Windows совместим по размеру с wchar_t, поэтому для его форматирования можно использовать // L"format_string", и передавать char16_t строковые объекты // char16_t on Windows is compatible in size with wchar_t, so you can use L"format_string" to format it // and pass char16_t string objects lstringu<2> text; text.format(L"{}{}", 'a', 'b'); EXPECT_EQ(text, u"ab"); text.format(L"{}{}", L"tested", text); EXPECT_EQ(text, u"testedab"); lstringw<10> tew; tew.format(L"-{}-", text); EXPECT_EQ(tew, L"-testedab-"); } #else { // char32_t в Linux совместим по размеру с wchar_t, поэтому для его форматирования можно использовать // L"format_string", и передавать char32_t строковые объекты // char32_t on Linux is compatible in size with wchar_t, so you can use L"format_string" to format it // and pass char32_t string objects lstringuu<2> text; text.format(L"{}{}", 'a', 'b'); EXPECT_EQ(text, U"ab"); text.format(L"{}{}", L"tested", text); EXPECT_EQ(text, U"testedab"); lstringw<10> tew; tew.format(L"-{}-", text); EXPECT_EQ(tew, L"-testedab-"); } #endif { lstringa<40> text = "tested"; text.format_from(4, "{}{}", 'a', 'b'); EXPECT_EQ(text, "testab"); text.format_from(1, "{}", "tested"); EXPECT_EQ(text, "ttested"); } { lstringa<40> text = "tested"; text.append_formatted("{}{}", 'a', 'b'); EXPECT_EQ(text, "testedab"); text.append_formatted("{}", "tested"); EXPECT_EQ(text, "testedabtested"); } } TEST(SimStr, LStrJoinAndExpressions) { lstringa<100> buffer; buffer = e_join(std::vector{}, "<>"); EXPECT_EQ(buffer, ""); buffer = e_join(std::vector{}, "<>"); EXPECT_EQ(buffer, ""); buffer = e_join(std::vector{""}, "<>"); EXPECT_EQ(buffer, "<>"); buffer = e_join(std::vector{""}, "<>"); EXPECT_EQ(buffer, ""); buffer = e_join(std::vector{""}, "<>"); EXPECT_EQ(buffer, ""); buffer = e_join(std::vector{"", ""}, "<>"); EXPECT_EQ(buffer, ""); buffer = e_join(std::vector{"s", "", "k"}, "<>"); EXPECT_EQ(buffer, "s<>k"); buffer = e_join(std::vector{"s", "", "k"}, "<>"); EXPECT_EQ(buffer, "s<>k<>"); buffer = e_join(std::vector{"s", "v", "k"}, "<>"); EXPECT_EQ(buffer, "s<>v<>k"); buffer = e_join(std::vector{"s", "v", "k"}, "<>"); EXPECT_EQ(buffer, "s<>v<>k<>"); buffer = e_join(std::vector{"asd", "fgh", "jkl"}, "<>"); EXPECT_EQ(buffer, "asd<>fgh<>jkl"); int k = 10; double d = 12.1; lstringa<10> test = ">" + e_repl(buffer, "<>", "-") + k + ", " + d; EXPECT_EQ(test, ">asd-fgh-jkl10, 12.1"); buffer.prepend(e_choice(test.length() > 2, eea + 99, eea + 12.1 + "asd")); EXPECT_EQ(buffer, "99asd<>fgh<>jkl"); buffer.change(2, 4, test(0, 3) + "__" + 1 + ','); EXPECT_EQ(buffer, "99>as__1,>fgh<>jkl"); } TEST(SimStr, LStrVFormat){ ssa t1 = "text1", t2 = "text2", format = "{}{}{}"; auto res = lstringa<4>{}.vformat(format, t1, t2, 4); EXPECT_EQ(res, "text1text24"); } TEST(SimStr, SStrFormat) { EXPECT_EQ(stringa::printf("%s%i", "test", 10), "test10"); EXPECT_EQ(stringa::format("{}{}", "test", 10), "test10"); EXPECT_EQ(stringw::printf(L"%ls%i", L"test", 10), L"test10"); EXPECT_EQ(stringw::format(L"{}{}", L"test", 10), L"test10"); } #define _S(par) par, size_t(std::size(par) - 1) TEST(SimStr, HashMap) { EXPECT_EQ(fnv_hash( "asdfghjkl"), fnv_hash(_S( "asdfghjkl"))); EXPECT_EQ(fnv_hash(u"asdfghjkl"), fnv_hash(_S(u"asdfghjkl"))); EXPECT_EQ(fnv_hash(L"asdfghjkl"), fnv_hash(_S(L"asdfghjkl"))); EXPECT_EQ(fnv_hash( "asdfghjkl"), fnv_hash_compile(_S( "asdfghjkl"))); EXPECT_EQ(fnv_hash(u"asdfghjkl"), fnv_hash_compile(_S(u"asdfghjkl"))); EXPECT_EQ(fnv_hash(L"asdfghjkl"), fnv_hash_compile(_S(L"asdfghjkl"))); EXPECT_EQ(fnv_hash_ia( "asdfGhjkl"), fnv_hash_ia(_S( "asDFghjkl"))); EXPECT_EQ(fnv_hash_ia(u"asdfghJkl"), fnv_hash_ia(_S(u"asdFGHjkl"))); EXPECT_EQ(fnv_hash_ia(L"Asdfghjkl"), fnv_hash_ia(_S(L"asdfghjKL"))); EXPECT_EQ(fnv_hash_ia( "asDfghjkl"), fnv_hash_ia_compile(_S( "aSDfghjkl"))); EXPECT_EQ(fnv_hash_ia(u"asdFghjkl"), fnv_hash_ia_compile(_S(u"asdFGhjkl"))); EXPECT_EQ(fnv_hash_ia(L"asDfghjkl"), fnv_hash_ia_compile(_S(u"asdFGhjkl"))); EXPECT_EQ(fnv_hash_ia( "asdfGhjkl"), unicode_traits ::hashia(_S( "asDFghjkl"))); EXPECT_EQ(fnv_hash_ia(u"asdfghJkl"), unicode_traits::hashia(_S(u"asDFghjkl"))); EXPECT_EQ(fnv_hash_ia(U"asDFghJkl"), unicode_traits::hashia(_S(U"asdFGhjkl"))); EXPECT_EQ(fnv_hash_ia( "asdfGhjklaaaaaaaaaaaaaaaaaaasDFghjklaaaaaaaaaaaaaaaaaa"), unicode_traits ::hashia(_S( "asDFghjklaaaaaaaaaaaaaaaaaaasdfGhjklaaaaaaaaaaaaaaaaaa"))); EXPECT_EQ(unicode_traits:: hashia(_S( "asDFghjkl")), unicode_traits:: hashia(_S( "Asdfghjkl"))); EXPECT_EQ(unicode_traits:: hashia(_S( "asDFghjklaaaaaAAAAaaaaAAAaaaAsdfghjklAaaaAaaAAaaaAAaaAAa")), unicode_traits:: hashia(_S( "AsdfghjklAaaaAaaAAaaaAAaaAAaasDFghjklaaaaaAAAAaaaaAAAaaa"))); EXPECT_EQ(unicode_traits::hashia(_S(u"asdFGhjkl")), unicode_traits::hashia(_S(u"aSDfghjkl"))); EXPECT_EQ(unicode_traits::hashia(_S(U"asdfGhjkl")), unicode_traits::hashia(_S(U"asDfghjkl"))); EXPECT_EQ(unicode_traits:: hashiu(_S( "asDFghjklРус")), unicode_traits:: hashiu(_S( "AsdfghjklрУС"))); EXPECT_EQ(unicode_traits::hashiu(_S(u"asdFGhjklРус")), unicode_traits::hashiu(_S(u"aSDfghjklрУС"))); EXPECT_EQ(unicode_traits::hashiu(_S(U"asdfGhjklРус")), unicode_traits::hashiu(_S(U"asDfghjklрУС"))); EXPECT_EQ(unicode_traits::hashiu(_S(U"asdfGhjklРУсasDfghjklрУСasЯDfghjklрУСasDfghjklрУС")), unicode_traits::hashiu(_S(U"asdfGhjklРусAsdfGhjklРусasяdfGhjklРусasDfghjklрУс"))); { hashStrMapA test = { {"asd"_h, 1}, {"fgh"_h, 2}, }; EXPECT_EQ(test.find("aaa"), test.end()); EXPECT_NE(test.find("asd"_h), test.end()); EXPECT_EQ(test.find("asd")->second, 1); } { hashStrMapAIA test = { {"asd"_ia, 1}, {"fgh"_ia, 2}, {"rusрус"_ia, 3}, }; EXPECT_EQ(test.find("aaa"), test.end()); EXPECT_EQ(test.find("RUSРУС"_ia), test.end()); EXPECT_EQ(test.find("aSd")->second, 1); } { hashStrMapAIA test = hashStrMapAIA::init_str { {"asd", 1}, {"fgh", 2}, {"rusрус", 3}, }; EXPECT_EQ(test.find("aaa"), test.end()); EXPECT_EQ(test.find("RUSРУС"), test.end()); EXPECT_EQ(test.find("aSd"_ia)->second, 1); } { hashStrMapAIU test = { {"asd"_iu, 1}, {"fgh"_iu, 2}, {"rusрус"_iu, 3}, }; EXPECT_EQ(test.find("aaa"), test.end()); EXPECT_NE(test.find("RUSРУС"), test.end()); EXPECT_EQ(test.find("RUSРУС"_iu)->second, 3); } } TEST(SimStr, SplitterWork) { Splitter splitter{"asdfQQbfjgjQQQQjfjfjf", "QQ"}; EXPECT_FALSE(splitter.is_done()); EXPECT_EQ(splitter.next(), "asdf"); EXPECT_EQ(splitter.next(), "bfjgj"); EXPECT_EQ(splitter.next(), ""); EXPECT_EQ(splitter.next(), "jfjfjf"); EXPECT_TRUE(splitter.is_done()); EXPECT_EQ(splitter.next(), ""); EXPECT_EQ(splitter.next(), ""); Splitter splitter1{"", "-"}; EXPECT_FALSE(splitter1.is_done()); EXPECT_EQ(splitter1.next(), ""); EXPECT_TRUE(splitter1.is_done()); Splitter splitter2{"asd-", "-"}; EXPECT_FALSE(splitter2.is_done()); EXPECT_EQ(splitter2.next(), "asd"); EXPECT_FALSE(splitter2.is_done()); EXPECT_EQ(splitter2.next(), ""); EXPECT_TRUE(splitter1.is_done()); } /* Чтобы была возможность возвращать строковое выражение из функции, надо сильно заморочится - надо тогда чтобы все типы подвыражений имели конструкторы копирования/перемещения, сохраняли всё в себе не по ссылке, а копией значения (потому что ссылка по неосторожности может вести на локальную/временную переменную). К примеру, та же e_join работает с вектором, придётся делать копию вектора, иначе надо будет тщательно следить, что в выражении мы не используем локальных/временных векторов. (такой случай показан в примере ниже будет). В общем, получится сложно и чревато багами. Поэтому лучше и проще проще сделать так - постулируем, что строковые выражения можно посылать в функции, но нельзя копировать и возвращать из функций. А если хочется иметь возможность оптимально возращать любой тип строки, можно делать как в примере ниже. */ namespace { // Это некая функция, возвращающая вектор строк std::vector get_strings() { return {"f1", "f2", "f3"}; } // Здесь будем запоминать адрес объекта, в который пишем результат void* address; void* address_copy; // Простая тестовая структура struct aaaa { int field = 10; // Сохранение текстового представления в строку-приёмник void toString(storable_str auto& res) const { address = &res; // e_join содержит ссылку на временный локальный вектор строк res = "my_str: "_ss + field + '\n' + e_join(get_strings(), "\n"); } // Получение текстового представления заданного типа template T> T toString() const { // Благодаря магии NRVO мы избежим копирования t, а toString применится к "наружному" инициализируемом объекту: // https://habr.com/ru/companies/vk/articles/666330/ // https://pvs-studio.ru/ru/blog/terms/6516/ T t; address_copy = &t; toString(t); return t; } }; // тестовая структура, в которой более сложное получение текстового представления: // надо в строках, полученных из get_strings, заменить "f" на "--" struct bbbb { int field = 10; // Сохранение текстового представления в мутабельную строку-приёмник void toString(mutable_str auto& res) const { address = &res; res = "my_str: "_ss + field + '\n'; auto strs = get_strings(); for (const auto& s : strs) { res += e_repl(s, "f", "--") + e_if(&s != &strs.back(), "\n"); } } void toString(immutable_str auto& res) const { lstringsa<100> temp_buffer; toString(temp_buffer); res = std::move(temp_buffer); } // Получение текстового представления заданного типа template T> T toString() const { T t; address_copy = &t; toString(t); return t; } }; } TEST(SimStr, YouMustNotCopyOrReturnStrExpr) { static const ssa sample = "my_str: 10\nf1\nf2\nf3"; static const ssa sample1 = "my_str: 10\n--1\n--2\n--3"; aaaa a; lstringa<200> text = "text"; // .... // некие действия по использованию text text += "text"; // и т.д. .... // Действия с text закончились, хотим переиспользовать text для других целей a.toString(text); // Символы из строкового выражения размещаются в буфер переменной text EXPECT_EQ(&text, address); // Проверим адрес переменной, к которой применялась toString(res) EXPECT_EQ(text, sample); // А можно так: // NRVO магически применит toString(res) прямо к t1 и к t2, // то есть символы из строкового выражения разместятся сразу в буферах переменных t1 и t2, // не создавая промежуточных копий auto t1 = a.toString(); EXPECT_EQ(&t1, address); // Проверим адрес переменной, к которой применялась toString(res) EXPECT_EQ(&t1, address_copy); // Проверим адрес переменной в toString() EXPECT_EQ(t1, sample); auto t2 = a.toString>(); EXPECT_EQ(&t2, address); // Проверим адрес переменной, к которой применялась toString(res) EXPECT_EQ(&t2, address_copy); // Проверим адрес переменной в toString() EXPECT_EQ(t2, sample); bbbb b; // text - мутабельная строка, поэтому bbbb::toString(res) будет писать сразу в буфер b b.toString(text); EXPECT_EQ(&text, address); // Проверим адрес переменной, к которой применялась toString(res) EXPECT_EQ(text, sample1); // stringa - иммутабельная строка, поэтому вызовется функция, готовящая строку во временном буфере, // а потом перемещающая готовую строку из временного буфера в stringa auto t3 = b.toString(); EXPECT_NE(&t3, address); // toString вызывалась не для t3, а для временного буфера EXPECT_EQ(&t3, address_copy); // Проверим адрес переменной в toString() EXPECT_EQ(t3, sample1); // Тут строка помещается сразу в буфер t4 auto t4 = b.toString>(); EXPECT_EQ(&t4, address); // Проверим адрес переменной, к которой применялась toString(res) EXPECT_EQ(&t4, address_copy); // Проверим адрес переменной в toString() EXPECT_EQ(t4, sample1); } TEST(SimStr, FindOneOf) { EXPECT_EQ("abcdefghij"_ss.find_first_of("ce"_ss), 2); EXPECT_EQ("abcdefghij"_ss.find_first_of("ce"), 2); } TEST(SimStr, ReplSymbols) { lstringa<100> res = "<" + e_repl_const_symbols("abc\"gg'uu"; EXPECT_EQ(res, ""); } std::vector prepareTestStrings(size_t length, size_t delta, size_t count) { std::vector result; result.reserve(count); struct expr_rand { using symb_type = u8s; size_t len; size_t length() const noexcept { return len; } char* place(char* ptr) const { for (size_t idx = len; idx > 0; idx--) { *ptr++ = char(' ' + std::rand() % 200); } return ptr; } }; for (size_t idx = 0; idx < count; idx++) { result.emplace_back(expr_rand{length + std::rand() % delta}); } return result; } TEST(SimStr, HashMapInserts) { auto strings = prepareTestStrings(30, 20, 10'000); hashStrMapA store; for (size_t idx = 0; idx < strings.size(); idx++) { store.emplace(strings[idx], idx); } EXPECT_EQ(store.size(), strings.size()); for (size_t idx = 0; idx < strings.size(); idx += 2) { store.erase(strings[idx]); } EXPECT_EQ(store.size(), strings.size() / 2); for (size_t idx = 0; idx < strings.size(); idx += 2) { store[strings[idx]] = idx; } EXPECT_EQ(store.size(), strings.size()); for (size_t idx = 1; idx < strings.size(); idx += 2) { auto fnd = store.find(strings[idx]); EXPECT_NE(fnd, store.end()); EXPECT_EQ(fnd->first.str, strings[idx]); } hashStrMapA copy = store, newCopy; store.clear(); for (size_t idx = 1; idx < strings.size(); idx += 2) { auto fnd = copy.find(strings[idx]); EXPECT_NE(fnd, copy.end()); EXPECT_EQ(fnd->first.str, strings[idx]); } newCopy = copy; copy.clear(); for (size_t idx = 1; idx < strings.size(); idx += 2) { auto fnd = newCopy.find(strings[idx]); EXPECT_NE(fnd, newCopy.end()); EXPECT_EQ(fnd->first.str, strings[idx]); } } TEST(SimStr, StringData) { { lstringa<10> test = "dd"; EXPECT_EQ(stra{test.data()}, "dd"); static_assert(std::is_same_v, "data() must be non const"); } { const lstringa<10> test = "dd"; EXPECT_EQ(stra{test.data()}, "dd"); static_assert(std::is_same_v, "data() must be const"); } { stringa test = "dd"; EXPECT_EQ(stra{test.data()}, "dd"); static_assert(std::is_same_v, "data() must be const"); } } TEST(SimStr, StdStringExpr) { { lstringa<20> res = eea + "test"s; EXPECT_EQ(res, "test"); } { lstringa<20> res = +"test"s; EXPECT_EQ(res, "test"); } { lstringa<20> res = "test"s + eea; EXPECT_EQ(res, "test"); } { lstringa<20> res = eea + "test"sv; EXPECT_EQ(res, "test"); } { lstringa<20> res = +"test"sv; EXPECT_EQ(res, "test"); } { lstringu<20> res = +u"test"sv; EXPECT_EQ(res, u"test"); } { lstringa<20> res = "test"sv + eea; EXPECT_EQ(res, "test"); } } TEST(SimStr, HashStrMapAt) { hashStrMapA test = { {"Test"_h, 1} }; EXPECT_EQ(test.find("Test")->second, 1); test.at("Test") = 2; EXPECT_EQ(test.find("Test")->second, 2); } TEST(SimStr, ExprRepeat) { EXPECT_EQ(stringa{e_repeat("aa", 3)}, "aaaaaa"); int t = 1; EXPECT_EQ(lstringa<40>{e_repeat("aa"_ss + t + "_", 3)}, "aa1_aa1_aa1_"); EXPECT_EQ(std::string{e_repeat("aa"_ss + t + "_", 3)}, "aa1_aa1_aa1_"); } TEST(SimStr, StrExpToStdString) { std::basic_string, std::pmr::polymorphic_allocator> test = "count = "_ss + 10 + " times"; EXPECT_EQ(test, "count = 10 times"); test = "aaa"_ss; EXPECT_EQ(test, "aaa"); EXPECT_EQ("aaa"_ss.to_sv(), "aaa"); std::string auto_utf = e_utf(u"Привет"_ss); EXPECT_EQ(auto_utf, "Привет"); auto_utf = e_utf(L"Досвидания"_ss); EXPECT_EQ(auto_utf, "Досвидания"); std::string res = +"test "s + 10 + e_if(true, " times"); EXPECT_EQ(res, "test 10 times"); res = +"test "sv + 10 + e_if(true, " times"); EXPECT_EQ(res, "test 10 times"); } std::string make_text(const std::string& text, int count, std::string_view what, std::string_view what_p = ""sv) { return +text + " " + count + " " + e_choice(what_p.empty(), what + e_if(count > 1, "s"), e_choice(count > 1, +what_p, +what)); } std::string make_answer(const std::string& text, int count, std::string_view what, std::string_view what_p = ""sv) { return "Answer is: " + +text + " " + count + " " + e_choice(what_p.empty(), what + e_if(count > 1, "s"), e_choice(count > 1, +what_p, +what)); } TEST(SimStr, StrPrintfU8) { stringb tt = u8"asdf"; stringa tr = tt; EXPECT_EQ(tr, "asdf"); tt = tr; EXPECT_EQ(tt, u8"asdf"); lstringb<100> res; res.printf(u8"asd %i", 10); EXPECT_EQ(res, u8"asd 10"); std::u8string std_bstr = u8"def"; std::vector ll = {"qwe", "rty"}; stringb bstring = eea + "abc" + u8"def" + 10 + e_spca<3>() + e_join(ll, "-"); EXPECT_EQ(bstring, u8"abcdef10 qwe-rty"); stringa check_choice = e_choice(true, eea + 10, u8"aaa"); EXPECT_EQ(check_choice, "10"); check_choice = e_choice(false, eea + 10, u8"aaa"); EXPECT_EQ(check_choice, "aaa"); check_choice = e_choice(true, "aaa", u8"aaa"); EXPECT_EQ(check_choice, "aaa"); check_choice = eea + e_if(true, u8"aaa"); EXPECT_EQ(check_choice, "aaa"); check_choice = eeb + e_if(true, "aaa"); EXPECT_EQ(check_choice, "aaa"); std::wstring wstr = L"test"sv + #if WIN32 u"test"_ss #else U"test"_ss #endif ; EXPECT_EQ(wstr, L"testtest"); EXPECT_EQ(make_text("got"s, 10, "apple"sv), "got 10 apples"); EXPECT_EQ(make_answer("got"s, 10, "aloe"sv, "aloe"sv), "Answer is: got 10 aloe"); } TEST(SimStr, ExprReal) { stringa a = e_num(1.1); EXPECT_EQ(a, "1.1"); stringb b = e_num(1.1); EXPECT_EQ(b, u8"1.1"); stringuu uu = e_num(1.1); EXPECT_EQ(uu, U"1.1"); stringu u = e_num(1.1); EXPECT_EQ(u, u"1.1"); stringw w = e_num(1.1); EXPECT_EQ(w, L"1.1"); } TEST(SimStr, StrRepl) { std::string r = e_repl("test"s, "t", "-t-"); EXPECT_EQ(r, "-t-es-t-"); r = e_repl("test"sv, "t", "-t-"); EXPECT_EQ(r, "-t-es-t-"); r = e_repl("test"sv, "t"s, "-t-"); EXPECT_EQ(r, "-t-es-t-"); r = e_repl("test"sv, "t", "-t-"sv); EXPECT_EQ(r, "-t-es-t-"); r = e_repl("test"s, "t"sv, "-t-"s); EXPECT_EQ(r, "-t-es-t-"); stringa a = e_repl("test"_ss, "t", "-t-"); EXPECT_EQ(a, "-t-es-t-"); a = e_repl("test"_ss, "t"_ss, "-t-"); EXPECT_EQ(a, "-t-es-t-"); a = e_repl("test"_ss, "t", "-t-"_ss); EXPECT_EQ(a, "-t-es-t-"); a = e_repl("test"_ss, "t"_ss, "-t-"_ss); EXPECT_EQ(a, "-t-es-t-"); a = e_repl("test"_ss, "t", "a"_ss + "1" + 10); EXPECT_EQ(a, "a110esa110"); a = e_repl("test"_ss, "x", "a"_ss + "1" + 10); EXPECT_EQ(a, "test"); a = e_repl("test"_ss, "t", eea + "a"); EXPECT_EQ(a, "aesa"); a = e_repl("tesd"_ss, "t", eea + "a"); EXPECT_EQ(a, "aesd"); a = e_repl("tttt"_ss, "t", eea); EXPECT_EQ(a, ""); a = e_repl("-tttttttttttttttttt-"_ss, "t", eea + "a"); EXPECT_EQ(a, "-aaaaaaaaaaaaaaaaaa-"); a = e_repl("-tttttttttttttttttt-"_ss, "t", eea + "aa"); EXPECT_EQ(a, "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-"); a = "<" + e_repl("test"sv, "t", "a" + e_repl("test"s, "es", "se")) + ">"; EXPECT_EQ(a, ""); } TEST(SimStr, HexEpr) { stringa hexa = expr_hex{0xabcd0102}; EXPECT_EQ(hexa, "0xABCD0102"); stringu hexu = expr_hex{0xabcd0102}; EXPECT_EQ(hexu, u"0xABCD0102"); stringuu hexuu = expr_hex{0xabcd0102}; EXPECT_EQ(hexuu, U"0xABCD0102"); stringb hexb = expr_hex{0xcd0102}; EXPECT_EQ(hexb, u8"0x00CD0102"); hexb = expr_hex{0xcd0102}; EXPECT_EQ(hexb, u8"0x00CD0102"); hexb = expr_hex{-0xcd0102}; EXPECT_EQ(hexb, u8"-0x00CD0102"); hexa = expr_hex{0xabcd0102}; EXPECT_EQ(hexa, "00000000abcd0102"); hexa = expr_hex{0}; EXPECT_EQ(hexa, "0"); hexa = expr_hex{0}; EXPECT_EQ(hexa, "0x0"); hexa = expr_hex{0}; EXPECT_EQ(hexa, "0x00000000"); std::string text = +"val = "sv + e_hex(10u); EXPECT_EQ(text, "val = 0x0000000A"); stringu textu = u"val = 0X"_ss + e_hex(0x12Au); EXPECT_EQ(textu, u"val = 0X12a"); std::u32string textuu = +U"val = 0X"sv + e_hex(0x12Au); EXPECT_EQ(textuu, U"val = 0X12A"); if (sizeof(void*) == 8) { text = +"ptr = "sv + (const void*)0xdeadbeefcafe01; EXPECT_EQ(text, "ptr = 0x00DEADBEEFCAFE01"); const char* ptr = (const char*)0xdeadbeefcafe01; std::u16string utext = ptr + +u" freed"sv; EXPECT_EQ(utext, u"0x00DEADBEEFCAFE01 freed"); } else { text = +"ptr = "sv + (const void*)0xdeadbeef; EXPECT_EQ(text, "ptr = 0xDEADBEEF"); const char* ptr = (const char*)0xdeadbeef; std::u16string utext = ptr + +u" freed"sv; EXPECT_EQ(utext, u"0xDEADBEEF freed"); } } TEST(SimStr, EFill) { int k = 10; stringa test = "<" + e_fill_left("t="_ss + k, 10, '_'); EXPECT_EQ(test, "<______t=10"); test = e_fill_right("t="_ss + k, 10, '_') + ">"; EXPECT_EQ(test, "t=10______>"); } TEST(SimStr, Subst) { int from = 1, total = 100; bool success = true; lstringu<100> u16t = e_subst(u"Test {} from {}, {}.", from, total, e_choice(success, u"success", u"fail")); EXPECT_EQ(u16t, u"Test 1 from 100, success."); } TEST(SimStr, EIntFmt) { stringa test = "'0x"_ss + 10 / 0x16E08_fmt + "' " + 10 / 0x11'8EF5f_fmt; EXPECT_EQ(test, "'0x0000000A' _______A"); test = 100 / 0x2a010_fmt; EXPECT_EQ(test, "0b01100100"); std::u16string textu = +u"val = 0X"sv + 0x12A / 123_f16; EXPECT_EQ(textu, u"val = 0X12a"); textu = u"val = "_ss + 0x12A / 0_f16; EXPECT_EQ(textu, u"val = 0x0000012A"); } TEST(SimStr, EChangeCase) { stringa test = e_upper("teSt"); EXPECT_EQ(test, "TEST"); test = e_lower(test); EXPECT_EQ(test, "test"); test = e_upper("ɐ ɑ ı ſ"); EXPECT_EQ(test, "Ɐ Ɑ I S"); test = "-" + e_lower("İ Ⱥ Ⱦ ẞ") + "-"; EXPECT_EQ(test, "-i ⱥ ⱦ ß-"); stringu utest = e_upper(u"teSt"); EXPECT_EQ(utest, u"TEST"); utest = e_lower(utest); EXPECT_EQ(utest, u"test"); utest = e_upper(u"ı ſ ɐ ɑ"); EXPECT_EQ(utest, u"I S Ɐ Ɑ"); utest = u"-" + e_lower(u"İ Ⱥ Ⱦ ẞ") + u"-"; EXPECT_EQ(utest, u"-i ⱥ ⱦ ß-"); } #ifndef _MSC_VER void check_equal(stra a, stra b) { EXPECT_EQ(a, b); } inline constexpr cestring ce_sample = "sample " + e_subst("test = {}", e_hex(10)) + ", done"; TEST(SimStr, ConstEval) { constexpr cestring ce_empty; static_assert(ce_empty.length() == 0); static_assert(ce_empty == ""); static_assert(ce_empty.find("aa") == -1); constexpr cestring ce_lit = "test"; static_assert(ce_lit.length() == 4); static_assert(ce_lit == "test"); static_assert(ce_lit.find("st") == 2); static_assert(ce_lit(1, 2) == "es"); constexpr cestring ce_str = "tester"_ss; static_assert(ce_str.length() == 6); static_assert(ce_str == "tester"); static_assert(ce_str.find("te") == 0); static_assert(ce_str.find("ter") == 3); static_assert(ce_str(1, -1) == "este"); constexpr cestring ce_repeat{10, "tu"}; static_assert(ce_repeat.length() == 20); constexpr cestring ce_expr = "test = "_ss + 10 + " times"; static_assert(ce_expr == "test = 10 times"); constexpr cestring ce_subst = e_subst("test = {}", 10); static_assert(ce_subst == "test = 10"); constexpr cestring ce_hex = e_subst("test = {}", e_hex(10)); static_assert(ce_hex == "test = 0x0000000A"); constexpr cestring ce_concat = e_concat("", "test = ", 10, " times"); static_assert(ce_concat == "test = 10 times"); static_assert(ce_concat(6, 3).to_int().value == 10); char arr[ce_concat.length()] = {}; static constexpr cestring ce_copy{ce_concat}; static_assert(ce_copy == "test = 10 times"); check_equal(ce_copy, "test = 10 times"); EXPECT_TRUE(ce_copy == "test = 10 times"); stringa test_copy = ce_sample(0, 10); EXPECT_EQ(test_copy, "sample tes"); constexpr cestring ce_repl = e_repl("test", "e", "--"); static_assert(ce_repl == "t--st"); } #endif } // namespace simstr::tests TEST(SimStr, StrNoNamespace) { std::string str = "test"; std::string test = +str + " = " + 10; EXPECT_EQ(test, "test = 10"); std::u16string textu = +u"val = 0X"sv + simstr::e_hex(0x12Au); EXPECT_EQ(textu, u"val = 0X12a"); }