strCat.cc 4.7 KB

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