2 * Copyright 2017 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 // Author: andrei.alexandrescu@fb.com
20 #include <folly/FBString.h>
28 #include <boost/algorithm/string.hpp>
29 #include <boost/random.hpp>
31 #include <folly/Conv.h>
32 #include <folly/Portability.h>
33 #include <folly/Random.h>
34 #include <folly/container/Foreach.h>
35 #include <folly/portability/GTest.h>
38 using namespace folly;
42 static const int seed = folly::randomNumberSeed();
43 typedef boost::mt19937 RandomT;
44 static RandomT rng(seed);
45 static const size_t maxString = 100;
46 static const bool avoidAliasing = true;
48 template <class Integral1, class Integral2>
49 Integral2 random(Integral1 low, Integral2 up) {
50 boost::uniform_int<> range(low, up);
54 template <class String>
55 void randomString(String* toFill, unsigned int maxSize = 1000) {
57 toFill->resize(random(0, maxSize));
58 FOR_EACH (i, *toFill) {
59 *i = random('a', 'z');
63 template <class String, class Integral>
64 void Num2String(String& str, Integral n) {
66 std::string tmp = folly::to<std::string>(n);
67 str = String(tmp.begin(), tmp.end());
70 std::list<char> RandomList(unsigned int maxSize) {
71 std::list<char> lst(random(0u, maxSize));
72 std::list<char>::iterator i = lst.begin();
73 for (; i != lst.end(); ++i) {
74 *i = random('a', 'z');
80 ////////////////////////////////////////////////////////////////////////////////
82 ////////////////////////////////////////////////////////////////////////////////
84 template <class String> void clause11_21_4_2_a(String & test) {
85 test.String::~String();
88 template <class String> void clause11_21_4_2_b(String & test) {
90 assert(test2 == test);
92 template <class String> void clause11_21_4_2_c(String & test) {
93 // Test move constructor. There is a more specialized test, see
94 // TEST(FBString, testMoveCtor)
96 String test2(std::move(donor));
97 EXPECT_EQ(test2, test);
98 // Technically not required, but all implementations that actually
99 // support move will move large strings. Make a guess for 128 as the
100 // maximum small string optimization that's reasonable.
101 EXPECT_LE(donor.size(), 128);
103 template <class String> void clause11_21_4_2_d(String & test) {
104 // Copy constructor with position and length
105 const size_t pos = random(0, test.size());
106 String s(test, pos, random(0, 9)
107 ? random(0, (size_t)(test.size() - pos))
108 : String::npos); // test for npos, too, in 10% of the cases
111 template <class String> void clause11_21_4_2_e(String & test) {
112 // Constructor from char*, size_t
114 pos = random(0, test.size()),
115 n = random(0, test.size() - pos);
116 String before(test.data(), test.size());
117 String s(test.c_str() + pos, n);
118 String after(test.data(), test.size());
119 EXPECT_EQ(before, after);
122 template <class String> void clause11_21_4_2_f(String & test) {
123 // Constructor from char*
124 const size_t pos = random(0, test.size());
125 String before(test.data(), test.size());
126 String s(test.c_str() + pos);
127 String after(test.data(), test.size());
128 EXPECT_EQ(before, after);
131 template <class String> void clause11_21_4_2_g(String & test) {
132 // Constructor from size_t, char
133 const size_t n = random(0, test.size());
134 const auto c = test.front();
137 template <class String> void clause11_21_4_2_h(String & test) {
138 // Constructors from various iterator pairs
139 // Constructor from char*, char*
140 String s1(test.begin(), test.end());
142 String s2(test.data(), test.data() + test.size());
144 // Constructor from other iterators
146 for (auto c : test) {
149 String s3(lst.begin(), lst.end());
151 // Constructor from wchar_t iterators
152 std::list<wchar_t> lst1;
153 for (auto c : test) {
156 String s4(lst1.begin(), lst1.end());
158 // Constructor from wchar_t pointers
162 fbstring s5(t, t + 2);;
165 template <class String> void clause11_21_4_2_i(String & test) {
166 // From initializer_list<char>
167 std::initializer_list<typename String::value_type>
168 il = { 'h', 'e', 'l', 'l', 'o' };
172 template <class String> void clause11_21_4_2_j(String & test) {
173 // Assignment from const String&
174 auto size = random(0, 2000);
175 String s(size, '\0');
176 EXPECT_EQ(s.size(), size);
177 FOR_EACH_RANGE (i, 0, s.size()) {
178 s[i] = random('a', 'z');
182 template <class String> void clause11_21_4_2_k(String & test) {
183 // Assignment from String&&
184 auto size = random(0, 2000);
185 String s(size, '\0');
186 EXPECT_EQ(s.size(), size);
187 FOR_EACH_RANGE (i, 0, s.size()) {
188 s[i] = random('a', 'z');
191 if (typeid(String) == typeid(fbstring)) {
192 EXPECT_LE(s.size(), 128);
195 template <class String> void clause11_21_4_2_l(String & test) {
196 // Assignment from char*
197 String s(random(0, 1000), '\0');
199 for (; i != s.size(); ++i) {
200 s[i] = random('a', 'z');
204 template <class String> void clause11_21_4_2_lprime(String & test) {
206 const size_t pos = random(0, test.size());
208 test = String(test.c_str() + pos);
210 test = test.c_str() + pos;
213 template <class String> void clause11_21_4_2_m(String & test) {
214 // Assignment from char
215 using value_type = typename String::value_type;
216 test = random(static_cast<value_type>('a'), static_cast<value_type>('z'));
218 template <class String> void clause11_21_4_2_n(String & test) {
219 // Assignment from initializer_list<char>
220 initializer_list<typename String::value_type>
221 il = { 'h', 'e', 'l', 'l', 'o' };
225 template <class String> void clause11_21_4_3(String & test) {
226 // Iterators. The code below should leave test unchanged
227 EXPECT_EQ(test.size(), test.end() - test.begin());
228 EXPECT_EQ(test.size(), test.rend() - test.rbegin());
229 EXPECT_EQ(test.size(), test.cend() - test.cbegin());
230 EXPECT_EQ(test.size(), test.crend() - test.crbegin());
232 auto s = test.size();
233 test.resize(test.end() - test.begin());
234 EXPECT_EQ(s, test.size());
235 test.resize(test.rend() - test.rbegin());
236 EXPECT_EQ(s, test.size());
239 template <class String> void clause11_21_4_4(String & test) {
240 // exercise capacity, size, max_size
241 EXPECT_EQ(test.size(), test.length());
242 EXPECT_LE(test.size(), test.max_size());
243 EXPECT_LE(test.capacity(), test.max_size());
244 EXPECT_LE(test.size(), test.capacity());
246 // exercise shrink_to_fit. Nonbinding request so we can't really do
247 // much beyond calling it.
249 copy.reserve(copy.capacity() * 3);
250 copy.shrink_to_fit();
251 EXPECT_EQ(copy, test);
254 string empty("empty");
255 string notempty("not empty");
257 test = String(empty.begin(), empty.end());
259 test = String(notempty.begin(), notempty.end());
263 template <class String> void clause11_21_4_5(String & test) {
264 // exercise element access
266 EXPECT_EQ(test[0], test.front());
267 EXPECT_EQ(test[test.size() - 1], test.back());
268 auto const i = random(0, test.size() - 1);
269 EXPECT_EQ(test[i], test.at(i));
274 template <class String> void clause11_21_4_6_1(String & test) {
275 // 21.3.5 modifiers (+=)
277 randomString(&test1);
278 assert(test1.size() == char_traits
279 <typename String::value_type>::length(test1.c_str()));
280 auto len = test.size();
282 EXPECT_EQ(test.size(), test1.size() + len);
283 FOR_EACH_RANGE (i, 0, test1.size()) {
284 EXPECT_EQ(test[len + i], test1[i]);
286 // aliasing modifiers
288 auto dt = test2.data();
289 auto sz = test.c_str();
291 EXPECT_EQ(memcmp(sz, dt, len), 0);
292 String copy(test.data(), test.size());
293 EXPECT_EQ(char_traits
294 <typename String::value_type>::length(test.c_str()), len);
297 EXPECT_EQ(test.size(), 2 * len);
298 EXPECT_EQ(char_traits
299 <typename String::value_type>::length(test.c_str()), 2 * len);
300 FOR_EACH_RANGE (i, 0, len) {
301 EXPECT_EQ(test[i], copy[i]);
302 EXPECT_EQ(test[i], test[len + i]);
305 EXPECT_EQ(char_traits
306 <typename String::value_type>::length(test.c_str()), len);
308 auto const pos = random(0, test.size());
309 EXPECT_EQ(char_traits
310 <typename String::value_type>::length(test.c_str() + pos), len - pos);
312 String addMe(test.c_str() + pos);
313 EXPECT_EQ(addMe.size(), len - pos);
316 test += test.c_str() + pos;
318 EXPECT_EQ(test.size(), 2 * len - pos);
321 test += random('a', 'z');
322 EXPECT_EQ(test.size(), len + 1);
324 initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
328 template <class String> void clause11_21_4_6_2(String & test) {
329 // 21.3.5 modifiers (append, push_back)
332 // Test with a small string first
333 char c = random('a', 'z');
335 EXPECT_EQ(s[s.size() - 1], c);
336 EXPECT_EQ(s.size(), 1);
337 s.resize(s.size() - 1);
339 randomString(&s, maxString);
341 randomString(&s, maxString);
342 test.append(s, random(0, s.size()), random(0, maxString));
343 randomString(&s, maxString);
344 test.append(s.c_str(), random(0, s.size()));
345 randomString(&s, maxString);
346 test.append(s.c_str());
347 test.append(random(0, maxString), random('a', 'z'));
348 std::list<char> lst(RandomList(maxString));
349 test.append(lst.begin(), lst.end());
350 c = random('a', 'z');
352 EXPECT_EQ(test[test.size() - 1], c);
354 initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
358 template <class String> void clause11_21_4_6_3_a(String & test) {
365 test.assign(std::move(s));
366 if (typeid(String) == typeid(fbstring)) {
367 EXPECT_LE(s.size(), 128);
371 template <class String> void clause11_21_4_6_3_b(String & test) {
374 randomString(&s, maxString);
375 test.assign(s, random(0, s.size()), random(0, maxString));
378 template <class String> void clause11_21_4_6_3_c(String & test) {
381 randomString(&s, maxString);
382 test.assign(s.c_str(), random(0, s.size()));
385 template <class String> void clause11_21_4_6_3_d(String & test) {
388 randomString(&s, maxString);
389 test.assign(s.c_str());
392 template <class String> void clause11_21_4_6_3_e(String & test) {
395 randomString(&s, maxString);
396 test.assign(random(0, maxString), random('a', 'z'));
399 template <class String> void clause11_21_4_6_3_f(String & test) {
400 // assign from bidirectional iterator
401 std::list<char> lst(RandomList(maxString));
402 test.assign(lst.begin(), lst.end());
405 template <class String> void clause11_21_4_6_3_g(String & test) {
406 // assign from aliased source
410 template <class String> void clause11_21_4_6_3_h(String & test) {
411 // assign from aliased source
412 test.assign(test, random(0, test.size()), random(0, maxString));
415 template <class String> void clause11_21_4_6_3_i(String & test) {
416 // assign from aliased source
417 test.assign(test.c_str(), random(0, test.size()));
420 template <class String> void clause11_21_4_6_3_j(String & test) {
421 // assign from aliased source
422 test.assign(test.c_str());
425 template <class String> void clause11_21_4_6_3_k(String & test) {
426 // assign from initializer_list
427 initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
431 template <class String> void clause11_21_4_6_4(String & test) {
434 randomString(&s, maxString);
435 test.insert(random(0, test.size()), s);
436 randomString(&s, maxString);
437 test.insert(random(0, test.size()),
438 s, random(0, s.size()),
439 random(0, maxString));
440 randomString(&s, maxString);
441 test.insert(random(0, test.size()),
442 s.c_str(), random(0, s.size()));
443 randomString(&s, maxString);
444 test.insert(random(0, test.size()), s.c_str());
445 test.insert(random(0, test.size()),
446 random(0, maxString), random('a', 'z'));
447 typename String::size_type pos = random(0, test.size());
448 typename String::iterator res =
449 test.insert(test.begin() + pos, random('a', 'z'));
450 EXPECT_EQ(res - test.begin(), pos);
451 std::list<char> lst(RandomList(maxString));
452 pos = random(0, test.size());
453 // Uncomment below to see a bug in gcc
454 /*res = */test.insert(test.begin() + pos, lst.begin(), lst.end());
455 // insert from initializer_list
456 initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
457 pos = random(0, test.size());
458 // Uncomment below to see a bug in gcc
459 /*res = */test.insert(test.begin() + pos, il);
461 // Test with actual input iterators
463 ss << "hello cruel world";
464 auto i = istream_iterator<char>(ss);
465 test.insert(test.begin(), i, istream_iterator<char>());
468 template <class String> void clause11_21_4_6_5(String & test) {
469 // erase and pop_back
471 test.erase(random(0, test.size()), random(0, maxString));
474 // TODO: is erase(end()) allowed?
475 test.erase(test.begin() + random(0, test.size() - 1));
478 auto const i = test.begin() + random(0, test.size());
479 if (i != test.end()) {
480 test.erase(i, i + random(0, size_t(test.end() - i)));
484 // Can't test pop_back with std::string, doesn't support it yet.
489 template <class String> void clause11_21_4_6_6(String & test) {
490 auto pos = random(0, test.size());
492 test.replace(pos, random(0, test.size() - pos),
495 test.replace(pos, random(0, test.size() - pos), test);
497 pos = random(0, test.size());
499 randomString(&s, maxString);
500 test.replace(pos, pos + random(0, test.size() - pos), s);
501 auto pos1 = random(0, test.size());
502 auto pos2 = random(0, test.size());
504 test.replace(pos1, pos1 + random(0, test.size() - pos1),
506 pos2, pos2 + random(0, test.size() - pos2));
508 test.replace(pos1, pos1 + random(0, test.size() - pos1),
509 test, pos2, pos2 + random(0, test.size() - pos2));
511 pos1 = random(0, test.size());
513 randomString(&str, maxString);
514 pos2 = random(0, str.size());
515 test.replace(pos1, pos1 + random(0, test.size() - pos1),
516 str, pos2, pos2 + random(0, str.size() - pos2));
517 pos = random(0, test.size());
519 test.replace(pos, random(0, test.size() - pos),
520 String(test).c_str(), test.size());
522 test.replace(pos, random(0, test.size() - pos),
523 test.c_str(), test.size());
525 pos = random(0, test.size());
526 randomString(&str, maxString);
527 test.replace(pos, pos + random(0, test.size() - pos),
528 str.c_str(), str.size());
529 pos = random(0, test.size());
530 randomString(&str, maxString);
531 test.replace(pos, pos + random(0, test.size() - pos),
533 pos = random(0, test.size());
534 test.replace(pos, random(0, test.size() - pos),
535 random(0, maxString), random('a', 'z'));
536 pos = random(0, test.size());
538 auto newString = String(test);
541 test.begin() + pos + random(0, test.size() - pos),
546 test.begin() + pos + random(0, test.size() - pos),
549 pos = random(0, test.size());
551 auto newString = String(test);
554 test.begin() + pos + random(0, test.size() - pos),
556 test.size() - random(0, test.size()));
560 test.begin() + pos + random(0, test.size() - pos),
562 test.size() - random(0, test.size()));
564 pos = random(0, test.size());
565 auto const n = random(0, test.size() - pos);
566 typename String::iterator b = test.begin();
568 randomString(&str1, maxString);
569 const String & str3 = str1;
570 const typename String::value_type* ss = str3.c_str();
575 pos = random(0, test.size());
578 test.begin() + pos + random(0, test.size() - pos),
579 random(0, maxString), random('a', 'z'));
582 template <class String> void clause11_21_4_6_7(String & test) {
583 std::vector<typename String::value_type>
584 vec(random(0, maxString));
588 test.copy(vec.data(), vec.size(), random(0, test.size()));
591 template <class String> void clause11_21_4_6_8(String & test) {
593 randomString(&s, maxString);
597 template <class String> void clause11_21_4_7_1(String & test) {
598 // 21.3.6 string operations
599 // exercise c_str() and data()
600 assert(test.c_str() == test.data());
601 // exercise get_allocator()
603 randomString(&s, maxString);
604 DCHECK(test.get_allocator() == s.get_allocator());
607 template <class String> void clause11_21_4_7_2_a(String & test) {
608 String str = test.substr(
609 random(0, test.size()),
610 random(0, test.size()));
611 Num2String(test, test.find(str, random(0, test.size())));
614 template <class String> void clause11_21_4_7_2_a1(String & test) {
615 String str = String(test).substr(
616 random(0, test.size()),
617 random(0, test.size()));
618 Num2String(test, test.find(str, random(0, test.size())));
621 template <class String> void clause11_21_4_7_2_a2(String & test) {
622 auto const& cTest = test;
623 String str = cTest.substr(
624 random(0, test.size()),
625 random(0, test.size()));
626 Num2String(test, test.find(str, random(0, test.size())));
629 template <class String> void clause11_21_4_7_2_b(String & test) {
630 auto from = random(0, test.size());
631 auto length = random(0, test.size() - from);
632 String str = test.substr(from, length);
633 Num2String(test, test.find(str.c_str(),
634 random(0, test.size()),
635 random(0, str.size())));
638 template <class String> void clause11_21_4_7_2_b1(String & test) {
639 auto from = random(0, test.size());
640 auto length = random(0, test.size() - from);
641 String str = String(test).substr(from, length);
642 Num2String(test, test.find(str.c_str(),
643 random(0, test.size()),
644 random(0, str.size())));
647 template <class String> void clause11_21_4_7_2_b2(String & test) {
648 auto from = random(0, test.size());
649 auto length = random(0, test.size() - from);
650 const auto& cTest = test;
651 String str = cTest.substr(from, length);
652 Num2String(test, test.find(str.c_str(),
653 random(0, test.size()),
654 random(0, str.size())));
657 template <class String> void clause11_21_4_7_2_c(String & test) {
658 String str = test.substr(
659 random(0, test.size()),
660 random(0, test.size()));
661 Num2String(test, test.find(str.c_str(),
662 random(0, test.size())));
665 template <class String> void clause11_21_4_7_2_c1(String & test) {
666 String str = String(test).substr(
667 random(0, test.size()),
668 random(0, test.size()));
669 Num2String(test, test.find(str.c_str(),
670 random(0, test.size())));
673 template <class String> void clause11_21_4_7_2_c2(String & test) {
674 const auto& cTest = test;
675 String str = cTest.substr(
676 random(0, test.size()),
677 random(0, test.size()));
678 Num2String(test, test.find(str.c_str(),
679 random(0, test.size())));
682 template <class String> void clause11_21_4_7_2_d(String & test) {
683 Num2String(test, test.find(
685 random(0, test.size())));
688 template <class String> void clause11_21_4_7_3_a(String & test) {
689 String str = test.substr(
690 random(0, test.size()),
691 random(0, test.size()));
692 Num2String(test, test.rfind(str, random(0, test.size())));
695 template <class String> void clause11_21_4_7_3_b(String & test) {
696 String str = test.substr(
697 random(0, test.size()),
698 random(0, test.size()));
699 Num2String(test, test.rfind(str.c_str(),
700 random(0, test.size()),
701 random(0, str.size())));
704 template <class String> void clause11_21_4_7_3_c(String & test) {
705 String str = test.substr(
706 random(0, test.size()),
707 random(0, test.size()));
708 Num2String(test, test.rfind(str.c_str(),
709 random(0, test.size())));
712 template <class String> void clause11_21_4_7_3_d(String & test) {
713 Num2String(test, test.rfind(
715 random(0, test.size())));
718 template <class String> void clause11_21_4_7_4_a(String & test) {
720 randomString(&str, maxString);
721 Num2String(test, test.find_first_of(str,
722 random(0, test.size())));
725 template <class String> void clause11_21_4_7_4_b(String & test) {
727 randomString(&str, maxString);
728 Num2String(test, test.find_first_of(str.c_str(),
729 random(0, test.size()),
730 random(0, str.size())));
733 template <class String> void clause11_21_4_7_4_c(String & test) {
735 randomString(&str, maxString);
736 Num2String(test, test.find_first_of(str.c_str(),
737 random(0, test.size())));
740 template <class String> void clause11_21_4_7_4_d(String & test) {
741 Num2String(test, test.find_first_of(
743 random(0, test.size())));
746 template <class String> void clause11_21_4_7_5_a(String & test) {
748 randomString(&str, maxString);
749 Num2String(test, test.find_last_of(str,
750 random(0, test.size())));
753 template <class String> void clause11_21_4_7_5_b(String & test) {
755 randomString(&str, maxString);
756 Num2String(test, test.find_last_of(str.c_str(),
757 random(0, test.size()),
758 random(0, str.size())));
761 template <class String> void clause11_21_4_7_5_c(String & test) {
763 randomString(&str, maxString);
764 Num2String(test, test.find_last_of(str.c_str(),
765 random(0, test.size())));
768 template <class String> void clause11_21_4_7_5_d(String & test) {
769 Num2String(test, test.find_last_of(
771 random(0, test.size())));
774 template <class String> void clause11_21_4_7_6_a(String & test) {
776 randomString(&str, maxString);
777 Num2String(test, test.find_first_not_of(str,
778 random(0, test.size())));
781 template <class String> void clause11_21_4_7_6_b(String & test) {
783 randomString(&str, maxString);
784 Num2String(test, test.find_first_not_of(str.c_str(),
785 random(0, test.size()),
786 random(0, str.size())));
789 template <class String> void clause11_21_4_7_6_c(String & test) {
791 randomString(&str, maxString);
792 Num2String(test, test.find_first_not_of(str.c_str(),
793 random(0, test.size())));
796 template <class String> void clause11_21_4_7_6_d(String & test) {
797 Num2String(test, test.find_first_not_of(
799 random(0, test.size())));
802 template <class String> void clause11_21_4_7_7_a(String & test) {
804 randomString(&str, maxString);
805 Num2String(test, test.find_last_not_of(str,
806 random(0, test.size())));
809 template <class String> void clause11_21_4_7_7_b(String & test) {
811 randomString(&str, maxString);
812 Num2String(test, test.find_last_not_of(str.c_str(),
813 random(0, test.size()),
814 random(0, str.size())));
817 template <class String> void clause11_21_4_7_7_c(String & test) {
819 randomString(&str, maxString);
820 Num2String(test, test.find_last_not_of(str.c_str(),
821 random(0, test.size())));
824 template <class String> void clause11_21_4_7_7_d(String & test) {
825 Num2String(test, test.find_last_not_of(
827 random(0, test.size())));
830 template <class String> void clause11_21_4_7_8(String & test) {
831 test = test.substr(random(0, test.size()), random(0, test.size()));
834 template <class String> void clause11_21_4_7_9_a(String & test) {
836 randomString(&s, maxString);
837 int tristate = test.compare(s);
840 } else if (tristate < 0) {
843 Num2String(test, tristate);
846 template <class String> void clause11_21_4_7_9_b(String & test) {
848 randomString(&s, maxString);
849 int tristate = test.compare(
850 random(0, test.size()),
851 random(0, test.size()),
855 } else if (tristate < 0) {
858 Num2String(test, tristate);
861 template <class String> void clause11_21_4_7_9_c(String & test) {
863 randomString(&str, maxString);
864 int tristate = test.compare(
865 random(0, test.size()),
866 random(0, test.size()),
868 random(0, str.size()),
869 random(0, str.size()));
872 } else if (tristate < 0) {
875 Num2String(test, tristate);
878 template <class String> void clause11_21_4_7_9_d(String & test) {
880 randomString(&s, maxString);
881 int tristate = test.compare(s.c_str());
884 } else if (tristate < 0) {
887 Num2String(test, tristate);
890 template <class String> void clause11_21_4_7_9_e(String & test) {
892 randomString(&str, maxString);
893 int tristate = test.compare(
894 random(0, test.size()),
895 random(0, test.size()),
897 random(0, str.size()));
900 } else if (tristate < 0) {
903 Num2String(test, tristate);
906 template <class String> void clause11_21_4_8_1_a(String & test) {
908 randomString(&s1, maxString);
910 randomString(&s2, maxString);
914 template <class String> void clause11_21_4_8_1_b(String & test) {
916 randomString(&s1, maxString);
918 randomString(&s2, maxString);
919 test = move(s1) + s2;
922 template <class String> void clause11_21_4_8_1_c(String & test) {
924 randomString(&s1, maxString);
926 randomString(&s2, maxString);
927 test = s1 + move(s2);
930 template <class String> void clause11_21_4_8_1_d(String & test) {
932 randomString(&s1, maxString);
934 randomString(&s2, maxString);
935 test = move(s1) + move(s2);
938 template <class String> void clause11_21_4_8_1_e(String & test) {
940 randomString(&s, maxString);
942 randomString(&s1, maxString);
943 test = s.c_str() + s1;
946 template <class String> void clause11_21_4_8_1_f(String & test) {
948 randomString(&s, maxString);
950 randomString(&s1, maxString);
951 test = s.c_str() + move(s1);
954 template <class String> void clause11_21_4_8_1_g(String & test) {
956 randomString(&s, maxString);
957 test = typename String::value_type(random('a', 'z')) + s;
960 template <class String> void clause11_21_4_8_1_h(String & test) {
962 randomString(&s, maxString);
963 test = typename String::value_type(random('a', 'z')) + move(s);
966 template <class String> void clause11_21_4_8_1_i(String & test) {
968 randomString(&s, maxString);
970 randomString(&s1, maxString);
971 test = s + s1.c_str();
974 template <class String> void clause11_21_4_8_1_j(String & test) {
976 randomString(&s, maxString);
978 randomString(&s1, maxString);
979 test = move(s) + s1.c_str();
982 template <class String> void clause11_21_4_8_1_k(String & test) {
984 randomString(&s, maxString);
985 test = s + typename String::value_type(random('a', 'z'));
988 template <class String> void clause11_21_4_8_1_l(String & test) {
990 randomString(&s, maxString);
992 randomString(&s1, maxString);
993 test = move(s) + s1.c_str();
996 // Numbering here is from C++11
997 template <class String> void clause11_21_4_8_9_a(String & test) {
998 basic_stringstream<typename String::value_type> stst(test.c_str());
1006 TEST(FBString, testAllClauses) {
1007 EXPECT_TRUE(1) << "Starting with seed: " << seed;
1010 #if FOLLY_HAVE_WCHAR_SUPPORT
1012 folly::basic_fbstring<wchar_t> wc;
1016 auto l = [&](const char * const clause,
1017 void(*f_string)(std::string&),
1018 void(*f_fbstring)(folly::fbstring&),
1019 void(*f_wfbstring)(folly::basic_fbstring<wchar_t>&)) {
1023 EXPECT_TRUE(1) << "Testing clause " << clause;
1028 #if FOLLY_HAVE_WCHAR_SUPPORT
1029 wr = std::wstring(r.begin(), r.end());
1030 wc = folly::basic_fbstring<wchar_t>(wr.c_str());
1032 auto localSeed = seed + count;
1033 rng = RandomT(localSeed);
1035 rng = RandomT(localSeed);
1038 << "Lengths: " << r.size() << " vs. " << c.size()
1039 << "\nReference: '" << r << "'"
1040 << "\nActual: '" << c.data()[0] << "'";
1041 #if FOLLY_HAVE_WCHAR_SUPPORT
1042 rng = RandomT(localSeed);
1044 int wret = wcslen(wc.c_str());
1045 auto mbv = std::vector<char>(wret + 1);
1046 auto mb = mbv.data();
1047 int ret = wcstombs(mb, wc.c_str(), wret + 1);
1051 const char *mc = c.c_str();
1052 std::string one(mb);
1053 std::string two(mc);
1054 EXPECT_EQ(one, two);
1056 } while (++count % 100 != 0);
1059 #define TEST_CLAUSE(x) \
1061 clause11_##x<std::string>, \
1062 clause11_##x<folly::fbstring>, \
1063 clause11_##x<folly::basic_fbstring<wchar_t>>);
1065 TEST_CLAUSE(21_4_2_a);
1066 TEST_CLAUSE(21_4_2_b);
1067 TEST_CLAUSE(21_4_2_c);
1068 TEST_CLAUSE(21_4_2_d);
1069 TEST_CLAUSE(21_4_2_e);
1070 TEST_CLAUSE(21_4_2_f);
1071 TEST_CLAUSE(21_4_2_g);
1072 TEST_CLAUSE(21_4_2_h);
1073 TEST_CLAUSE(21_4_2_i);
1074 TEST_CLAUSE(21_4_2_j);
1075 TEST_CLAUSE(21_4_2_k);
1076 TEST_CLAUSE(21_4_2_l);
1077 TEST_CLAUSE(21_4_2_lprime);
1078 TEST_CLAUSE(21_4_2_m);
1079 TEST_CLAUSE(21_4_2_n);
1080 TEST_CLAUSE(21_4_3);
1081 TEST_CLAUSE(21_4_4);
1082 TEST_CLAUSE(21_4_5);
1083 TEST_CLAUSE(21_4_6_1);
1084 TEST_CLAUSE(21_4_6_2);
1085 TEST_CLAUSE(21_4_6_3_a);
1086 TEST_CLAUSE(21_4_6_3_b);
1087 TEST_CLAUSE(21_4_6_3_c);
1088 TEST_CLAUSE(21_4_6_3_d);
1089 TEST_CLAUSE(21_4_6_3_e);
1090 TEST_CLAUSE(21_4_6_3_f);
1091 TEST_CLAUSE(21_4_6_3_g);
1092 TEST_CLAUSE(21_4_6_3_h);
1093 TEST_CLAUSE(21_4_6_3_i);
1094 TEST_CLAUSE(21_4_6_3_j);
1095 TEST_CLAUSE(21_4_6_3_k);
1096 TEST_CLAUSE(21_4_6_4);
1097 TEST_CLAUSE(21_4_6_5);
1098 TEST_CLAUSE(21_4_6_6);
1099 TEST_CLAUSE(21_4_6_7);
1100 TEST_CLAUSE(21_4_6_8);
1101 TEST_CLAUSE(21_4_7_1);
1103 TEST_CLAUSE(21_4_7_2_a);
1104 TEST_CLAUSE(21_4_7_2_a1);
1105 TEST_CLAUSE(21_4_7_2_a2);
1106 TEST_CLAUSE(21_4_7_2_b);
1107 TEST_CLAUSE(21_4_7_2_b1);
1108 TEST_CLAUSE(21_4_7_2_b2);
1109 TEST_CLAUSE(21_4_7_2_c);
1110 TEST_CLAUSE(21_4_7_2_c1);
1111 TEST_CLAUSE(21_4_7_2_c2);
1112 TEST_CLAUSE(21_4_7_2_d);
1113 TEST_CLAUSE(21_4_7_3_a);
1114 TEST_CLAUSE(21_4_7_3_b);
1115 TEST_CLAUSE(21_4_7_3_c);
1116 TEST_CLAUSE(21_4_7_3_d);
1117 TEST_CLAUSE(21_4_7_4_a);
1118 TEST_CLAUSE(21_4_7_4_b);
1119 TEST_CLAUSE(21_4_7_4_c);
1120 TEST_CLAUSE(21_4_7_4_d);
1121 TEST_CLAUSE(21_4_7_5_a);
1122 TEST_CLAUSE(21_4_7_5_b);
1123 TEST_CLAUSE(21_4_7_5_c);
1124 TEST_CLAUSE(21_4_7_5_d);
1125 TEST_CLAUSE(21_4_7_6_a);
1126 TEST_CLAUSE(21_4_7_6_b);
1127 TEST_CLAUSE(21_4_7_6_c);
1128 TEST_CLAUSE(21_4_7_6_d);
1129 TEST_CLAUSE(21_4_7_7_a);
1130 TEST_CLAUSE(21_4_7_7_b);
1131 TEST_CLAUSE(21_4_7_7_c);
1132 TEST_CLAUSE(21_4_7_7_d);
1133 TEST_CLAUSE(21_4_7_8);
1134 TEST_CLAUSE(21_4_7_9_a);
1135 TEST_CLAUSE(21_4_7_9_b);
1136 TEST_CLAUSE(21_4_7_9_c);
1137 TEST_CLAUSE(21_4_7_9_d);
1138 TEST_CLAUSE(21_4_7_9_e);
1139 TEST_CLAUSE(21_4_8_1_a);
1140 TEST_CLAUSE(21_4_8_1_b);
1141 TEST_CLAUSE(21_4_8_1_c);
1142 TEST_CLAUSE(21_4_8_1_d);
1143 TEST_CLAUSE(21_4_8_1_e);
1144 TEST_CLAUSE(21_4_8_1_f);
1145 TEST_CLAUSE(21_4_8_1_g);
1146 TEST_CLAUSE(21_4_8_1_h);
1147 TEST_CLAUSE(21_4_8_1_i);
1148 TEST_CLAUSE(21_4_8_1_j);
1149 TEST_CLAUSE(21_4_8_1_k);
1150 TEST_CLAUSE(21_4_8_1_l);
1151 TEST_CLAUSE(21_4_8_9_a);
1154 TEST(FBString, testGetline) {
1156 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan \n\
1157 elit ut urna consectetur in sagittis mi auctor. Nulla facilisi. In nec \n\
1158 dolor leo, vitae imperdiet neque. Donec ut erat mauris, a faucibus \n\
1159 elit. Integer consectetur gravida augue, sit amet mattis mauris auctor \n\
1160 sed. Morbi congue libero eu nunc sodales adipiscing. In lectus nunc, \n\
1161 vulputate a fringilla at, venenatis quis justo. Proin eu velit \n\
1162 nibh. Maecenas vitae tellus eros. Pellentesque habitant morbi \n\
1163 tristique senectus et netus et malesuada fames ac turpis \n\
1164 egestas. Vivamus faucibus feugiat consequat. Donec fermentum neque sit \n\
1165 amet ligula suscipit porta. Phasellus facilisis felis in purus luctus \n\
1166 quis posuere leo tempor. Nam nunc purus, luctus a pharetra ut, \n\
1167 placerat at dui. Donec imperdiet, diam quis convallis pulvinar, dui \n\
1168 est commodo lorem, ut tincidunt diam nibh et nibh. Maecenas nec velit \n\
1169 massa, ut accumsan magna. Donec imperdiet tempor nisi et \n\
1170 laoreet. Phasellus lectus quam, ultricies ut tincidunt in, dignissim \n\
1171 id eros. Mauris vulputate tortor nec neque pellentesque sagittis quis \n\
1172 sed nisl. In diam lacus, lobortis ut posuere nec, ornare id quam.";
1175 boost::split(v, s1, boost::is_any_of("\n"));
1177 istringstream input(s1);
1180 EXPECT_TRUE(!getline(input, line).fail());
1181 EXPECT_EQ(line, *i);
1186 TEST(FBString, testMoveCtor) {
1187 // Move constructor. Make sure we allocate a large string, so the
1188 // small string optimization doesn't kick in.
1189 auto size = random(100, 2000);
1190 fbstring s(size, 'a');
1191 fbstring test = std::move(s);
1192 EXPECT_TRUE(s.empty());
1193 EXPECT_EQ(size, test.size());
1196 TEST(FBString, testMoveAssign) {
1197 // Move constructor. Make sure we allocate a large string, so the
1198 // small string optimization doesn't kick in.
1199 auto size = random(100, 2000);
1200 fbstring s(size, 'a');
1202 test = std::move(s);
1203 EXPECT_TRUE(s.empty());
1204 EXPECT_EQ(size, test.size());
1207 TEST(FBString, testMoveOperatorPlusLhs) {
1208 // Make sure we allocate a large string, so the
1209 // small string optimization doesn't kick in.
1210 auto size1 = random(100, 2000);
1211 auto size2 = random(100, 2000);
1212 fbstring s1(size1, 'a');
1213 fbstring s2(size2, 'b');
1215 test = std::move(s1) + s2;
1216 EXPECT_TRUE(s1.empty());
1217 EXPECT_EQ(size1 + size2, test.size());
1220 TEST(FBString, testMoveOperatorPlusRhs) {
1221 // Make sure we allocate a large string, so the
1222 // small string optimization doesn't kick in.
1223 auto size1 = random(100, 2000);
1224 auto size2 = random(100, 2000);
1225 fbstring s1(size1, 'a');
1226 fbstring s2(size2, 'b');
1228 test = s1 + std::move(s2);
1229 EXPECT_EQ(size1 + size2, test.size());
1232 // The GNU C++ standard library throws an std::logic_error when an std::string
1233 // is constructed with a null pointer. Verify that we mirror this behavior.
1235 // N.B. We behave this way even if the C++ library being used is something
1236 // other than libstdc++. Someday if we deem it important to present
1237 // identical undefined behavior for other platforms, we can re-visit this.
1238 TEST(FBString, testConstructionFromLiteralZero) {
1239 EXPECT_THROW(fbstring s(nullptr), std::logic_error);
1242 TEST(FBString, testFixedBugs) {
1244 fbstring str(1337, 'f');
1248 EXPECT_EQ(str.front(), 'f');
1251 fbstring str(1337, 'f');
1252 for (int i = 0; i < 2; ++i) {
1255 EXPECT_EQ(cp.c_str()[cp.size()], '\0');
1261 fbstring str(1337, 'f');
1266 fbstring str(1337, 'f');
1272 folly::basic_fbstring<wchar_t> s;
1273 EXPECT_EQ(0, s.size());
1276 fbstring str(1337, 'f');
1277 std::swap(str, str);
1278 EXPECT_EQ(1337, str.size());
1280 { // D1012196, --allocator=malloc
1281 fbstring str(128, 'f');
1282 str.clear(); // Empty medium string.
1283 fbstring copy(str); // Medium string of 0 capacity.
1284 copy.push_back('b');
1285 EXPECT_GE(copy.capacity(), 1);
1289 s1.reserve(8); // Trigger the optimized code path.
1290 auto test1 = '\0' + std::move(s1);
1291 EXPECT_EQ(2, test1.size());
1293 fbstring s2(1, '\0');
1295 auto test2 = "a" + std::move(s2);
1296 EXPECT_EQ(2, test2.size());
1299 EXPECT_EQ(fbstring().find(fbstring(), 4), fbstring::npos);
1301 if (usingJEMalloc()) { // D4355440
1302 fbstring str(1337, 'f');
1304 EXPECT_NE(str.capacity(), 3840);
1307 std::atomic<size_t> refCount_;
1311 goodMallocSize(3840) - sizeof(dummyRefCounted) - sizeof(char));
1315 TEST(FBString, findWithNpos) {
1316 fbstring fbstr("localhost:80");
1317 EXPECT_EQ(fbstring::npos, fbstr.find(":", fbstring::npos));
1320 TEST(FBString, testHash) {
1327 std::hash<fbstring> hashfunc;
1328 EXPECT_NE(hashfunc(a), hashfunc(b));
1331 #if FOLLY_HAVE_WCHAR_SUPPORT
1332 TEST(FBString, testHashChar16) {
1333 using u16fbstring = folly::basic_fbstring<char16_t>;
1340 std::hash<u16fbstring> hashfunc;
1341 EXPECT_NE(hashfunc(a), hashfunc(b));
1345 TEST(FBString, testFrontBack) {
1346 fbstring str("hello");
1347 EXPECT_EQ(str.front(), 'h');
1348 EXPECT_EQ(str.back(), 'o');
1350 EXPECT_EQ(str.front(), 'H');
1352 EXPECT_EQ(str.back(), 'O');
1353 EXPECT_EQ(str, "HellO");
1356 TEST(FBString, noexcept) {
1357 EXPECT_TRUE(noexcept(fbstring()));
1359 EXPECT_FALSE(noexcept(fbstring(x)));
1360 EXPECT_TRUE(noexcept(fbstring(std::move(x))));
1362 EXPECT_FALSE(noexcept(y = x));
1363 EXPECT_TRUE(noexcept(y = std::move(x)));
1366 TEST(FBString, iomanip) {
1368 fbstring fbstr("Hello");
1370 ss << setw(6) << fbstr;
1371 EXPECT_EQ(ss.str(), " Hello");
1374 ss << left << setw(6) << fbstr;
1375 EXPECT_EQ(ss.str(), "Hello ");
1378 ss << right << setw(6) << fbstr;
1379 EXPECT_EQ(ss.str(), " Hello");
1382 ss << setw(4) << fbstr;
1383 EXPECT_EQ(ss.str(), "Hello");
1386 ss << setfill('^') << setw(6) << fbstr;
1387 EXPECT_EQ(ss.str(), "^Hello");
1391 TEST(FBString, rvalueIterators) {
1392 // you cannot take &* of a move-iterator, so use that for testing
1393 fbstring s = "base";
1394 fbstring r = "hello";
1395 r.replace(r.begin(), r.end(),
1396 make_move_iterator(s.begin()), make_move_iterator(s.end()));
1397 EXPECT_EQ("base", r);
1399 // The following test is probably not required by the standard.
1400 // i.e. this could be in the realm of undefined behavior.
1401 fbstring b = "123abcXYZ";
1402 auto ait = b.begin() + 3;
1403 auto Xit = b.begin() + 6;
1404 b.replace(ait, b.end(), b.begin(), Xit);
1405 EXPECT_EQ("123123abc", b); // if things go wrong, you'd get "123123123"
1408 TEST(FBString, moveTerminator) {
1409 // The source of a move must remain in a valid state
1410 fbstring s(100, 'x'); // too big to be in-situ
1414 EXPECT_EQ(0, s.size());
1415 EXPECT_EQ('\0', *s.c_str());
1420 * t8968589: Clang 3.7 refused to compile w/ certain constructors (specifically
1421 * those that were "explicit" and had a defaulted parameter, if they were used
1422 * in structs which were default-initialized). Exercise these just to ensure
1425 * In diff D2632953 the old constructor:
1426 * explicit basic_fbstring(const A& a = A()) noexcept;
1428 * was split into these two, as a workaround:
1429 * basic_fbstring() noexcept;
1430 * explicit basic_fbstring(const A& a) noexcept;
1433 struct TestStructDefaultAllocator {
1434 folly::basic_fbstring<char> stringMember;
1438 struct TestStructWithAllocator {
1439 folly::basic_fbstring<char, std::char_traits<char>, A> stringMember;
1442 std::atomic<size_t> allocatorConstructedCount(0);
1443 struct TestStructStringAllocator : std::allocator<char> {
1444 TestStructStringAllocator() {
1445 ++ allocatorConstructedCount;
1451 TEST(FBStringCtorTest, DefaultInitStructDefaultAlloc) {
1452 TestStructDefaultAllocator t1 { };
1453 EXPECT_TRUE(t1.stringMember.empty());
1456 TEST(FBStringCtorTest, DefaultInitStructAlloc) {
1457 EXPECT_EQ(allocatorConstructedCount.load(), 0);
1458 TestStructWithAllocator<TestStructStringAllocator> t2;
1459 EXPECT_TRUE(t2.stringMember.empty());
1460 EXPECT_EQ(allocatorConstructedCount.load(), 1);
1463 TEST(FBStringCtorTest, NullZeroConstruction) {
1466 folly::fbstring f(p, n);
1467 EXPECT_EQ(f.size(), 0);
1470 // Tests for the comparison operators. I use EXPECT_TRUE rather than EXPECT_LE
1471 // because what's under test is the operator rather than the relation between
1474 TEST(FBString, compareToStdString) {
1475 using folly::fbstring;
1476 using namespace std::string_literals;
1481 EXPECT_TRUE(stdA == fbA);
1482 EXPECT_TRUE(fbB == stdB);
1483 EXPECT_TRUE(stdA != fbB);
1484 EXPECT_TRUE(fbA != stdB);
1485 EXPECT_TRUE(stdA < fbB);
1486 EXPECT_TRUE(fbA < stdB);
1487 EXPECT_TRUE(stdB > fbA);
1488 EXPECT_TRUE(fbB > stdA);
1489 EXPECT_TRUE(stdA <= fbB);
1490 EXPECT_TRUE(fbA <= stdB);
1491 EXPECT_TRUE(stdA <= fbA);
1492 EXPECT_TRUE(fbA <= stdA);
1493 EXPECT_TRUE(stdB >= fbA);
1494 EXPECT_TRUE(fbB >= stdA);
1495 EXPECT_TRUE(stdB >= fbB);
1496 EXPECT_TRUE(fbB >= stdB);
1499 TEST(U16FBString, compareToStdU16String) {
1500 using folly::basic_fbstring;
1501 using namespace std::string_literals;
1504 basic_fbstring<char16_t> fbA(u"a");
1505 basic_fbstring<char16_t> fbB(u"b");
1506 EXPECT_TRUE(stdA == fbA);
1507 EXPECT_TRUE(fbB == stdB);
1508 EXPECT_TRUE(stdA != fbB);
1509 EXPECT_TRUE(fbA != stdB);
1510 EXPECT_TRUE(stdA < fbB);
1511 EXPECT_TRUE(fbA < stdB);
1512 EXPECT_TRUE(stdB > fbA);
1513 EXPECT_TRUE(fbB > stdA);
1514 EXPECT_TRUE(stdA <= fbB);
1515 EXPECT_TRUE(fbA <= stdB);
1516 EXPECT_TRUE(stdA <= fbA);
1517 EXPECT_TRUE(fbA <= stdA);
1518 EXPECT_TRUE(stdB >= fbA);
1519 EXPECT_TRUE(fbB >= stdA);
1520 EXPECT_TRUE(stdB >= fbB);
1521 EXPECT_TRUE(fbB >= stdB);
1524 TEST(U32FBString, compareToStdU32String) {
1525 using folly::basic_fbstring;
1526 using namespace std::string_literals;
1529 basic_fbstring<char32_t> fbA(U"a");
1530 basic_fbstring<char32_t> fbB(U"b");
1531 EXPECT_TRUE(stdA == fbA);
1532 EXPECT_TRUE(fbB == stdB);
1533 EXPECT_TRUE(stdA != fbB);
1534 EXPECT_TRUE(fbA != stdB);
1535 EXPECT_TRUE(stdA < fbB);
1536 EXPECT_TRUE(fbA < stdB);
1537 EXPECT_TRUE(stdB > fbA);
1538 EXPECT_TRUE(fbB > stdA);
1539 EXPECT_TRUE(stdA <= fbB);
1540 EXPECT_TRUE(fbA <= stdB);
1541 EXPECT_TRUE(stdA <= fbA);
1542 EXPECT_TRUE(fbA <= stdA);
1543 EXPECT_TRUE(stdB >= fbA);
1544 EXPECT_TRUE(fbB >= stdA);
1545 EXPECT_TRUE(stdB >= fbB);
1546 EXPECT_TRUE(fbB >= stdB);
1549 TEST(WFBString, compareToStdWString) {
1550 using folly::basic_fbstring;
1551 using namespace std::string_literals;
1554 basic_fbstring<wchar_t> fbA(L"a");
1555 basic_fbstring<wchar_t> fbB(L"b");
1556 EXPECT_TRUE(stdA == fbA);
1557 EXPECT_TRUE(fbB == stdB);
1558 EXPECT_TRUE(stdA != fbB);
1559 EXPECT_TRUE(fbA != stdB);
1560 EXPECT_TRUE(stdA < fbB);
1561 EXPECT_TRUE(fbA < stdB);
1562 EXPECT_TRUE(stdB > fbA);
1563 EXPECT_TRUE(fbB > stdA);
1564 EXPECT_TRUE(stdA <= fbB);
1565 EXPECT_TRUE(fbA <= stdB);
1566 EXPECT_TRUE(stdA <= fbA);
1567 EXPECT_TRUE(fbA <= stdA);
1568 EXPECT_TRUE(stdB >= fbA);
1569 EXPECT_TRUE(fbB >= stdA);
1570 EXPECT_TRUE(stdB >= fbB);
1571 EXPECT_TRUE(fbB >= stdB);
1574 // Same again, but with a more challenging input - a common prefix and different
1577 TEST(FBString, compareToStdStringLong) {
1578 using folly::fbstring;
1579 using namespace std::string_literals;
1580 auto stdA = "1234567890a"s;
1581 auto stdB = "1234567890ab"s;
1582 fbstring fbA("1234567890a");
1583 fbstring fbB("1234567890ab");
1584 EXPECT_TRUE(stdA == fbA);
1585 EXPECT_TRUE(fbB == stdB);
1586 EXPECT_TRUE(stdA != fbB);
1587 EXPECT_TRUE(fbA != stdB);
1588 EXPECT_TRUE(stdA < fbB);
1589 EXPECT_TRUE(fbA < stdB);
1590 EXPECT_TRUE(stdB > fbA);
1591 EXPECT_TRUE(fbB > stdA);
1592 EXPECT_TRUE(stdA <= fbB);
1593 EXPECT_TRUE(fbA <= stdB);
1594 EXPECT_TRUE(stdA <= fbA);
1595 EXPECT_TRUE(fbA <= stdA);
1596 EXPECT_TRUE(stdB >= fbA);
1597 EXPECT_TRUE(fbB >= stdA);
1598 EXPECT_TRUE(stdB >= fbB);
1599 EXPECT_TRUE(fbB >= stdB);
1602 TEST(U16FBString, compareToStdU16StringLong) {
1603 using folly::basic_fbstring;
1604 using namespace std::string_literals;
1605 auto stdA = u"1234567890a"s;
1606 auto stdB = u"1234567890ab"s;
1607 basic_fbstring<char16_t> fbA(u"1234567890a");
1608 basic_fbstring<char16_t> fbB(u"1234567890ab");
1609 EXPECT_TRUE(stdA == fbA);
1610 EXPECT_TRUE(fbB == stdB);
1611 EXPECT_TRUE(stdA != fbB);
1612 EXPECT_TRUE(fbA != stdB);
1613 EXPECT_TRUE(stdA < fbB);
1614 EXPECT_TRUE(fbA < stdB);
1615 EXPECT_TRUE(stdB > fbA);
1616 EXPECT_TRUE(fbB > stdA);
1617 EXPECT_TRUE(stdA <= fbB);
1618 EXPECT_TRUE(fbA <= stdB);
1619 EXPECT_TRUE(stdA <= fbA);
1620 EXPECT_TRUE(fbA <= stdA);
1621 EXPECT_TRUE(stdB >= fbA);
1622 EXPECT_TRUE(fbB >= stdA);
1623 EXPECT_TRUE(stdB >= fbB);
1624 EXPECT_TRUE(fbB >= stdB);
1627 #if FOLLY_HAVE_WCHAR_SUPPORT
1628 TEST(U32FBString, compareToStdU32StringLong) {
1629 using folly::basic_fbstring;
1630 using namespace std::string_literals;
1631 auto stdA = U"1234567890a"s;
1632 auto stdB = U"1234567890ab"s;
1633 basic_fbstring<char32_t> fbA(U"1234567890a");
1634 basic_fbstring<char32_t> fbB(U"1234567890ab");
1635 EXPECT_TRUE(stdA == fbA);
1636 EXPECT_TRUE(fbB == stdB);
1637 EXPECT_TRUE(stdA != fbB);
1638 EXPECT_TRUE(fbA != stdB);
1639 EXPECT_TRUE(stdA < fbB);
1640 EXPECT_TRUE(fbA < stdB);
1641 EXPECT_TRUE(stdB > fbA);
1642 EXPECT_TRUE(fbB > stdA);
1643 EXPECT_TRUE(stdA <= fbB);
1644 EXPECT_TRUE(fbA <= stdB);
1645 EXPECT_TRUE(stdA <= fbA);
1646 EXPECT_TRUE(fbA <= stdA);
1647 EXPECT_TRUE(stdB >= fbA);
1648 EXPECT_TRUE(fbB >= stdA);
1649 EXPECT_TRUE(stdB >= fbB);
1650 EXPECT_TRUE(fbB >= stdB);
1653 TEST(WFBString, compareToStdWStringLong) {
1654 using folly::basic_fbstring;
1655 using namespace std::string_literals;
1656 auto stdA = L"1234567890a"s;
1657 auto stdB = L"1234567890ab"s;
1658 basic_fbstring<wchar_t> fbA(L"1234567890a");
1659 basic_fbstring<wchar_t> fbB(L"1234567890ab");
1660 EXPECT_TRUE(stdA == fbA);
1661 EXPECT_TRUE(fbB == stdB);
1662 EXPECT_TRUE(stdA != fbB);
1663 EXPECT_TRUE(fbA != stdB);
1664 EXPECT_TRUE(stdA < fbB);
1665 EXPECT_TRUE(fbA < stdB);
1666 EXPECT_TRUE(stdB > fbA);
1667 EXPECT_TRUE(fbB > stdA);
1668 EXPECT_TRUE(stdA <= fbB);
1669 EXPECT_TRUE(fbA <= stdB);
1670 EXPECT_TRUE(stdA <= fbA);
1671 EXPECT_TRUE(fbA <= stdA);
1672 EXPECT_TRUE(stdB >= fbA);
1673 EXPECT_TRUE(fbB >= stdA);
1674 EXPECT_TRUE(stdB >= fbB);
1675 EXPECT_TRUE(fbB >= stdB);