| 1003 | |
| 1004 | #ifndef TSTRING_IS_STD_STRING |
| 1005 | void TestCharRef() { |
| 1006 | const char_type abc[] = {'a', 'b', 'c', 0}; |
| 1007 | const char_type bbc[] = {'b', 'b', 'c', 0}; |
| 1008 | const char_type cbc[] = {'c', 'b', 'c', 0}; |
| 1009 | |
| 1010 | TStringType s0 = abc; |
| 1011 | TStringType s1 = s0; |
| 1012 | |
| 1013 | UNIT_ASSERT(!s0.IsDetached()); |
| 1014 | UNIT_ASSERT(!s1.IsDetached()); |
| 1015 | |
| 1016 | /* Read access shouldn't detach. */ |
| 1017 | UNIT_ASSERT_VALUES_EQUAL(s0[0], (ui8)'a'); |
| 1018 | UNIT_ASSERT(!s0.IsDetached()); |
| 1019 | UNIT_ASSERT(!s1.IsDetached()); |
| 1020 | |
| 1021 | /* Writing should detach. */ |
| 1022 | s1[0] = (ui8)'b'; |
| 1023 | TStringType s2 = s0; |
| 1024 | s0[0] = (ui8)'c'; |
| 1025 | |
| 1026 | UNIT_ASSERT_VALUES_EQUAL(s0, cbc); |
| 1027 | UNIT_ASSERT_VALUES_EQUAL(s1, bbc); |
| 1028 | UNIT_ASSERT_VALUES_EQUAL(s2, abc); |
| 1029 | UNIT_ASSERT(s0.IsDetached()); |
| 1030 | UNIT_ASSERT(s1.IsDetached()); |
| 1031 | UNIT_ASSERT(s2.IsDetached()); |
| 1032 | |
| 1033 | /* Accessing null terminator is OK. Note that writing into it is UB. */ |
| 1034 | UNIT_ASSERT_VALUES_EQUAL(s0[3], (ui8)'\0'); |
| 1035 | UNIT_ASSERT_VALUES_EQUAL(s1[3], (ui8)'\0'); |
| 1036 | UNIT_ASSERT_VALUES_EQUAL(s2[3], (ui8)'\0'); |
| 1037 | |
| 1038 | /* Assignment one char reference to another results in modification of underlying character */ |
| 1039 | { |
| 1040 | const char_type dark_eyed[] = {'d', 'a', 'r', 'k', '-', 'e', 'y', 'e', 'd', 0}; |
| 1041 | const char_type red_eared[] = {'r', 'e', 'd', '-', 'e', 'a', 'r', 'e', 'd', 0}; |
| 1042 | TStringType s0 = dark_eyed; |
| 1043 | TStringType s1 = TStringType::Uninitialized(s0.size()); |
| 1044 | for (size_t i = 0; i < s1.size(); ++i) { |
| 1045 | const size_t j = (3u * (i + 1u) ^ 1u) % s0.size(); |
| 1046 | s1[i] = s0[j]; |
| 1047 | } |
| 1048 | UNIT_ASSERT_VALUES_EQUAL(s1, red_eared); |
| 1049 | } |
| 1050 | } |
| 1051 | #endif |
| 1052 | |
| 1053 | void TestBack() { |
nothing calls this directly
no test coverage detected