string_ut.h 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  1. #pragma once
  2. #include "string.h"
  3. #include <library/cpp/testing/unittest/registar.h>
  4. #include <util/string/reverse.h>
  5. template <typename CharT, size_t N>
  6. struct TCharBuffer {
  7. CharT Data[N];
  8. //! copies characters from string to the internal buffer without any conversion
  9. //! @param s a string that must contain only characters less than 0x7F
  10. explicit TCharBuffer(const char* s) {
  11. // copy all symbols including null terminated symbol
  12. for (size_t i = 0; i < N; ++i) {
  13. Data[i] = s[i];
  14. }
  15. }
  16. const CharT* GetData() const {
  17. return Data;
  18. }
  19. };
  20. template <>
  21. struct TCharBuffer<char, 0> {
  22. const char* Data;
  23. //! stores pointer to string
  24. explicit TCharBuffer(const char* s)
  25. : Data(s)
  26. {
  27. }
  28. const char* GetData() const {
  29. return Data;
  30. }
  31. };
  32. #define DECLARE_AND_RETURN_BUFFER(s) \
  33. static TCharBuffer<CharT, sizeof(s)> buf(s); \
  34. return buf.GetData();
  35. //! @attention this class can process characters less than 0x7F only (the low half of ASCII table)
  36. template <typename CharT>
  37. struct TTestData {
  38. // words
  39. const CharT* str1() {
  40. DECLARE_AND_RETURN_BUFFER("str1");
  41. }
  42. const CharT* str2() {
  43. DECLARE_AND_RETURN_BUFFER("str2");
  44. }
  45. const CharT* str__________________________________________________1() {
  46. DECLARE_AND_RETURN_BUFFER("str 1");
  47. }
  48. const CharT* str__________________________________________________2() {
  49. DECLARE_AND_RETURN_BUFFER("str 2");
  50. }
  51. const CharT* one() {
  52. DECLARE_AND_RETURN_BUFFER("one");
  53. }
  54. const CharT* two() {
  55. DECLARE_AND_RETURN_BUFFER("two");
  56. }
  57. const CharT* three() {
  58. DECLARE_AND_RETURN_BUFFER("three");
  59. }
  60. const CharT* thrii() {
  61. DECLARE_AND_RETURN_BUFFER("thrii");
  62. }
  63. const CharT* four() {
  64. DECLARE_AND_RETURN_BUFFER("four");
  65. }
  66. const CharT* enotw_() {
  67. DECLARE_AND_RETURN_BUFFER("enotw ");
  68. }
  69. const CharT* foo() {
  70. DECLARE_AND_RETURN_BUFFER("foo");
  71. }
  72. const CharT* abcdef() {
  73. DECLARE_AND_RETURN_BUFFER("abcdef");
  74. }
  75. const CharT* abcdefg() {
  76. DECLARE_AND_RETURN_BUFFER("abcdefg");
  77. }
  78. const CharT* aba() {
  79. DECLARE_AND_RETURN_BUFFER("aba");
  80. }
  81. const CharT* hr() {
  82. DECLARE_AND_RETURN_BUFFER("hr");
  83. }
  84. const CharT* hrt() {
  85. DECLARE_AND_RETURN_BUFFER("hrt");
  86. }
  87. const CharT* thr() {
  88. DECLARE_AND_RETURN_BUFFER("thr");
  89. }
  90. const CharT* tw() {
  91. DECLARE_AND_RETURN_BUFFER("tw");
  92. }
  93. const CharT* ow() {
  94. DECLARE_AND_RETURN_BUFFER("ow");
  95. }
  96. const CharT* opq() {
  97. DECLARE_AND_RETURN_BUFFER("opq");
  98. }
  99. const CharT* xyz() {
  100. DECLARE_AND_RETURN_BUFFER("xyz");
  101. }
  102. const CharT* abc() {
  103. DECLARE_AND_RETURN_BUFFER("abc");
  104. }
  105. const CharT* abcd() {
  106. DECLARE_AND_RETURN_BUFFER("abcd");
  107. }
  108. const CharT* abcde() {
  109. DECLARE_AND_RETURN_BUFFER("abcde");
  110. }
  111. const CharT* abcc() {
  112. DECLARE_AND_RETURN_BUFFER("abcc");
  113. }
  114. const CharT* abce() {
  115. DECLARE_AND_RETURN_BUFFER("abce");
  116. }
  117. const CharT* qwe() {
  118. DECLARE_AND_RETURN_BUFFER("qwe");
  119. }
  120. const CharT* cd() {
  121. DECLARE_AND_RETURN_BUFFER("cd");
  122. }
  123. const CharT* cde() {
  124. DECLARE_AND_RETURN_BUFFER("cde");
  125. }
  126. const CharT* cdef() {
  127. DECLARE_AND_RETURN_BUFFER("cdef");
  128. }
  129. const CharT* cdefgh() {
  130. DECLARE_AND_RETURN_BUFFER("cdefgh");
  131. }
  132. const CharT* ehortw_() {
  133. DECLARE_AND_RETURN_BUFFER("ehortw ");
  134. }
  135. const CharT* fg() {
  136. DECLARE_AND_RETURN_BUFFER("fg");
  137. }
  138. const CharT* abcdefgh() {
  139. DECLARE_AND_RETURN_BUFFER("abcdefgh");
  140. }
  141. // phrases
  142. const CharT* Hello_World() {
  143. DECLARE_AND_RETURN_BUFFER("Hello World");
  144. }
  145. const CharT* This_is_test_string_for_string_calls() {
  146. DECLARE_AND_RETURN_BUFFER("This is test string for string calls");
  147. }
  148. const CharT* This_is_teis_test_string_st_string_for_string_calls() {
  149. DECLARE_AND_RETURN_BUFFER("This is teis test string st string for string calls");
  150. }
  151. const CharT* This_is_test_stis_test_string_for_stringring_for_string_calls() {
  152. DECLARE_AND_RETURN_BUFFER("This is test stis test string for stringring for string calls");
  153. }
  154. const CharT* allsThis_is_test_string_for_string_calls() {
  155. DECLARE_AND_RETURN_BUFFER("allsThis is test string for string calls");
  156. }
  157. const CharT* ng_for_string_callsThis_is_test_string_for_string_calls() {
  158. DECLARE_AND_RETURN_BUFFER("ng for string callsThis is test string for string calls");
  159. }
  160. const CharT* one_two_three_one_two_three() {
  161. DECLARE_AND_RETURN_BUFFER("one two three one two three");
  162. }
  163. const CharT* test_string_for_assign() {
  164. DECLARE_AND_RETURN_BUFFER("test string for assign");
  165. }
  166. const CharT* other_test_string() {
  167. DECLARE_AND_RETURN_BUFFER("other test string");
  168. }
  169. const CharT* This_This_is_tefor_string_calls() {
  170. DECLARE_AND_RETURN_BUFFER("This This is tefor string calls");
  171. }
  172. const CharT* This_This_is_test_string_for_string_calls() {
  173. DECLARE_AND_RETURN_BUFFER("This This is test string for string calls");
  174. }
  175. const CharT* _0123456x() {
  176. DECLARE_AND_RETURN_BUFFER("0123456x");
  177. }
  178. const CharT* _0123456xy() {
  179. DECLARE_AND_RETURN_BUFFER("0123456xy");
  180. }
  181. const CharT* _0123456xyz() {
  182. DECLARE_AND_RETURN_BUFFER("0123456xyz");
  183. }
  184. const CharT* _0123456xyzZ() {
  185. DECLARE_AND_RETURN_BUFFER("0123456xyzZ");
  186. }
  187. const CharT* _0123456xyzZ0() {
  188. DECLARE_AND_RETURN_BUFFER("0123456xyzZ0");
  189. }
  190. const CharT* abc0123456xyz() {
  191. DECLARE_AND_RETURN_BUFFER("abc0123456xyz");
  192. }
  193. const CharT* BCabc0123456xyz() {
  194. DECLARE_AND_RETURN_BUFFER("BCabc0123456xyz");
  195. }
  196. const CharT* qweBCabc0123456xyz() {
  197. DECLARE_AND_RETURN_BUFFER("qweBCabc0123456xyz");
  198. }
  199. const CharT* _1qweBCabc0123456xyz() {
  200. DECLARE_AND_RETURN_BUFFER("1qweBCabc0123456xyz");
  201. }
  202. const CharT* _01abc23456() {
  203. DECLARE_AND_RETURN_BUFFER("01abc23456");
  204. }
  205. const CharT* _01ABCabc23456() {
  206. DECLARE_AND_RETURN_BUFFER("01ABCabc23456");
  207. }
  208. const CharT* ABC() {
  209. DECLARE_AND_RETURN_BUFFER("ABC");
  210. }
  211. const CharT* ABCD() {
  212. DECLARE_AND_RETURN_BUFFER("ABCD");
  213. }
  214. const CharT* QWE() {
  215. DECLARE_AND_RETURN_BUFFER("QWE");
  216. }
  217. const CharT* XYZ() {
  218. DECLARE_AND_RETURN_BUFFER("XYZ");
  219. }
  220. const CharT* W01ABCabc23456() {
  221. DECLARE_AND_RETURN_BUFFER("W01ABCabc23456");
  222. }
  223. const CharT* abcd456() {
  224. DECLARE_AND_RETURN_BUFFER("abcd456");
  225. }
  226. const CharT* abcdABCD() {
  227. DECLARE_AND_RETURN_BUFFER("abcdABCD");
  228. }
  229. const CharT* abcdABC123() {
  230. DECLARE_AND_RETURN_BUFFER("abcdABC123");
  231. }
  232. const CharT* z123z123() {
  233. DECLARE_AND_RETURN_BUFFER("z123z123");
  234. }
  235. const CharT* ASDF1234QWER() {
  236. DECLARE_AND_RETURN_BUFFER("ASDF1234QWER");
  237. }
  238. const CharT* asdf1234qwer() {
  239. DECLARE_AND_RETURN_BUFFER("asdf1234qwer");
  240. }
  241. const CharT* asDF1234qWEr() {
  242. DECLARE_AND_RETURN_BUFFER("asDF1234qWEr");
  243. }
  244. const CharT* AsDF1234qWEr() {
  245. DECLARE_AND_RETURN_BUFFER("AsDF1234qWEr");
  246. }
  247. const CharT* Asdf1234qwer() {
  248. DECLARE_AND_RETURN_BUFFER("Asdf1234qwer");
  249. }
  250. const CharT* Asdf1234qwerWWWW() {
  251. DECLARE_AND_RETURN_BUFFER("Asdf1234qwerWWWW");
  252. }
  253. const CharT* Asdf() {
  254. DECLARE_AND_RETURN_BUFFER("Asdf");
  255. }
  256. const CharT* orig() {
  257. DECLARE_AND_RETURN_BUFFER("orig");
  258. }
  259. const CharT* fdfdsfds() {
  260. DECLARE_AND_RETURN_BUFFER("fdfdsfds");
  261. }
  262. // numbers
  263. const CharT* _0() {
  264. DECLARE_AND_RETURN_BUFFER("0");
  265. }
  266. const CharT* _00() {
  267. DECLARE_AND_RETURN_BUFFER("00");
  268. }
  269. const CharT* _0000000000() {
  270. DECLARE_AND_RETURN_BUFFER("0000000000");
  271. }
  272. const CharT* _00000() {
  273. DECLARE_AND_RETURN_BUFFER("00000");
  274. }
  275. const CharT* _0123() {
  276. DECLARE_AND_RETURN_BUFFER("0123");
  277. }
  278. const CharT* _01230123() {
  279. DECLARE_AND_RETURN_BUFFER("01230123");
  280. }
  281. const CharT* _01234() {
  282. DECLARE_AND_RETURN_BUFFER("01234");
  283. }
  284. const CharT* _0123401234() {
  285. DECLARE_AND_RETURN_BUFFER("0123401234");
  286. }
  287. const CharT* _012345() {
  288. DECLARE_AND_RETURN_BUFFER("012345");
  289. }
  290. const CharT* _0123456() {
  291. DECLARE_AND_RETURN_BUFFER("0123456");
  292. }
  293. const CharT* _1() {
  294. DECLARE_AND_RETURN_BUFFER("1");
  295. }
  296. const CharT* _11() {
  297. DECLARE_AND_RETURN_BUFFER("11");
  298. }
  299. const CharT* _1100000() {
  300. DECLARE_AND_RETURN_BUFFER("1100000");
  301. }
  302. const CharT* _110000034() {
  303. DECLARE_AND_RETURN_BUFFER("110000034");
  304. }
  305. const CharT* _12() {
  306. DECLARE_AND_RETURN_BUFFER("12");
  307. }
  308. const CharT* _123() {
  309. DECLARE_AND_RETURN_BUFFER("123");
  310. }
  311. const CharT* _1233321() {
  312. DECLARE_AND_RETURN_BUFFER("1233321");
  313. }
  314. const CharT* _1221() {
  315. DECLARE_AND_RETURN_BUFFER("1221");
  316. }
  317. const CharT* _1234123456() {
  318. DECLARE_AND_RETURN_BUFFER("1234123456");
  319. }
  320. const CharT* _12334444321() {
  321. DECLARE_AND_RETURN_BUFFER("12334444321");
  322. }
  323. const CharT* _123344544321() {
  324. DECLARE_AND_RETURN_BUFFER("123344544321");
  325. }
  326. const CharT* _1234567890123456789012345678901234567890() {
  327. DECLARE_AND_RETURN_BUFFER("1234567890123456789012345678901234567890");
  328. }
  329. const CharT* _1234() {
  330. DECLARE_AND_RETURN_BUFFER("1234");
  331. }
  332. const CharT* _12345() {
  333. DECLARE_AND_RETURN_BUFFER("12345");
  334. }
  335. const CharT* _123456() {
  336. DECLARE_AND_RETURN_BUFFER("123456");
  337. }
  338. const CharT* _1234567() {
  339. DECLARE_AND_RETURN_BUFFER("1234567");
  340. }
  341. const CharT* _1234561234() {
  342. DECLARE_AND_RETURN_BUFFER("1234561234");
  343. }
  344. const CharT* _12356() {
  345. DECLARE_AND_RETURN_BUFFER("12356");
  346. }
  347. const CharT* _1345656() {
  348. DECLARE_AND_RETURN_BUFFER("1345656");
  349. }
  350. const CharT* _15656() {
  351. DECLARE_AND_RETURN_BUFFER("15656");
  352. }
  353. const CharT* _17856() {
  354. DECLARE_AND_RETURN_BUFFER("17856");
  355. }
  356. const CharT* _1783456() {
  357. DECLARE_AND_RETURN_BUFFER("1783456");
  358. }
  359. const CharT* _2() {
  360. DECLARE_AND_RETURN_BUFFER("2");
  361. }
  362. const CharT* _2123456() {
  363. DECLARE_AND_RETURN_BUFFER("2123456");
  364. }
  365. const CharT* _23() {
  366. DECLARE_AND_RETURN_BUFFER("23");
  367. }
  368. const CharT* _2345() {
  369. DECLARE_AND_RETURN_BUFFER("2345");
  370. }
  371. const CharT* _3() {
  372. DECLARE_AND_RETURN_BUFFER("3");
  373. }
  374. const CharT* _345() {
  375. DECLARE_AND_RETURN_BUFFER("345");
  376. }
  377. const CharT* _3456() {
  378. DECLARE_AND_RETURN_BUFFER("3456");
  379. }
  380. const CharT* _333333() {
  381. DECLARE_AND_RETURN_BUFFER("333333");
  382. }
  383. const CharT* _389() {
  384. DECLARE_AND_RETURN_BUFFER("389");
  385. }
  386. const CharT* _4294967295() {
  387. DECLARE_AND_RETURN_BUFFER("4294967295");
  388. }
  389. const CharT* _4444() {
  390. DECLARE_AND_RETURN_BUFFER("4444");
  391. }
  392. const CharT* _5() {
  393. DECLARE_AND_RETURN_BUFFER("5");
  394. }
  395. const CharT* _6() {
  396. DECLARE_AND_RETURN_BUFFER("6");
  397. }
  398. const CharT* _6543210() {
  399. DECLARE_AND_RETURN_BUFFER("6543210");
  400. }
  401. const CharT* _7() {
  402. DECLARE_AND_RETURN_BUFFER("7");
  403. }
  404. const CharT* _78() {
  405. DECLARE_AND_RETURN_BUFFER("78");
  406. }
  407. const CharT* _2004_01_01() {
  408. DECLARE_AND_RETURN_BUFFER("2004-01-01");
  409. }
  410. const CharT* _1234562004_01_01() {
  411. DECLARE_AND_RETURN_BUFFER("1234562004-01-01");
  412. }
  413. const CharT* _0123456_12345() {
  414. DECLARE_AND_RETURN_BUFFER("0123456_12345");
  415. }
  416. // letters
  417. const CharT* a() {
  418. DECLARE_AND_RETURN_BUFFER("a");
  419. }
  420. const CharT* b() {
  421. DECLARE_AND_RETURN_BUFFER("b");
  422. }
  423. const CharT* c() {
  424. DECLARE_AND_RETURN_BUFFER("c");
  425. }
  426. const CharT* d() {
  427. DECLARE_AND_RETURN_BUFFER("d");
  428. }
  429. const CharT* e() {
  430. DECLARE_AND_RETURN_BUFFER("e");
  431. }
  432. const CharT* f() {
  433. DECLARE_AND_RETURN_BUFFER("f");
  434. }
  435. const CharT* h() {
  436. DECLARE_AND_RETURN_BUFFER("h");
  437. }
  438. const CharT* o() {
  439. DECLARE_AND_RETURN_BUFFER("o");
  440. }
  441. const CharT* p() {
  442. DECLARE_AND_RETURN_BUFFER("p");
  443. }
  444. const CharT* q() {
  445. DECLARE_AND_RETURN_BUFFER("q");
  446. }
  447. const CharT* r() {
  448. DECLARE_AND_RETURN_BUFFER("r");
  449. }
  450. const CharT* s() {
  451. DECLARE_AND_RETURN_BUFFER("s");
  452. }
  453. const CharT* t() {
  454. DECLARE_AND_RETURN_BUFFER("t");
  455. }
  456. const CharT* w() {
  457. DECLARE_AND_RETURN_BUFFER("w");
  458. }
  459. const CharT* x() {
  460. DECLARE_AND_RETURN_BUFFER("x");
  461. }
  462. const CharT* y() {
  463. DECLARE_AND_RETURN_BUFFER("y");
  464. }
  465. const CharT* z() {
  466. DECLARE_AND_RETURN_BUFFER("z");
  467. }
  468. const CharT* H() {
  469. DECLARE_AND_RETURN_BUFFER("H");
  470. }
  471. const CharT* I() {
  472. DECLARE_AND_RETURN_BUFFER("I");
  473. }
  474. const CharT* W() {
  475. DECLARE_AND_RETURN_BUFFER("W");
  476. }
  477. const CharT* Space() {
  478. DECLARE_AND_RETURN_BUFFER(" ");
  479. }
  480. const CharT* Empty() {
  481. DECLARE_AND_RETURN_BUFFER("");
  482. }
  483. size_t HashOf_0123456() {
  484. return 0;
  485. }
  486. };
  487. template <>
  488. size_t TTestData<char>::HashOf_0123456() {
  489. return 1229863857ul;
  490. }
  491. template <>
  492. size_t TTestData<wchar16>::HashOf_0123456() {
  493. return 2775195331ul;
  494. }
  495. template <class TStringType, typename TTestData>
  496. class TStringTestImpl {
  497. protected:
  498. using char_type = typename TStringType::char_type;
  499. using traits_type = typename TStringType::traits_type;
  500. TTestData Data;
  501. public:
  502. void TestMaxSize() {
  503. const size_t badMaxVal = TStringType{}.max_size() + 1;
  504. TStringType s;
  505. UNIT_CHECK_GENERATED_EXCEPTION(s.reserve(badMaxVal), std::length_error);
  506. }
  507. void TestConstructors() {
  508. TStringType s0(nullptr);
  509. UNIT_ASSERT(s0.size() == 0);
  510. UNIT_ASSERT_EQUAL(s0, TStringType());
  511. TStringType s;
  512. TStringType s1(*Data._0());
  513. TStringType s2(Data._0());
  514. UNIT_ASSERT(s1 == s2);
  515. TStringType fromZero(0);
  516. UNIT_ASSERT_VALUES_EQUAL(fromZero.size(), 0u);
  517. TStringType fromChar(char_type('a'));
  518. UNIT_ASSERT_VALUES_EQUAL(fromChar.size(), 1u);
  519. UNIT_ASSERT_VALUES_EQUAL(fromChar[0], char_type('a'));
  520. #ifndef TSTRING_IS_STD_STRING
  521. TStringType s3 = TStringType::Uninitialized(10);
  522. UNIT_ASSERT(s3.size() == 10);
  523. #endif
  524. TStringType s4(Data._0123456(), 1, 3);
  525. UNIT_ASSERT(s4 == Data._123());
  526. TStringType s5(5, *Data._0());
  527. UNIT_ASSERT(s5 == Data._00000());
  528. TStringType s6(Data._0123456());
  529. UNIT_ASSERT(s6 == Data._0123456());
  530. TStringType s7(s6);
  531. UNIT_ASSERT(s7 == s6);
  532. #ifndef TSTRING_IS_STD_STRING
  533. UNIT_ASSERT(s7.c_str() == s6.c_str());
  534. #endif
  535. TStringType s8(s7, 1, 3);
  536. UNIT_ASSERT(s8 == Data._123());
  537. TStringType s9(*Data._1());
  538. UNIT_ASSERT(s9 == Data._1());
  539. TStringType s10(Reserve(100));
  540. UNIT_ASSERT(s10.empty());
  541. UNIT_ASSERT(s10.capacity() >= 100);
  542. }
  543. void TestReplace() {
  544. TStringType s(Data._0123456());
  545. UNIT_ASSERT(s.copy() == Data._0123456());
  546. // append family
  547. s.append(Data.x());
  548. UNIT_ASSERT(s == Data._0123456x());
  549. #ifdef TSTRING_IS_STD_STRING
  550. s.append(Data.xyz() + 1, 1);
  551. #else
  552. s.append(Data.xyz(), 1, 1);
  553. #endif
  554. UNIT_ASSERT(s == Data._0123456xy());
  555. s.append(TStringType(Data.z()));
  556. UNIT_ASSERT(s == Data._0123456xyz());
  557. s.append(TStringType(Data.XYZ()), 2, 1);
  558. UNIT_ASSERT(s == Data._0123456xyzZ());
  559. s.append(*Data._0());
  560. UNIT_ASSERT(s == Data._0123456xyzZ0());
  561. // prepend family
  562. s = Data._0123456xyz();
  563. s.prepend(TStringType(Data.abc()));
  564. UNIT_ASSERT(s == Data.abc0123456xyz());
  565. s.prepend(TStringType(Data.ABC()), 1, 2);
  566. UNIT_ASSERT(s == Data.BCabc0123456xyz());
  567. s.prepend(Data.qwe());
  568. UNIT_ASSERT(s == Data.qweBCabc0123456xyz());
  569. s.prepend(*Data._1());
  570. UNIT_ASSERT(s == Data._1qweBCabc0123456xyz());
  571. // substr
  572. s = Data.abc0123456xyz();
  573. s = s.substr(3, 7);
  574. UNIT_ASSERT(s == Data._0123456());
  575. // insert family
  576. s.insert(2, Data.abc());
  577. UNIT_ASSERT(s == Data._01abc23456());
  578. s.insert(2, TStringType(Data.ABC()));
  579. UNIT_ASSERT(s == Data._01ABCabc23456());
  580. s.insert(0, TStringType(Data.QWE()), 1, 1);
  581. UNIT_ASSERT(s == Data.W01ABCabc23456());
  582. // replace family
  583. s = Data._01abc23456();
  584. s.replace(0, 7, Data.abcd());
  585. UNIT_ASSERT(s == Data.abcd456());
  586. s.replace(4, 3, TStringType(Data.ABCD()));
  587. UNIT_ASSERT(s == Data.abcdABCD());
  588. s.replace(7, 10, TStringType(Data._01234()), 1, 3);
  589. UNIT_ASSERT(s == Data.abcdABC123());
  590. UNIT_ASSERT(Data.abcdABC123() == s);
  591. // remove, erase
  592. s.remove(4);
  593. UNIT_ASSERT(s == Data.abcd());
  594. s.erase(3);
  595. UNIT_ASSERT(s == Data.abc());
  596. // Read access
  597. s = Data._012345();
  598. UNIT_ASSERT(s.at(1) == *Data._1());
  599. UNIT_ASSERT(s[1] == *Data._1());
  600. UNIT_ASSERT(s.at(s.size()) == 0);
  601. UNIT_ASSERT(s[s.size()] == 0);
  602. }
  603. #ifndef TSTRING_IS_STD_STRING
  604. void TestRefCount() {
  605. using TStr = TStringType;
  606. struct TestStroka: public TStr {
  607. using TStr::TStr;
  608. // un-protect
  609. using TStr::RefCount;
  610. };
  611. TestStroka s1(Data.orig());
  612. UNIT_ASSERT_EQUAL(s1.RefCount() == 1, true);
  613. TestStroka s2(s1);
  614. UNIT_ASSERT_EQUAL(s1.RefCount() == 2, true);
  615. UNIT_ASSERT_EQUAL(s2.RefCount() == 2, true);
  616. UNIT_ASSERT_EQUAL(s1.c_str() == s2.c_str(), true); // the same pointer
  617. char_type* beg = s2.begin();
  618. UNIT_ASSERT_EQUAL(s1 == beg, true);
  619. UNIT_ASSERT_EQUAL(s1.RefCount() == 1, true);
  620. UNIT_ASSERT_EQUAL(s2.RefCount() == 1, true);
  621. UNIT_ASSERT_EQUAL(s1.c_str() == s2.c_str(), false);
  622. }
  623. #endif
  624. // Find family
  625. void TestFind() {
  626. const TStringType s(Data._0123456_12345());
  627. const TStringType s2(Data._0123());
  628. UNIT_ASSERT(s.find(Data._345()) == 3);
  629. UNIT_ASSERT(s.find(Data._345(), 5) == 10);
  630. UNIT_ASSERT(s.find(Data._345(), 20) == TStringType::npos);
  631. UNIT_ASSERT(s.find(*Data._3()) == 3);
  632. UNIT_ASSERT(s.find(TStringType(Data._345())) == 3);
  633. UNIT_ASSERT(s.find(TStringType(Data._345()), 2) == 3);
  634. UNIT_ASSERT(s.find_first_of(TStringType(Data._389())) == 3);
  635. UNIT_ASSERT(s.find_first_of(Data._389()) == 3);
  636. UNIT_ASSERT(s.find_first_of(Data._389(), s.size()) == TStringType::npos);
  637. UNIT_ASSERT(s.find_first_not_of(Data._123()) == 0);
  638. UNIT_ASSERT(s.find_first_of('6') == 6);
  639. UNIT_ASSERT(s.find_first_of('1', 2) == 8);
  640. UNIT_ASSERT(s.find_first_not_of('0') == 1);
  641. UNIT_ASSERT(s.find_first_not_of('1', 1) == 2);
  642. const TStringType rs = Data._0123401234();
  643. UNIT_ASSERT(rs.rfind(*Data._3()) == 8);
  644. const TStringType empty;
  645. UNIT_ASSERT(empty.find(empty) == 0);
  646. UNIT_ASSERT(s.find(empty, 0) == 0);
  647. UNIT_ASSERT(s.find(empty, 1) == 1);
  648. UNIT_ASSERT(s.find(empty, s.length()) == s.length());
  649. UNIT_ASSERT(s.find(empty, s.length() + 1) == TStringType::npos);
  650. UNIT_ASSERT(s.rfind(empty) == s.length());
  651. UNIT_ASSERT(empty.rfind(empty) == 0);
  652. UNIT_ASSERT(empty.rfind(s) == TStringType::npos);
  653. UNIT_ASSERT(s2.rfind(s) == TStringType::npos);
  654. UNIT_ASSERT(s.rfind(s2) == 0);
  655. UNIT_ASSERT(s.rfind(TStringType(Data._345())) == 10);
  656. UNIT_ASSERT(s.rfind(TStringType(Data._345()), 13) == 10);
  657. UNIT_ASSERT(s.rfind(TStringType(Data._345()), 10) == 10);
  658. UNIT_ASSERT(s.rfind(TStringType(Data._345()), 9) == 3);
  659. UNIT_ASSERT(s.rfind(TStringType(Data._345()), 6) == 3);
  660. UNIT_ASSERT(s.rfind(TStringType(Data._345()), 3) == 3);
  661. UNIT_ASSERT(s.rfind(TStringType(Data._345()), 2) == TStringType::npos);
  662. }
  663. void TestContains() {
  664. const TStringType s(Data._0123456_12345());
  665. const TStringType s2(Data._0123());
  666. UNIT_ASSERT(s.Contains(Data._345()));
  667. UNIT_ASSERT(!s2.Contains(Data._345()));
  668. UNIT_ASSERT(s.Contains('1'));
  669. UNIT_ASSERT(!s.Contains('*'));
  670. TStringType empty;
  671. UNIT_ASSERT(s.Contains(empty));
  672. UNIT_ASSERT(!empty.Contains(s));
  673. UNIT_ASSERT(empty.Contains(empty));
  674. UNIT_ASSERT(s.Contains(empty, s.length()));
  675. }
  676. // Operators
  677. void TestOperators() {
  678. TStringType s(Data._0123456());
  679. // operator +=
  680. s += TStringType(Data.x());
  681. UNIT_ASSERT(s == Data._0123456x());
  682. s += Data.y();
  683. UNIT_ASSERT(s == Data._0123456xy());
  684. s += *Data.z();
  685. UNIT_ASSERT(s == Data._0123456xyz());
  686. // operator +
  687. s = Data._0123456();
  688. s = s + TStringType(Data.x());
  689. UNIT_ASSERT(s == Data._0123456x());
  690. s = s + Data.y();
  691. UNIT_ASSERT(s == Data._0123456xy());
  692. s = s + *Data.z();
  693. UNIT_ASSERT(s == Data._0123456xyz());
  694. // operator !=
  695. s = Data._012345();
  696. UNIT_ASSERT(s != TStringType(Data.xyz()));
  697. UNIT_ASSERT(s != Data.xyz());
  698. UNIT_ASSERT(Data.xyz() != s);
  699. // operator <
  700. UNIT_ASSERT_EQUAL(s < TStringType(Data.xyz()), true);
  701. UNIT_ASSERT_EQUAL(s < Data.xyz(), true);
  702. UNIT_ASSERT_EQUAL(Data.xyz() < s, false);
  703. // operator <=
  704. UNIT_ASSERT_EQUAL(s <= TStringType(Data.xyz()), true);
  705. UNIT_ASSERT_EQUAL(s <= Data.xyz(), true);
  706. UNIT_ASSERT_EQUAL(Data.xyz() <= s, false);
  707. // operator >
  708. UNIT_ASSERT_EQUAL(s > TStringType(Data.xyz()), false);
  709. UNIT_ASSERT_EQUAL(s > Data.xyz(), false);
  710. UNIT_ASSERT_EQUAL(Data.xyz() > s, true);
  711. // operator >=
  712. UNIT_ASSERT_EQUAL(s >= TStringType(Data.xyz()), false);
  713. UNIT_ASSERT_EQUAL(s >= Data.xyz(), false);
  714. UNIT_ASSERT_EQUAL(Data.xyz() >= s, true);
  715. }
  716. void TestOperatorsCI() {
  717. TStringType s(Data.ABCD());
  718. UNIT_ASSERT(s > Data.abc0123456xyz());
  719. UNIT_ASSERT(s == Data.abcd());
  720. using TCIStringBuf = TBasicStringBuf<char_type, traits_type>;
  721. UNIT_ASSERT(s > TCIStringBuf(Data.abc0123456xyz()));
  722. UNIT_ASSERT(TCIStringBuf(Data.abc0123456xyz()) < s);
  723. UNIT_ASSERT(s == TCIStringBuf(Data.abcd()));
  724. }
  725. void TestMulOperators() {
  726. {
  727. TStringType s(Data._0());
  728. s *= 10;
  729. UNIT_ASSERT_EQUAL(s, TStringType(Data._0000000000()));
  730. }
  731. {
  732. TStringType s = TStringType(Data._0()) * 2;
  733. UNIT_ASSERT_EQUAL(s, TStringType(Data._00()));
  734. }
  735. }
  736. // Test any other functions
  737. void TestFuncs() {
  738. TStringType s(Data._0123456());
  739. UNIT_ASSERT(s.c_str() == s.data());
  740. // length()
  741. UNIT_ASSERT(s.length() == s.size());
  742. UNIT_ASSERT(s.length() == traits_type::length(s.data()));
  743. // is_null()
  744. TStringType s1(Data.Empty());
  745. UNIT_ASSERT(s1.is_null() == true);
  746. UNIT_ASSERT(s1.is_null() == s1.empty());
  747. UNIT_ASSERT(s1.is_null() == !s1);
  748. TStringType s2(s);
  749. UNIT_ASSERT(s2 == s);
  750. // reverse()
  751. ReverseInPlace(s2);
  752. UNIT_ASSERT(s2 == Data._6543210());
  753. // to_upper()
  754. s2 = Data.asdf1234qwer();
  755. s2.to_upper();
  756. UNIT_ASSERT(s2 == Data.ASDF1234QWER());
  757. // to_lower()
  758. s2.to_lower();
  759. UNIT_ASSERT(s2 == Data.asdf1234qwer());
  760. // to_title()
  761. s2 = Data.asDF1234qWEr();
  762. s2.to_title();
  763. UNIT_ASSERT(s2 == Data.Asdf1234qwer());
  764. s2 = Data.AsDF1234qWEr();
  765. s2.to_title();
  766. UNIT_ASSERT(s2 == Data.Asdf1234qwer());
  767. // Friend functions
  768. s2 = Data.asdf1234qwer();
  769. TStringType s3 = to_upper(s2);
  770. UNIT_ASSERT(s3 == Data.ASDF1234QWER());
  771. s3 = to_lower(s2);
  772. UNIT_ASSERT(s3 == Data.asdf1234qwer());
  773. s3 = to_title(s2);
  774. UNIT_ASSERT(s3 == Data.Asdf1234qwer());
  775. s2 = s3;
  776. // resize family
  777. s2.resize(s2.size()); // without length change
  778. UNIT_ASSERT(s2 == Data.Asdf1234qwer());
  779. s2.resize(s2.size() + 4, *Data.W());
  780. UNIT_ASSERT(s2 == Data.Asdf1234qwerWWWW());
  781. s2.resize(4);
  782. UNIT_ASSERT(s2 == Data.Asdf());
  783. // assign family
  784. s2 = Data.asdf1234qwer();
  785. s2.assign(s, 1, 3);
  786. UNIT_ASSERT(s2 == Data._123());
  787. s2.assign(Data._0123456(), 4);
  788. UNIT_ASSERT(s2 == Data._0123());
  789. s2.assign('1');
  790. UNIT_ASSERT(s2 == Data._1());
  791. s2.assign(Data._0123456());
  792. UNIT_ASSERT(s2 == Data._0123456());
  793. // hash()
  794. TStringType sS = s2; // type 'TStringType' is used as is
  795. ComputeHash(sS); /*size_t hash_val = sS.hash();
  796. try {
  797. //UNIT_ASSERT(hash_val == Data.HashOf_0123456());
  798. } catch (...) {
  799. Cerr << hash_val << Endl;
  800. throw;
  801. }*/
  802. s2.assign(Data._0123456(), 2, 2);
  803. UNIT_ASSERT(s2 == Data._23());
  804. // s2.reserve();
  805. TStringType s5(Data.abcde());
  806. s5.clear();
  807. UNIT_ASSERT(s5 == Data.Empty());
  808. }
  809. void TestUtils() {
  810. TStringType s;
  811. s = Data._01230123();
  812. TStringType from = Data._0();
  813. TStringType to = Data.z();
  814. SubstGlobal(s, from, to);
  815. UNIT_ASSERT(s == Data.z123z123());
  816. }
  817. void TestEmpty() {
  818. TStringType s;
  819. s = Data._2();
  820. s = TStringType(Data.fdfdsfds(), (size_t)0, (size_t)0);
  821. UNIT_ASSERT(s.empty());
  822. }
  823. void TestJoin() {
  824. UNIT_ASSERT_EQUAL(TStringType::Join(Data._12(), Data._3456()), Data._123456());
  825. UNIT_ASSERT_EQUAL(TStringType::Join(Data._12(), TStringType(Data._3456())), Data._123456());
  826. UNIT_ASSERT_EQUAL(TStringType::Join(TStringType(Data._12()), Data._3456()), Data._123456());
  827. UNIT_ASSERT_EQUAL(TStringType::Join(Data._12(), Data._345(), Data._6()), Data._123456());
  828. UNIT_ASSERT_EQUAL(TStringType::Join(Data._12(), TStringType(Data._345()), Data._6()), Data._123456());
  829. UNIT_ASSERT_EQUAL(TStringType::Join(TStringType(Data._12()), TStringType(Data._345()), Data._6()), Data._123456());
  830. UNIT_ASSERT_EQUAL(TStringType::Join(TStringType(Data.a()), Data.b(), TStringType(Data.cd()), TStringType(Data.e()), Data.fg(), TStringType(Data.h())), Data.abcdefgh());
  831. UNIT_ASSERT_EQUAL(TStringType::Join(TStringType(Data.a()), static_cast<typename TStringType::char_type>('b'), TStringType(Data.cd()), TStringType(Data.e()), Data.fg(), TStringType(Data.h())), Data.abcdefgh());
  832. }
  833. void TestCopy() {
  834. TStringType s(Data.abcd());
  835. TStringType c = s.copy();
  836. UNIT_ASSERT_EQUAL(s, c);
  837. UNIT_ASSERT(s.end() != c.end());
  838. }
  839. void TestStrCpy() {
  840. {
  841. TStringType s(Data.abcd());
  842. char_type data[5];
  843. data[4] = 1;
  844. s.strcpy(data, 4);
  845. UNIT_ASSERT_EQUAL(data[0], *Data.a());
  846. UNIT_ASSERT_EQUAL(data[1], *Data.b());
  847. UNIT_ASSERT_EQUAL(data[2], *Data.c());
  848. UNIT_ASSERT_EQUAL(data[3], 0);
  849. UNIT_ASSERT_EQUAL(data[4], 1);
  850. }
  851. {
  852. TStringType s(Data.abcd());
  853. char_type data[5];
  854. s.strcpy(data, 5);
  855. UNIT_ASSERT_EQUAL(data[0], *Data.a());
  856. UNIT_ASSERT_EQUAL(data[1], *Data.b());
  857. UNIT_ASSERT_EQUAL(data[2], *Data.c());
  858. UNIT_ASSERT_EQUAL(data[3], *Data.d());
  859. UNIT_ASSERT_EQUAL(data[4], 0);
  860. }
  861. }
  862. void TestPrefixSuffix() {
  863. const TStringType emptyStr;
  864. UNIT_ASSERT_EQUAL(emptyStr.StartsWith('x'), false);
  865. UNIT_ASSERT_EQUAL(emptyStr.EndsWith('x'), false);
  866. UNIT_ASSERT_EQUAL(emptyStr.StartsWith(0), false);
  867. UNIT_ASSERT_EQUAL(emptyStr.EndsWith(0), false);
  868. UNIT_ASSERT_EQUAL(emptyStr.StartsWith(emptyStr), true);
  869. UNIT_ASSERT_EQUAL(emptyStr.EndsWith(emptyStr), true);
  870. const char_type chars[] = {'h', 'e', 'l', 'l', 'o', 0};
  871. const TStringType str(chars);
  872. UNIT_ASSERT_EQUAL(str.StartsWith('h'), true);
  873. UNIT_ASSERT_EQUAL(str.StartsWith('o'), false);
  874. UNIT_ASSERT_EQUAL(str.EndsWith('o'), true);
  875. UNIT_ASSERT_EQUAL(str.EndsWith('h'), false);
  876. UNIT_ASSERT_EQUAL(str.StartsWith(emptyStr), true);
  877. UNIT_ASSERT_EQUAL(str.EndsWith(emptyStr), true);
  878. }
  879. #ifndef TSTRING_IS_STD_STRING
  880. void TestCharRef() {
  881. const char_type abc[] = {'a', 'b', 'c', 0};
  882. const char_type bbc[] = {'b', 'b', 'c', 0};
  883. const char_type cbc[] = {'c', 'b', 'c', 0};
  884. TStringType s0 = abc;
  885. TStringType s1 = s0;
  886. UNIT_ASSERT(!s0.IsDetached());
  887. UNIT_ASSERT(!s1.IsDetached());
  888. /* Read access shouldn't detach. */
  889. UNIT_ASSERT_VALUES_EQUAL(s0[0], (ui8)'a');
  890. UNIT_ASSERT(!s0.IsDetached());
  891. UNIT_ASSERT(!s1.IsDetached());
  892. /* Writing should detach. */
  893. s1[0] = (ui8)'b';
  894. TStringType s2 = s0;
  895. s0[0] = (ui8)'c';
  896. UNIT_ASSERT_VALUES_EQUAL(s0, cbc);
  897. UNIT_ASSERT_VALUES_EQUAL(s1, bbc);
  898. UNIT_ASSERT_VALUES_EQUAL(s2, abc);
  899. UNIT_ASSERT(s0.IsDetached());
  900. UNIT_ASSERT(s1.IsDetached());
  901. UNIT_ASSERT(s2.IsDetached());
  902. /* Accessing null terminator is OK. Note that writing into it is UB. */
  903. UNIT_ASSERT_VALUES_EQUAL(s0[3], (ui8)'\0');
  904. UNIT_ASSERT_VALUES_EQUAL(s1[3], (ui8)'\0');
  905. UNIT_ASSERT_VALUES_EQUAL(s2[3], (ui8)'\0');
  906. /* Assignment one char reference to another results in modification of underlying character */
  907. {
  908. const char_type dark_eyed[] = {'d', 'a', 'r', 'k', '-', 'e', 'y', 'e', 'd', 0};
  909. const char_type red_eared[] = {'r', 'e', 'd', '-', 'e', 'a', 'r', 'e', 'd', 0};
  910. TStringType s0 = dark_eyed;
  911. TStringType s1 = TStringType::Uninitialized(s0.size());
  912. for (size_t i = 0; i < s1.size(); ++i) {
  913. const size_t j = (3u * (i + 1u) ^ 1u) % s0.size();
  914. s1[i] = s0[j];
  915. }
  916. UNIT_ASSERT_VALUES_EQUAL(s1, red_eared);
  917. }
  918. }
  919. #endif
  920. void TestBack() {
  921. const char_type chars[] = {'f', 'o', 'o', 0};
  922. TStringType str = chars;
  923. const TStringType constStr = str;
  924. UNIT_ASSERT_VALUES_EQUAL(constStr.back(), (ui8)'o');
  925. UNIT_ASSERT_VALUES_EQUAL(str.back(), (ui8)'o');
  926. str.back() = 'r';
  927. UNIT_ASSERT_VALUES_EQUAL(constStr.back(), (ui8)'o');
  928. UNIT_ASSERT_VALUES_EQUAL(str.back(), (ui8)'r');
  929. }
  930. void TestFront() {
  931. const char_type chars[] = {'f', 'o', 'o', 0};
  932. TStringType str = chars;
  933. const TStringType constStr = str;
  934. UNIT_ASSERT_VALUES_EQUAL(constStr.front(), (ui8)'f');
  935. UNIT_ASSERT_VALUES_EQUAL(str.front(), (ui8)'f');
  936. str.front() = 'r';
  937. UNIT_ASSERT_VALUES_EQUAL(constStr.front(), (ui8)'f');
  938. UNIT_ASSERT_VALUES_EQUAL(str.front(), (ui8)'r');
  939. }
  940. void TestIterators() {
  941. const char_type chars[] = {'f', 'o', 0};
  942. TStringType str = chars;
  943. const TStringType constStr = str;
  944. typename TStringType::const_iterator itBegin = str.begin();
  945. typename TStringType::const_iterator itEnd = str.end();
  946. typename TStringType::const_iterator citBegin = constStr.begin();
  947. typename TStringType::const_iterator citEnd = constStr.end();
  948. UNIT_ASSERT_VALUES_EQUAL(*itBegin, (ui8)'f');
  949. UNIT_ASSERT_VALUES_EQUAL(*citBegin, (ui8)'f');
  950. str.front() = 'r';
  951. UNIT_ASSERT_VALUES_EQUAL(*itBegin, (ui8)'r');
  952. UNIT_ASSERT_VALUES_EQUAL(*citBegin, (ui8)'f');
  953. UNIT_ASSERT_VALUES_EQUAL(2, itEnd - itBegin);
  954. UNIT_ASSERT_VALUES_EQUAL(2, citEnd - citBegin);
  955. UNIT_ASSERT_VALUES_EQUAL(*(++itBegin), (ui8)'o');
  956. UNIT_ASSERT_VALUES_EQUAL(*(++citBegin), (ui8)'o');
  957. UNIT_ASSERT_VALUES_EQUAL(*(--itBegin), (ui8)'r');
  958. UNIT_ASSERT_VALUES_EQUAL(*(--citBegin), (ui8)'f');
  959. UNIT_ASSERT_VALUES_EQUAL(*(itBegin++), (ui8)'r');
  960. UNIT_ASSERT_VALUES_EQUAL(*(citBegin++), (ui8)'f');
  961. UNIT_ASSERT_VALUES_EQUAL(*itBegin, (ui8)'o');
  962. UNIT_ASSERT_VALUES_EQUAL(*citBegin, (ui8)'o');
  963. UNIT_ASSERT_VALUES_EQUAL(*(itBegin--), (ui8)'o');
  964. UNIT_ASSERT_VALUES_EQUAL(*(citBegin--), (ui8)'o');
  965. UNIT_ASSERT_VALUES_EQUAL(*itBegin, (ui8)'r');
  966. UNIT_ASSERT_VALUES_EQUAL(*citBegin, (ui8)'f');
  967. }
  968. void TestReverseIterators() {
  969. const char_type chars[] = {'f', 'o', 0};
  970. TStringType str = chars;
  971. const TStringType constStr = str;
  972. typename TStringType::reverse_iterator ritBegin = str.rbegin();
  973. typename TStringType::reverse_iterator ritEnd = str.rend();
  974. typename TStringType::const_reverse_iterator critBegin = constStr.rbegin();
  975. typename TStringType::const_reverse_iterator critEnd = constStr.rend();
  976. UNIT_ASSERT_VALUES_EQUAL(*ritBegin, (ui8)'o');
  977. UNIT_ASSERT_VALUES_EQUAL(*critBegin, (ui8)'o');
  978. str.back() = (ui8)'r';
  979. UNIT_ASSERT_VALUES_EQUAL(*ritBegin, (ui8)'r');
  980. UNIT_ASSERT_VALUES_EQUAL(*critBegin, (ui8)'o');
  981. UNIT_ASSERT_VALUES_EQUAL(2, ritEnd - ritBegin);
  982. UNIT_ASSERT_VALUES_EQUAL(2, critEnd - critBegin);
  983. UNIT_ASSERT_VALUES_EQUAL(*(++ritBegin), (ui8)'f');
  984. UNIT_ASSERT_VALUES_EQUAL(*(++critBegin), (ui8)'f');
  985. UNIT_ASSERT_VALUES_EQUAL(*(--ritBegin), (ui8)'r');
  986. UNIT_ASSERT_VALUES_EQUAL(*(--critBegin), (ui8)'o');
  987. UNIT_ASSERT_VALUES_EQUAL(*(ritBegin++), (ui8)'r');
  988. UNIT_ASSERT_VALUES_EQUAL(*(critBegin++), (ui8)'o');
  989. UNIT_ASSERT_VALUES_EQUAL(*ritBegin, (ui8)'f');
  990. UNIT_ASSERT_VALUES_EQUAL(*critBegin, (ui8)'f');
  991. UNIT_ASSERT_VALUES_EQUAL(*(ritBegin--), (ui8)'f');
  992. UNIT_ASSERT_VALUES_EQUAL(*(critBegin--), (ui8)'f');
  993. UNIT_ASSERT_VALUES_EQUAL(*ritBegin, (ui8)'r');
  994. UNIT_ASSERT_VALUES_EQUAL(*critBegin, (ui8)'o');
  995. *ritBegin = (ui8)'e';
  996. UNIT_ASSERT_VALUES_EQUAL(*ritBegin, (ui8)'e');
  997. str = chars;
  998. auto it = std::find_if(
  999. str.rbegin(), str.rend(),
  1000. [](char_type c) { return c == 'o'; });
  1001. UNIT_ASSERT_EQUAL(it, str.rbegin());
  1002. }
  1003. };