FixedStringTest.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. //
  17. // Author: eniebler@fb.com
  18. #include <folly/FixedString.h>
  19. #include <folly/portability/GTest.h>
  20. #define FS(x) ::folly::makeFixedString(x)
  21. using namespace folly::string_literals;
  22. TEST(FixedStringExamples, Examples) {
  23. // Example from the docs:
  24. using namespace folly;
  25. constexpr auto hello = makeFixedString("hello"); // a FixedString<5>
  26. constexpr auto world = makeFixedString("world"); // another FixedString<5>
  27. constexpr auto hello_world = hello + ' ' + world + '!';
  28. static_assert(hello_world == "hello world!", "w00t");
  29. EXPECT_STREQ("hello world!", hello_world.c_str());
  30. FixedString<10> test{"****"};
  31. test.replace(1, 2, "!!!!");
  32. EXPECT_STREQ("*!!!!*", test.c_str());
  33. static_assert(makeFixedString("****").creplace(1, 2, "!!!!") == "*!!!!*", "");
  34. }
  35. TEST(FixedStringCtorTest, Default) {
  36. constexpr folly::FixedString<42> s{};
  37. static_assert(s[0] == '\0', "");
  38. static_assert(s.size() == 0u, "");
  39. constexpr auto s2 = s;
  40. static_assert(s2[0] == '\0', "");
  41. static_assert(s2.size() == 0u, "");
  42. }
  43. TEST(FixedStringCtorTest, FromLiterals) {
  44. constexpr folly::FixedString<42> s{"hello world"};
  45. static_assert(s[0] == 'h', "");
  46. constexpr folly::FixedString<11> s2{"hello world"};
  47. static_assert(s2[0] == 'h', "");
  48. static_assert(s2[10] == 'd', "");
  49. static_assert(s2[11] == '\0', "");
  50. // Does not compile, hurray! :-)
  51. // constexpr char a[1] = {'a'};
  52. // constexpr folly::FixedString<10> s3(a);
  53. }
  54. TEST(FixedStringCtorTest, FromPtrAndLength) {
  55. constexpr folly::FixedString<11> s{"hello world", 11};
  56. static_assert(s[0] == 'h', "");
  57. static_assert(s[10] == 'd', "");
  58. static_assert(s[11] == '\0', "");
  59. static_assert(s.size() == 11u, "");
  60. constexpr folly::FixedString<5> s2{"hello world", 5};
  61. static_assert(s2[0] == 'h', "");
  62. static_assert(s2[4] == 'o', "");
  63. static_assert(s2[5] == '\0', "");
  64. static_assert(s2.size() == 5u, "");
  65. constexpr folly::FixedString<20> s3{"hello world", 5};
  66. static_assert(s2[0] == 'h', "");
  67. static_assert(s2[4] == 'o', "");
  68. static_assert(s2[5] == '\0', "");
  69. static_assert(s2.size() == 5u, "");
  70. static_assert("hello" == s3, "");
  71. static_assert(s3 == "hello", "");
  72. static_assert(s3 == s2, "");
  73. static_assert("hell" != s3, "");
  74. static_assert(s3 != "helloooo", "");
  75. static_assert(!(s3 != s2), "");
  76. }
  77. TEST(FixedStringCtorTest, FromStringAndOffset) {
  78. constexpr folly::FixedString<11> s{"hello world"};
  79. constexpr folly::FixedString<5> s2{s, 6u, npos};
  80. static_assert(s2 == "world", "");
  81. constexpr folly::FixedString<0> s3{s, 11u, npos};
  82. static_assert(s3 == "", "");
  83. // Out of bounds offset, does not compile
  84. // constexpr folly::FixedString<0> s4{s, 12};
  85. }
  86. TEST(FixedStringCtorTest, FromStringOffsetAndCount) {
  87. constexpr folly::FixedString<11> s{"hello world"};
  88. constexpr folly::FixedString<4> s2{s, 6u, 4u};
  89. static_assert(s2 == "worl", "");
  90. constexpr folly::FixedString<5> s3{s, 6u, 5u};
  91. static_assert(s3 == "world", "");
  92. // Out of bounds count, does not compile:
  93. // constexpr folly::FixedString<5> s4{s, 6, 6};
  94. }
  95. TEST(FixedStringCtorTest, FromInitializerList) {
  96. constexpr folly::FixedString<11> s{
  97. 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'};
  98. static_assert(s == "hello world", "");
  99. // Out of bounds count, does not compile:
  100. // constexpr folly::FixedString<10> s{
  101. // {'h','e','l','l','o',' ','w','o','r','l','d'}};
  102. }
  103. TEST(FixedStringCtorTest, FromUDL) {
  104. using namespace folly::literals;
  105. #if defined(__GNUC__)
  106. constexpr auto x = "hello"_fs;
  107. static_assert(
  108. std::is_same<decltype(x), const folly::FixedString<5>>::value, "");
  109. static_assert(x[0] == 'h', "");
  110. static_assert(x[1] == 'e', "");
  111. static_assert(x[2] == 'l', "");
  112. static_assert(x[3] == 'l', "");
  113. static_assert(x[4] == 'o', "");
  114. static_assert(x[5] == '\0', "");
  115. static_assert(x.size() == 5u, "");
  116. #endif
  117. constexpr auto y = "goodbye"_fs8;
  118. static_assert(
  119. std::is_same<decltype(y), const folly::FixedString<8>>::value, "");
  120. static_assert(y.size() == 7u, "");
  121. static_assert(y == "goodbye", "");
  122. constexpr auto z = "now is the time for all good llamas"_fs64;
  123. static_assert(
  124. std::is_same<decltype(z), const folly::FixedString<64>>::value, "");
  125. static_assert(z.size() == 35u, "");
  126. static_assert(z == "now is the time for all good llamas", "");
  127. }
  128. TEST(FixedStringConcatTest, FromStringAndLiteral) {
  129. constexpr folly::FixedString<42> s{"hello world"};
  130. constexpr auto res = s + "!!!";
  131. static_assert(res.size() == 14u, "");
  132. static_assert(res == "hello world!!!", "");
  133. }
  134. TEST(FixedStringConcatTest, FromTwoStrings) {
  135. constexpr folly::FixedString<42> s{"hello world"};
  136. constexpr auto res = s + "!!!";
  137. static_assert(res.size() == 14u, "");
  138. static_assert(res == "hello world!!!", "");
  139. }
  140. #if FOLLY_USE_CPP14_CONSTEXPR
  141. constexpr folly::FixedString<20> constexpr_swap_test() {
  142. folly::FixedString<10> tmp1{"hello"}, tmp2{"world!"};
  143. tmp2.swap(tmp1);
  144. return tmp1 + tmp2;
  145. }
  146. TEST(FixedStringSwapTest, ConstexprSwap) {
  147. static_assert(constexpr_swap_test() == "world!hello", "");
  148. }
  149. #endif
  150. TEST(FixedStringSwapTest, RuntimeSwap) {
  151. folly::FixedString<10> tmp1{"hello"}, tmp2{"world!"};
  152. tmp2.swap(tmp1);
  153. EXPECT_STREQ((tmp1 + tmp2).c_str(), "world!hello");
  154. }
  155. #if FOLLY_USE_CPP14_CONSTEXPR
  156. constexpr folly::FixedString<10> constexpr_assign_string_test_1() {
  157. folly::FixedString<10> tmp1, tmp2{"world!"};
  158. tmp1 = tmp2;
  159. return tmp1;
  160. }
  161. constexpr folly::FixedString<10> constexpr_assign_string_test_2() {
  162. folly::FixedString<10> tmp{"aaaaaaaaaa"};
  163. tmp.assign("hello"_fs8);
  164. return tmp;
  165. }
  166. constexpr folly::FixedString<10> constexpr_assign_string_test_3() {
  167. folly::FixedString<10> tmp{"aaaaaaaaaa"};
  168. tmp.assign("goodbye"_fs8, 3u, 2u);
  169. return tmp;
  170. }
  171. constexpr folly::FixedString<10> constexpr_assign_string_test_4() {
  172. folly::FixedString<10> tmp{"aaaaaaaaaa"};
  173. tmp.assign("goodbye"_fs8, 3u, npos);
  174. return tmp;
  175. }
  176. TEST(FixedStringAssignTest, ConstexprAssignString) {
  177. static_assert(constexpr_assign_string_test_1() == "world!", "");
  178. static_assert(constexpr_assign_string_test_2() == "hello", "");
  179. static_assert(constexpr_assign_string_test_3() == "db", "");
  180. static_assert(constexpr_assign_string_test_4() == "dbye", "");
  181. }
  182. #endif
  183. TEST(FixedStringAssignTest, RuntimeAssignString) {
  184. folly::FixedString<10> tmp1, tmp2{"world!"};
  185. tmp1 = tmp2;
  186. EXPECT_STREQ(tmp1.c_str(), "world!");
  187. tmp1.assign("goodbye"_fs8);
  188. EXPECT_STREQ("goodbye", tmp1.c_str());
  189. tmp1.assign("goodbye"_fs8, 3u, npos);
  190. EXPECT_STREQ("dbye", tmp1.c_str());
  191. tmp1.assign("goodbye"_fs8, 3u, 3u);
  192. EXPECT_STREQ("dby", tmp1.c_str());
  193. }
  194. #if FOLLY_USE_CPP14_CONSTEXPR
  195. constexpr folly::FixedString<10> constexpr_assign_literal_test_1() {
  196. folly::FixedString<10> tmp{"aaaaaaaaaa"};
  197. tmp = "hello";
  198. // Not null-terminated, does not compile:
  199. // using C = const char[1];
  200. // tmp = C{'a'};
  201. return tmp;
  202. }
  203. constexpr folly::FixedString<10> constexpr_assign_literal_test_2() {
  204. folly::FixedString<10> tmp{"aaaaaaaaaa"};
  205. tmp.assign("hello");
  206. return tmp;
  207. }
  208. constexpr folly::FixedString<10> constexpr_assign_literal_test_3() {
  209. folly::FixedString<10> tmp{"aaaaaaaaaa"};
  210. tmp.assign("goodbye", 4u);
  211. return tmp;
  212. }
  213. TEST(FixedStringAssignTest, ConstexprAssignLiteral) {
  214. static_assert(constexpr_assign_literal_test_1() == "hello", "");
  215. static_assert(constexpr_assign_literal_test_2() == "hello", "");
  216. static_assert(constexpr_assign_literal_test_3() == "good", "");
  217. }
  218. #endif
  219. TEST(FixedStringAssignTest, RuntimeAssignLiteral) {
  220. folly::FixedString<10> tmp{"aaaaaaaaaa"};
  221. tmp = "hello";
  222. EXPECT_STREQ("hello", tmp.c_str());
  223. tmp.assign("goodbye");
  224. EXPECT_STREQ("goodbye", tmp.c_str());
  225. tmp.assign("goodbye", 4u);
  226. EXPECT_STREQ("good", tmp.c_str());
  227. }
  228. TEST(FixedStringIndexTest, Index) {
  229. constexpr folly::FixedString<11> digits{"0123456789"};
  230. static_assert(digits[0] == '0', "");
  231. static_assert(digits[1] == '1', "");
  232. static_assert(digits[2] == '2', "");
  233. static_assert(digits[9] == '9', "");
  234. static_assert(digits[10] == '\0', "");
  235. #ifdef NDEBUG
  236. // This should be allowed and work in constexpr mode since the internal array
  237. // is actually big enough and op[] does no parameter validation:
  238. static_assert(digits[11] == '\0', "");
  239. #endif
  240. static_assert(digits.at(0) == '0', "");
  241. static_assert(digits.at(1) == '1', "");
  242. static_assert(digits.at(2) == '2', "");
  243. static_assert(digits.at(9) == '9', "");
  244. static_assert(digits.at(10) == '\0', "");
  245. EXPECT_THROW(digits.at(11), std::out_of_range);
  246. }
  247. TEST(FixedStringCompareTest, Compare) {
  248. constexpr folly::FixedString<10> tmp1{"aaaaaaaaaa"};
  249. constexpr folly::FixedString<12> tmp2{"aaaaaaaaaba"};
  250. static_assert(-1 == tmp1.compare(tmp2), "");
  251. static_assert(1 == tmp2.compare(tmp1), "");
  252. static_assert(0 == tmp2.compare(tmp2), "");
  253. static_assert(tmp1 < tmp2, "");
  254. static_assert(tmp1 <= tmp2, "");
  255. static_assert(tmp2 > tmp1, "");
  256. static_assert(tmp2 >= tmp1, "");
  257. static_assert(tmp2 == tmp2, ""); // @nolint
  258. static_assert(tmp2 <= tmp2, ""); // @nolint
  259. static_assert(tmp2 >= tmp2, ""); // @nolint
  260. static_assert(!(tmp2 < tmp2), "");
  261. static_assert(!(tmp2 > tmp2), "");
  262. constexpr folly::FixedString<10> tmp3{"aaa"};
  263. constexpr folly::FixedString<12> tmp4{"aaaa"};
  264. static_assert(-1 == tmp3.compare(tmp4), "");
  265. static_assert(1 == tmp4.compare(tmp3), "");
  266. static_assert(tmp3 < tmp4, "");
  267. static_assert(tmp3 <= tmp4, "");
  268. static_assert(tmp4 > tmp3, "");
  269. static_assert(tmp4 >= tmp3, "");
  270. static_assert(tmp3 < "aaaa", "");
  271. static_assert(tmp3 <= "aaaa", "");
  272. static_assert(!(tmp3 == tmp4), "");
  273. static_assert(tmp3 != tmp4, "");
  274. static_assert("aaaa" > tmp3, "");
  275. static_assert("aaaa" >= tmp3, "");
  276. static_assert("aaaa" != tmp3, "");
  277. static_assert("aaa" == tmp3, "");
  278. static_assert(tmp3 != "aaaa", "");
  279. static_assert(tmp3 == "aaa", "");
  280. }
  281. TEST(FixedStringCompareTest, CompareStdString) {
  282. constexpr folly::FixedString<10> tmp1{"aaaaaaaaaa"};
  283. std::string const tmp2{"aaaaaaaaaba"};
  284. EXPECT_EQ(-1, tmp1.compare(tmp2));
  285. // These are specifically testing the operators, and so we can't rely
  286. // on whever the implementation details of EXPECT_<OP> might be.
  287. EXPECT_FALSE(tmp1 == tmp2);
  288. EXPECT_FALSE(tmp2 == tmp1);
  289. EXPECT_TRUE(tmp1 != tmp2);
  290. EXPECT_TRUE(tmp2 != tmp1);
  291. EXPECT_TRUE(tmp1 < tmp2);
  292. EXPECT_FALSE(tmp2 < tmp1);
  293. EXPECT_TRUE(tmp1 <= tmp2);
  294. EXPECT_FALSE(tmp2 <= tmp1);
  295. EXPECT_FALSE(tmp1 > tmp2);
  296. EXPECT_TRUE(tmp2 > tmp1);
  297. EXPECT_FALSE(tmp1 >= tmp2);
  298. EXPECT_TRUE(tmp2 >= tmp1);
  299. }
  300. #if FOLLY_USE_CPP14_CONSTEXPR
  301. constexpr folly::FixedString<20> constexpr_append_string_test() {
  302. folly::FixedString<20> a{"hello"}, b{"X world!"};
  303. a.append(1u, ' ');
  304. a.append(b, 2u, 5u);
  305. a.append(b, 7u, 1u);
  306. return a;
  307. }
  308. TEST(FixedStringAssignTest, ConstexprAppendString) {
  309. static_assert(constexpr_append_string_test() == "hello world!", "");
  310. }
  311. #endif
  312. TEST(FixedStringAssignTest, RuntimeAppendString) {
  313. folly::FixedString<20> a{"hello"}, b{"X world!"};
  314. a.append(1u, ' ');
  315. a.append(b, 2u, 5u);
  316. a.append(b, 7u, 1u);
  317. EXPECT_STREQ("hello world!", a.c_str());
  318. }
  319. #if FOLLY_USE_CPP14_CONSTEXPR
  320. constexpr folly::FixedString<20> constexpr_append_literal_test() {
  321. folly::FixedString<20> a{"hello"};
  322. a.append(1u, ' ');
  323. a.append("X world!" + 2u, 5u);
  324. a.append("X world!" + 7u);
  325. return a;
  326. }
  327. TEST(FixedStringAssignTest, ConstexprAppendLiteral) {
  328. static_assert(constexpr_append_literal_test() == "hello world!", "");
  329. }
  330. #endif
  331. TEST(FixedStringAssignTest, RuntimeAppendLiteral) {
  332. folly::FixedString<20> a{"hello"};
  333. a.append(1u, ' ');
  334. a.append("X world!" + 2u, 5u);
  335. a.append("X world!" + 7u);
  336. EXPECT_STREQ("hello world!", a.c_str());
  337. }
  338. TEST(FixedStringCAppendTest, CAppendString) {
  339. constexpr folly::FixedString<10> a{"hello"}, b{"X world!"};
  340. constexpr auto tmp1 = a.cappend(' ');
  341. constexpr auto tmp2 = tmp1.cappend(b, 2u, 5u);
  342. constexpr auto tmp3 = tmp2.cappend(b, 7u, 1u);
  343. static_assert(tmp3 == "hello world!", "");
  344. }
  345. TEST(FixedStringCAppendTest, CAppendLiteral) {
  346. constexpr folly::FixedString<10> a{"hello"};
  347. constexpr auto tmp1 = a.cappend(' ');
  348. constexpr auto tmp2 = tmp1.cappend("X world!", 2u, 5u);
  349. constexpr auto tmp3 = tmp2.cappend("X world!", 7u, 1u);
  350. static_assert(tmp3 == "hello world!", "");
  351. }
  352. #if FOLLY_USE_CPP14_CONSTEXPR
  353. constexpr folly::FixedString<10> constexpr_replace_string_test() {
  354. folly::FixedString<10> tmp{"abcdefghij"};
  355. tmp.replace(1, 5, FS("XX"));
  356. return tmp;
  357. }
  358. TEST(FixedStringReplaceTest, ConstexprReplaceString) {
  359. static_assert(constexpr_replace_string_test().size() == 7u, "");
  360. static_assert(constexpr_replace_string_test() == "aXXghij", "");
  361. }
  362. #endif
  363. TEST(FixedStringReplaceTest, RuntimeReplaceString) {
  364. folly::FixedString<10> tmp{"abcdefghij"};
  365. tmp.replace(1, 5, FS("XX"));
  366. EXPECT_EQ(7u, tmp.size());
  367. EXPECT_STREQ("aXXghij", tmp.c_str());
  368. }
  369. TEST(FixedStringEraseTest, RuntimeEraseTest) {
  370. auto x = FS("abcdefghijklmnopqrstuvwxyz"), y = x;
  371. x.erase(x.size());
  372. EXPECT_EQ(26u, x.size());
  373. EXPECT_STREQ(y.c_str(), x.c_str());
  374. x.erase(25u).erase(24u);
  375. EXPECT_EQ(24u, x.size());
  376. EXPECT_STREQ("abcdefghijklmnopqrstuvwx", x.c_str());
  377. x.erase(1u, x.size() - 2u);
  378. EXPECT_EQ(2u, x.size());
  379. EXPECT_STREQ("ax", x.c_str());
  380. }
  381. TEST(FixedStringEraseTest, CEraseTest) {
  382. constexpr auto x = FS("abcdefghijklmnopqrstuvwxyz"), y = x;
  383. constexpr auto tmp0 = x.cerase(x.size());
  384. static_assert(26u == tmp0.size(), "");
  385. static_assert(y == tmp0, "");
  386. constexpr auto tmp1 = tmp0.cerase(25u).cerase(24u);
  387. static_assert(24u == tmp1.size(), "");
  388. static_assert("abcdefghijklmnopqrstuvwx" == tmp1, "");
  389. constexpr auto tmp2 = tmp1.cerase(1u, tmp1.size() - 2u);
  390. static_assert(2u == tmp2.size(), "");
  391. static_assert("ax" == tmp2, "");
  392. constexpr auto tmp3 = tmp2.cerase();
  393. static_assert("" == tmp3, "");
  394. }
  395. TEST(FixedStringFindTest, FindString) {
  396. constexpr folly::FixedString<10> tmp{"hijdefghij"};
  397. static_assert(tmp.find(FS("hij")) == 0u, "");
  398. static_assert(tmp.find(FS("hij"), 1u) == 7u, "");
  399. static_assert(tmp.find(FS("hijdefghij")) == 0u, "");
  400. static_assert(tmp.find(FS("")) == 0u, "");
  401. }
  402. TEST(FixedStringFindTest, FindLiteral) {
  403. constexpr folly::FixedString<10> tmp{"hijdefghij"};
  404. static_assert(tmp.find("hij") == 0u, "");
  405. static_assert(tmp.find("hij", 1u) == 7u, "");
  406. static_assert(tmp.find("hijdefghij") == 0u, "");
  407. }
  408. TEST(FixedStringReverseFindTest, FindChar) {
  409. constexpr folly::FixedString<16> tmp{"This is a string"};
  410. static_assert(tmp.find('s') == 3u, "");
  411. static_assert(tmp.find('s', 9u) == 10u, "");
  412. static_assert(tmp.find('s', 10u) == 10u, "");
  413. static_assert(tmp.find('s', 11u) == tmp.npos, "");
  414. }
  415. TEST(FixedStringReverseFindTest, ReverseFindString) {
  416. constexpr folly::FixedString<16> tmp{"This is a string"};
  417. static_assert(tmp.rfind(FS("is")) == 5u, "");
  418. static_assert(tmp.rfind(FS("is"), 4u) == 2u, "");
  419. static_assert(tmp.rfind(FS("This is a string")) == 0u, "");
  420. static_assert(tmp.rfind(FS("This is a string!")) == tmp.npos, "");
  421. static_assert(tmp.rfind(FS("")) == 16u, "");
  422. }
  423. TEST(FixedStringReverseFindTest, ReverseFindLiteral) {
  424. constexpr folly::FixedString<16> tmp{"This is a string"};
  425. static_assert(tmp.rfind("is") == 5u, "");
  426. static_assert(tmp.rfind("is", 4u) == 2u, "");
  427. static_assert(tmp.rfind("This is a string") == 0u, "");
  428. static_assert(tmp.rfind("This is a string!") == tmp.npos, "");
  429. static_assert(tmp.rfind("") == 16u, "");
  430. }
  431. TEST(FixedStringReverseFindTest, ReverseFindChar) {
  432. constexpr folly::FixedString<16> tmp{"This is a string"};
  433. static_assert(tmp.rfind('s') == 10u, "");
  434. static_assert(tmp.rfind('s', 5u) == 3u, "");
  435. static_assert(tmp.rfind('s', 3u) == 3u, "");
  436. static_assert(tmp.rfind('s', 2u) == tmp.npos, "");
  437. }
  438. TEST(FixedStringFindFirstOfTest, FindFirstOfString) {
  439. constexpr folly::FixedString<16> tmp{"This is a string"};
  440. static_assert(tmp.find_first_of(FS("hi")) == 1u, "");
  441. static_assert(tmp.find_first_of(FS("xi")) == 2u, "");
  442. static_assert(tmp.find_first_of(FS("xi"), 6u) == 13u, "");
  443. static_assert(tmp.find_first_of(FS("xz")) == tmp.npos, "");
  444. static_assert(FS("a").find_first_of(FS("cba")) == 0u, "");
  445. static_assert(FS("").find_first_of(FS("cba")) == tmp.npos, "");
  446. static_assert(FS("a").find_first_of(FS("")) == tmp.npos, "");
  447. static_assert(FS("").find_first_of(FS("")) == tmp.npos, "");
  448. }
  449. TEST(FixedStringFindFirstOfTest, FindFirstOfLiteral) {
  450. constexpr folly::FixedString<16> tmp{"This is a string"};
  451. static_assert(tmp.find_first_of("hi") == 1u, "");
  452. static_assert(tmp.find_first_of("xi") == 2u, "");
  453. static_assert(tmp.find_first_of("xi", 6u) == 13u, "");
  454. static_assert(tmp.find_first_of("xis", 6u, 2u) == 13u, "");
  455. static_assert(tmp.find_first_of("xz") == tmp.npos, "");
  456. static_assert(FS("a").find_first_of("cba") == 0u, "");
  457. static_assert(FS("").find_first_of("cba") == tmp.npos, "");
  458. static_assert(FS("a").find_first_of("") == tmp.npos, "");
  459. static_assert(FS("").find_first_of("") == tmp.npos, "");
  460. }
  461. TEST(FixedStringFindFirstOfTest, FindFirstOfChar) {
  462. constexpr folly::FixedString<16> tmp{"This is a string"};
  463. static_assert(tmp.find_first_of('h') == 1u, "");
  464. static_assert(tmp.find_first_of('i') == 2u, "");
  465. static_assert(tmp.find_first_of('i', 6u) == 13u, "");
  466. static_assert(tmp.find_first_of('x') == tmp.npos, "");
  467. static_assert(FS("a").find_first_of('a') == 0u, "");
  468. static_assert(FS("").find_first_of('a') == tmp.npos, "");
  469. }
  470. TEST(FixedStringFindFirstNotOfTest, FindFirstNotOfString) {
  471. constexpr folly::FixedString<16> tmp{"This is a string"};
  472. static_assert(tmp.find_first_not_of(FS("Ti")) == 1u, "");
  473. static_assert(tmp.find_first_not_of(FS("hT")) == 2u, "");
  474. static_assert(tmp.find_first_not_of(FS("s atr"), 6u) == 13u, "");
  475. static_assert(tmp.find_first_not_of(FS("This atrng")) == tmp.npos, "");
  476. static_assert(FS("a").find_first_not_of(FS("X")) == 0u, "");
  477. static_assert(FS("").find_first_not_of(FS("cba")) == tmp.npos, "");
  478. static_assert(FS("a").find_first_not_of(FS("")) == 0u, "");
  479. static_assert(FS("").find_first_not_of(FS("")) == tmp.npos, "");
  480. }
  481. TEST(FixedStringFindFirstNotOfTest, FindFirstNotOfLiteral) {
  482. constexpr folly::FixedString<16> tmp{"This is a string"};
  483. static_assert(tmp.find_first_not_of("Ti") == 1u, "");
  484. static_assert(tmp.find_first_not_of("hT") == 2u, "");
  485. static_assert(tmp.find_first_not_of("s atr", 6u) == 13u, "");
  486. static_assert(tmp.find_first_not_of("This atrng") == tmp.npos, "");
  487. static_assert(FS("a").find_first_not_of("X") == 0u, "");
  488. static_assert(FS("").find_first_not_of("cba") == tmp.npos, "");
  489. static_assert(FS("a").find_first_not_of("") == 0u, "");
  490. static_assert(FS("").find_first_not_of("") == tmp.npos, "");
  491. }
  492. TEST(FixedStringFindFirstNotOfTest, FindFirstNotOfChar) {
  493. constexpr folly::FixedString<16> tmp{"This is a string"};
  494. static_assert(tmp.find_first_not_of('T') == 1u, "");
  495. static_assert(tmp.find_first_not_of('i') == 0u, "");
  496. static_assert(tmp.find_first_not_of('x', 6u) == 6u, "");
  497. static_assert(tmp.find_first_not_of('s', 6u) == 7u, "");
  498. static_assert(FS("a").find_first_not_of('a') == tmp.npos, "");
  499. static_assert(FS("").find_first_not_of('a') == tmp.npos, "");
  500. }
  501. TEST(FixedStringFindLastOfTest, FindLastOfString) {
  502. constexpr folly::FixedString<16> tmp{"This is a string"};
  503. static_assert(tmp.find_last_of(FS("hi")) == 13u, "");
  504. static_assert(tmp.find_last_of(FS("xh")) == 1u, "");
  505. static_assert(tmp.find_last_of(FS("xi"), 6u) == 5u, "");
  506. static_assert(tmp.find_last_of(FS("xz")) == tmp.npos, "");
  507. static_assert(FS("a").find_last_of(FS("cba")) == 0u, "");
  508. static_assert(FS("").find_last_of(FS("cba")) == tmp.npos, "");
  509. static_assert(FS("a").find_last_of(FS("")) == tmp.npos, "");
  510. static_assert(FS("").find_last_of(FS("")) == tmp.npos, "");
  511. }
  512. TEST(FixedStringFindLastOfTest, FindLastOfLiteral) {
  513. constexpr folly::FixedString<16> tmp{"This is a string"};
  514. static_assert(tmp.find_last_of("hi") == 13u, "");
  515. static_assert(tmp.find_last_of("xh") == 1u, "");
  516. static_assert(tmp.find_last_of("xi", 6u) == 5u, "");
  517. static_assert(tmp.find_last_of("xis", 6u, 2u) == 5u, "");
  518. static_assert(tmp.find_last_of("xz") == tmp.npos, "");
  519. static_assert(FS("a").find_last_of("cba") == 0u, "");
  520. static_assert(FS("").find_last_of("cba") == tmp.npos, "");
  521. static_assert(FS("a").find_last_of("") == tmp.npos, "");
  522. static_assert(FS("").find_last_of("") == tmp.npos, "");
  523. }
  524. TEST(FixedStringFindLastOfTest, FindLastOfChar) {
  525. constexpr folly::FixedString<16> tmp{"This is a string"};
  526. static_assert(tmp.find_last_of('h') == 1u, "");
  527. static_assert(tmp.find_last_of('i') == 13u, "");
  528. static_assert(tmp.find_last_of('i', 6u) == 5u, "");
  529. static_assert(tmp.find_last_of('x') == tmp.npos, "");
  530. static_assert(FS("a").find_last_of('a') == 0u, "");
  531. static_assert(FS("").find_last_of('a') == tmp.npos, "");
  532. }
  533. TEST(FixedStringFindLastNotOfTest, FindLastNotOfString) {
  534. constexpr folly::FixedString<16> tmp{"This is a string"};
  535. static_assert(tmp.find_last_not_of(FS("gstrin")) == 9u, "");
  536. static_assert(tmp.find_last_not_of(FS("hT")) == 15u, "");
  537. static_assert(tmp.find_last_not_of(FS("s atr"), 6u) == 5u, "");
  538. static_assert(tmp.find_last_not_of(FS("This atrng")) == tmp.npos, "");
  539. static_assert(FS("a").find_last_not_of(FS("X")) == 0u, "");
  540. static_assert(FS("").find_last_not_of(FS("cba")) == tmp.npos, "");
  541. static_assert(FS("a").find_last_not_of(FS("")) == 0u, "");
  542. static_assert(FS("").find_last_not_of(FS("")) == tmp.npos, "");
  543. }
  544. TEST(FixedStringFindLastNotOfTest, FindLastNotOfLiteral) {
  545. constexpr folly::FixedString<16> tmp{"This is a string"};
  546. static_assert(tmp.find_last_not_of("gstrin") == 9u, "");
  547. static_assert(tmp.find_last_not_of("hT") == 15u, "");
  548. static_assert(tmp.find_last_not_of("s atr", 6u) == 5u, "");
  549. static_assert(tmp.find_last_not_of(" atrs", 6u, 4u) == 6u, "");
  550. static_assert(tmp.find_last_not_of("This atrng") == tmp.npos, "");
  551. static_assert(FS("a").find_last_not_of("X") == 0u, "");
  552. static_assert(FS("").find_last_not_of("cba") == tmp.npos, "");
  553. static_assert(FS("a").find_last_not_of("") == 0u, "");
  554. static_assert(FS("").find_last_not_of("") == tmp.npos, "");
  555. }
  556. TEST(FixedStringFindLastNotOfTest, FindLastNotOfChar) {
  557. constexpr folly::FixedString<16> tmp{"This is a string"};
  558. static_assert(tmp.find_last_not_of('g') == 14u, "");
  559. static_assert(tmp.find_last_not_of('i') == 15u, "");
  560. static_assert(tmp.find_last_not_of('x', 6u) == 6u, "");
  561. static_assert(tmp.find_last_not_of('s', 6u) == 5u, "");
  562. static_assert(FS("a").find_last_not_of('a') == tmp.npos, "");
  563. static_assert(FS("").find_last_not_of('a') == tmp.npos, "");
  564. }
  565. TEST(FixedStringConversionTest, ConversionToStdString) {
  566. constexpr folly::FixedString<16> tmp{"This is a string"};
  567. std::string str = tmp;
  568. EXPECT_STREQ("This is a string", str.c_str());
  569. str = "another string"_fs16;
  570. EXPECT_STREQ("another string", str.c_str());
  571. }
  572. #if FOLLY_USE_CPP14_CONSTEXPR
  573. constexpr std::size_t countSpacesReverse(folly::FixedString<50> s) {
  574. std::size_t count = 0u;
  575. auto i = s.rbegin();
  576. for (; i != s.rend(); ++i, --i, i++, i--, i += 1, i -= 1, i += 1) {
  577. if (' ' == *i) {
  578. ++count;
  579. }
  580. }
  581. return count;
  582. }
  583. TEST(FixedStringReverseIteratorTest, Cpp14ConstexprReverseIteration) {
  584. static_assert(3 == countSpacesReverse("This is a string"), "");
  585. }
  586. #endif
  587. TEST(FixedStringReverseIteratorTest, ConstexprReverseIteration) {
  588. static constexpr auto alpha = FS("abcdefghijklmnopqrstuvwxyz");
  589. static_assert('a' == alpha.rbegin()[25], "");
  590. static_assert('a' == *(alpha.rbegin() + 25), "");
  591. static_assert('c' == *(alpha.rbegin() + 25 - 2), "");
  592. static_assert((alpha.rend() - 2) == (alpha.rbegin() + 24), "");
  593. }
  594. namespace GCC61971 {
  595. // FixedString runs afoul of GCC #61971 (spurious -Warray-bounds)
  596. // in optimized builds. The following test case triggers it for gcc-4.x.
  597. // Test that FixedString suppresses the warning correctly.
  598. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61971
  599. constexpr auto xyz = folly::makeFixedString("xyz");
  600. constexpr auto dot = folly::makeFixedString(".");
  601. template <typename T1>
  602. constexpr auto concatStuff(const T1& component) noexcept {
  603. return xyz + dot + component;
  604. }
  605. constexpr auto co = folly::makeFixedString("co");
  606. struct S {
  607. std::string s{concatStuff(co)};
  608. };
  609. } // namespace GCC61971
  610. TEST(FixedStringGCC61971, GCC61971) {
  611. GCC61971::S s;
  612. (void)s;
  613. }
  614. #include <folly/Range.h>
  615. TEST(FixedStringConversionTest, ConversionToFollyRange) {
  616. // The following declaraction is static for compilers that haven't implemented
  617. // the resolution of:
  618. // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1454
  619. static constexpr folly::FixedString<16> tmp{"This is a string"};
  620. constexpr folly::StringPiece piece = tmp;
  621. static_assert(tmp.begin() == piece.begin(), "");
  622. static_assert(tmp.end() == piece.end(), "");
  623. }