openMSX
strCat.cc
Go to the documentation of this file.
1#include "catch.hpp"
2#include "strCat.hh"
3
4static std::string rValue()
5{
6 return "bar";
7}
8
9struct MyType
10{
11 char c;
12};
13
14static std::ostream& operator<<(std::ostream& os, const MyType& m)
15{
16 os << "--|" << m.c << "|--";
17 return os;
18}
19
20TEST_CASE("strCat")
21{
22 std::string str = "abc";
23 std::string_view sr = "xyz";
24 const char* literal = "foo";
25 char buf[100]; buf[0] = 'q'; buf[1] = 'u'; buf[2] = 'x'; buf[3] = '\0';
26 char c = '-';
27 unsigned char uc = 222;
28 int m = -31;
29 int i = 123456;
30 float f = 6.28f;
31 double d = -1.234;
32 MyType t = {'a'};
33
34 SECTION("zero") {
35 CHECK(strCat() == "");
36 }
37 SECTION("one") {
38 CHECK(strCat(rValue()) == "bar");
39 CHECK(strCat(str) == "abc");
40 CHECK(strCat(sr) == "xyz");
41 CHECK(strCat(literal) == "foo");
42 CHECK(strCat(buf) == "qux");
43 CHECK(strCat(c) == "-");
44 CHECK(strCat(uc) == "222");
45 CHECK(strCat(m) == "-31");
46 CHECK(strCat(i) == "123456");
47 CHECK(strCat(f) == "6.28");
48 CHECK(strCat(d) == "-1.234");
49 CHECK(strCat(t) == "--|a|--");
50 CHECK(strCat(hex_string<8>(i)) == "0001e240");
51 CHECK(strCat(hex_string<4>(i)) == "e240");
52 CHECK(strCat(hex_string<4, HexCase::upper>(i)) == "E240");
53 CHECK(strCat(hex_string(Digits{5}, i)) == "1e240");
54 CHECK(strCat(hex_string<HexCase::upper>(Digits{5}, i)) == "1E240");
55 CHECK(strCat(hex_string(Digits{3}, i)) == "240");
56 CHECK(strCat(bin_string<16>(i)) == "1110001001000000");
57 CHECK(strCat(bin_string<8>(i)) == "01000000");
58 CHECK(strCat(dec_string<8>(i)) == " 123456");
59 CHECK(strCat(dec_string<6>(i)) == "123456");
60 CHECK(strCat(dec_string<4>(i)) == "3456");
61 CHECK(strCat(spaces(5)) == " ");
62 }
63 SECTION("two") {
64 CHECK(strCat(str, i) == "abc123456");
65 CHECK(strCat(str, m) == "abc-31");
66 CHECK(strCat(str, uc) == "abc222");
67 CHECK(strCat(i, str) == "123456abc");
68 CHECK(strCat(m, str) == "-31abc");
69 CHECK(strCat(uc, str) == "222abc");
70 CHECK(strCat(buf, i) == "qux123456");
71 CHECK(strCat(literal, m) == "foo-31");
72 CHECK(strCat(i, m) == "123456-31");
73 CHECK(strCat(c, m) == "--31");
74 CHECK(strCat(i, rValue()) == "123456bar");
75 CHECK(strCat(spaces(4), i) == " 123456");
76 CHECK(strCat(hex_string<3>(i), i) == "240123456");
77 CHECK(strCat(c, hex_string<1>(i)) == "-0");
78 CHECK(strCat(rValue(), uc) == "bar222");
79
80 // these have special overloads
81 CHECK(strCat(str, str) == "abcabc");
82 CHECK(strCat(literal, str) == "fooabc");
83 CHECK(strCat(c, str) == "-abc");
84 CHECK(strCat(str, literal) == "abcfoo");
85 CHECK(strCat(str, c) == "abc-");
86 CHECK(strCat(rValue(), str) == "barabc");
87 CHECK(strCat(str, rValue()) == "abcbar");
88 CHECK(strCat(rValue(), rValue()) == "barbar");
89 CHECK(strCat(literal, rValue()) == "foobar");
90 CHECK(strCat(c, rValue()) == "-bar");
91 CHECK(strCat(rValue(), literal) == "barfoo");
92 CHECK(strCat(rValue(), c) == "bar-");
93 CHECK(strCat(rValue(), sr) == "barxyz");
94 }
95 SECTION("three") {
96 CHECK(strCat(str, str, str) == "abcabcabc");
97 CHECK(strCat(i, m, c) == "123456-31-");
98 CHECK(strCat(literal, buf, rValue()) == "fooquxbar");
99
100 // 1st an r-value is a special case
101 CHECK(strCat(rValue(), i, literal) == "bar123456foo");
102 CHECK(strCat(rValue(), uc, buf) == "bar222qux");
103 }
104 SECTION("many") {
105 CHECK(strCat(str, sr, literal, buf, c, uc, m, i, rValue(), spaces(2), hex_string<2>(255)) ==
106 "abcxyzfooqux-222-31123456bar ff");
107 CHECK(strCat(rValue(), uc, buf, c, spaces(2), str, i, hex_string<3>(9999), sr, literal, m) ==
108 "bar222qux- abc12345670fxyzfoo-31");
109 }
110}
111
112template<typename... Args>
113static void testAppend(const std::string& expected, Args&& ...args)
114{
115 std::string s1;
116 strAppend(s1, std::forward<Args>(args)...);
117 CHECK(s1 == expected);
118
119 std::string s2 = "abcdefghijklmnopqrstuvwxyz";
120 strAppend(s2, std::forward<Args>(args)...);
121 CHECK(s2 == ("abcdefghijklmnopqrstuvwxyz" + expected));
122}
123
124TEST_CASE("strAppend")
125{
126 std::string str = "mno";
127 std::string_view sr = "rst";
128 const char* literal = "ijklmn";
129 char buf[100]; buf[0] = 'd'; buf[1] = 'e'; buf[2] = '\0'; buf[3] = 'f';
130 char c = '+';
131 unsigned u = 4294967295u;
132 long long ll = -876;
133
134 SECTION("zero") {
135 testAppend("");
136 }
137 SECTION("one") {
138 testAppend("bar", rValue());
139 testAppend("mno", str);
140 testAppend("rst", sr);
141 testAppend("ijklmn", literal);
142 testAppend("de", buf);
143 testAppend("+", c);
144 testAppend("4294967295", u);
145 testAppend("-876", ll);
146 testAppend(" ", spaces(10));
147 testAppend("fffffffc94", hex_string<10>(ll));
148 }
149 SECTION("many") {
150 std::string s = "bla";
151 strAppend(s, str, sr, literal, spaces(3));
152 strAppend(s, buf, c, u, ll, rValue());
153 CHECK(s == "blamnorstijklmn de+4294967295-876bar");
154 }
155}
156
157
158#if 0
159
160// Not part of the actual unittest. Can be used to (manually) inspect the
161// quality of the generated code.
162
163auto test1(int i) { return strCat(i); }
164auto test1b(int i) { return std::to_string(i); }
165auto test2(const char* s) { return strCat(s); }
166auto test3(std::string_view s) { return strCat(s); }
167auto test4(const std::string& s) { return strCat(s); }
168auto test5() { return strCat("bla"); }
169auto test6() { return strCat('a'); }
170auto test7(char i) { return strCat('a', i, "bla"); }
171auto test8(int i, unsigned u) { return strCat(i, u); }
172
173auto testA1(const std::string& s1, const std::string& s2) { return strCat(s1, s2); }
174auto testA2(const std::string& s1, const std::string& s2) { return s1 + s2; }
175
176#endif
TclObject t
CHECK(m3==m3)
TEST_CASE("strCat")
Definition strCat.cc:20
std::string strCat()
Definition strCat.hh:703
strCatImpl::ConcatSpaces spaces(size_t n)
Definition strCat.hh:801
strCatImpl::ConcatVariableWidthHexIntegral< Case, T > hex_string(Digits n, T t)
Definition strCat.hh:778
void strAppend(std::string &result, Ts &&...ts)
Definition strCat.hh:752
char c
Definition strCat.cc:11