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