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/Foreach.h>
32 #include <folly/Portability.h>
33 #include <folly/Random.h>
34 #include <folly/Conv.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) lst.push_back(c);
147 String s3(lst.begin(), lst.end());
149 // Constructor from wchar_t iterators
150 std::list<wchar_t> lst1;
151 for (auto c : test) lst1.push_back(c);
152 String s4(lst1.begin(), lst1.end());
154 // Constructor from wchar_t pointers
158 fbstring s5(t, t + 2);;
161 template <class String> void clause11_21_4_2_i(String & test) {
162 // From initializer_list<char>
163 std::initializer_list<typename String::value_type>
164 il = { 'h', 'e', 'l', 'l', 'o' };
168 template <class String> void clause11_21_4_2_j(String & test) {
169 // Assignment from const String&
170 auto size = random(0, 2000);
171 String s(size, '\0');
172 EXPECT_EQ(s.size(), size);
173 FOR_EACH_RANGE (i, 0, s.size()) {
174 s[i] = random('a', 'z');
178 template <class String> void clause11_21_4_2_k(String & test) {
179 // Assignment from String&&
180 auto size = random(0, 2000);
181 String s(size, '\0');
182 EXPECT_EQ(s.size(), size);
183 FOR_EACH_RANGE (i, 0, s.size()) {
184 s[i] = random('a', 'z');
187 if (typeid(String) == typeid(fbstring)) {
188 EXPECT_LE(s.size(), 128);
191 template <class String> void clause11_21_4_2_l(String & test) {
192 // Assignment from char*
193 String s(random(0, 1000), '\0');
195 for (; i != s.size(); ++i) {
196 s[i] = random('a', 'z');
200 template <class String> void clause11_21_4_2_lprime(String & test) {
202 const size_t pos = random(0, test.size());
204 test = String(test.c_str() + pos);
206 test = test.c_str() + pos;
209 template <class String> void clause11_21_4_2_m(String & test) {
210 // Assignment from char
211 using value_type = typename String::value_type;
212 test = random(static_cast<value_type>('a'), static_cast<value_type>('z'));
214 template <class String> void clause11_21_4_2_n(String & test) {
215 // Assignment from initializer_list<char>
216 initializer_list<typename String::value_type>
217 il = { 'h', 'e', 'l', 'l', 'o' };
221 template <class String> void clause11_21_4_3(String & test) {
222 // Iterators. The code below should leave test unchanged
223 EXPECT_EQ(test.size(), test.end() - test.begin());
224 EXPECT_EQ(test.size(), test.rend() - test.rbegin());
225 EXPECT_EQ(test.size(), test.cend() - test.cbegin());
226 EXPECT_EQ(test.size(), test.crend() - test.crbegin());
228 auto s = test.size();
229 test.resize(test.end() - test.begin());
230 EXPECT_EQ(s, test.size());
231 test.resize(test.rend() - test.rbegin());
232 EXPECT_EQ(s, test.size());
235 template <class String> void clause11_21_4_4(String & test) {
236 // exercise capacity, size, max_size
237 EXPECT_EQ(test.size(), test.length());
238 EXPECT_LE(test.size(), test.max_size());
239 EXPECT_LE(test.capacity(), test.max_size());
240 EXPECT_LE(test.size(), test.capacity());
242 // exercise shrink_to_fit. Nonbinding request so we can't really do
243 // much beyond calling it.
245 copy.reserve(copy.capacity() * 3);
246 copy.shrink_to_fit();
247 EXPECT_EQ(copy, test);
250 string empty("empty");
251 string notempty("not empty");
252 if (test.empty()) test = String(empty.begin(), empty.end());
253 else test = String(notempty.begin(), notempty.end());
256 template <class String> void clause11_21_4_5(String & test) {
257 // exercise element access
259 EXPECT_EQ(test[0], test.front());
260 EXPECT_EQ(test[test.size() - 1], test.back());
261 auto const i = random(0, test.size() - 1);
262 EXPECT_EQ(test[i], test.at(i));
267 template <class String> void clause11_21_4_6_1(String & test) {
268 // 21.3.5 modifiers (+=)
270 randomString(&test1);
271 assert(test1.size() == char_traits
272 <typename String::value_type>::length(test1.c_str()));
273 auto len = test.size();
275 EXPECT_EQ(test.size(), test1.size() + len);
276 FOR_EACH_RANGE (i, 0, test1.size()) {
277 EXPECT_EQ(test[len + i], test1[i]);
279 // aliasing modifiers
281 auto dt = test2.data();
282 auto sz = test.c_str();
284 EXPECT_EQ(memcmp(sz, dt, len), 0);
285 String copy(test.data(), test.size());
286 EXPECT_EQ(char_traits
287 <typename String::value_type>::length(test.c_str()), len);
290 EXPECT_EQ(test.size(), 2 * len);
291 EXPECT_EQ(char_traits
292 <typename String::value_type>::length(test.c_str()), 2 * len);
293 FOR_EACH_RANGE (i, 0, len) {
294 EXPECT_EQ(test[i], copy[i]);
295 EXPECT_EQ(test[i], test[len + i]);
298 EXPECT_EQ(char_traits
299 <typename String::value_type>::length(test.c_str()), len);
301 auto const pos = random(0, test.size());
302 EXPECT_EQ(char_traits
303 <typename String::value_type>::length(test.c_str() + pos), len - pos);
305 String addMe(test.c_str() + pos);
306 EXPECT_EQ(addMe.size(), len - pos);
309 test += test.c_str() + pos;
311 EXPECT_EQ(test.size(), 2 * len - pos);
314 test += random('a', 'z');
315 EXPECT_EQ(test.size(), len + 1);
317 initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
321 template <class String> void clause11_21_4_6_2(String & test) {
322 // 21.3.5 modifiers (append, push_back)
325 // Test with a small string first
326 char c = random('a', 'z');
328 EXPECT_EQ(s[s.size() - 1], c);
329 EXPECT_EQ(s.size(), 1);
330 s.resize(s.size() - 1);
332 randomString(&s, maxString);
334 randomString(&s, maxString);
335 test.append(s, random(0, s.size()), random(0, maxString));
336 randomString(&s, maxString);
337 test.append(s.c_str(), random(0, s.size()));
338 randomString(&s, maxString);
339 test.append(s.c_str());
340 test.append(random(0, maxString), random('a', 'z'));
341 std::list<char> lst(RandomList(maxString));
342 test.append(lst.begin(), lst.end());
343 c = random('a', 'z');
345 EXPECT_EQ(test[test.size() - 1], c);
347 initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
351 template <class String> void clause11_21_4_6_3_a(String & test) {
358 test.assign(std::move(s));
359 if (typeid(String) == typeid(fbstring)) {
360 EXPECT_LE(s.size(), 128);
364 template <class String> void clause11_21_4_6_3_b(String & test) {
367 randomString(&s, maxString);
368 test.assign(s, random(0, s.size()), random(0, maxString));
371 template <class String> void clause11_21_4_6_3_c(String & test) {
374 randomString(&s, maxString);
375 test.assign(s.c_str(), random(0, s.size()));
378 template <class String> void clause11_21_4_6_3_d(String & test) {
381 randomString(&s, maxString);
382 test.assign(s.c_str());
385 template <class String> void clause11_21_4_6_3_e(String & test) {
388 randomString(&s, maxString);
389 test.assign(random(0, maxString), random('a', 'z'));
392 template <class String> void clause11_21_4_6_3_f(String & test) {
393 // assign from bidirectional iterator
394 std::list<char> lst(RandomList(maxString));
395 test.assign(lst.begin(), lst.end());
398 template <class String> void clause11_21_4_6_3_g(String & test) {
399 // assign from aliased source
403 template <class String> void clause11_21_4_6_3_h(String & test) {
404 // assign from aliased source
405 test.assign(test, random(0, test.size()), random(0, maxString));
408 template <class String> void clause11_21_4_6_3_i(String & test) {
409 // assign from aliased source
410 test.assign(test.c_str(), random(0, test.size()));
413 template <class String> void clause11_21_4_6_3_j(String & test) {
414 // assign from aliased source
415 test.assign(test.c_str());
418 template <class String> void clause11_21_4_6_3_k(String & test) {
419 // assign from initializer_list
420 initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
424 template <class String> void clause11_21_4_6_4(String & test) {
427 randomString(&s, maxString);
428 test.insert(random(0, test.size()), s);
429 randomString(&s, maxString);
430 test.insert(random(0, test.size()),
431 s, random(0, s.size()),
432 random(0, maxString));
433 randomString(&s, maxString);
434 test.insert(random(0, test.size()),
435 s.c_str(), random(0, s.size()));
436 randomString(&s, maxString);
437 test.insert(random(0, test.size()), s.c_str());
438 test.insert(random(0, test.size()),
439 random(0, maxString), random('a', 'z'));
440 typename String::size_type pos = random(0, test.size());
441 typename String::iterator res =
442 test.insert(test.begin() + pos, random('a', 'z'));
443 EXPECT_EQ(res - test.begin(), pos);
444 std::list<char> lst(RandomList(maxString));
445 pos = random(0, test.size());
446 // Uncomment below to see a bug in gcc
447 /*res = */test.insert(test.begin() + pos, lst.begin(), lst.end());
448 // insert from initializer_list
449 initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
450 pos = random(0, test.size());
451 // Uncomment below to see a bug in gcc
452 /*res = */test.insert(test.begin() + pos, il);
454 // Test with actual input iterators
456 ss << "hello cruel world";
457 auto i = istream_iterator<char>(ss);
458 test.insert(test.begin(), i, istream_iterator<char>());
461 template <class String> void clause11_21_4_6_5(String & test) {
462 // erase and pop_back
464 test.erase(random(0, test.size()), random(0, maxString));
467 // TODO: is erase(end()) allowed?
468 test.erase(test.begin() + random(0, test.size() - 1));
471 auto const i = test.begin() + random(0, test.size());
472 if (i != test.end()) {
473 test.erase(i, i + random(0, size_t(test.end() - i)));
477 // Can't test pop_back with std::string, doesn't support it yet.
482 template <class String> void clause11_21_4_6_6(String & test) {
483 auto pos = random(0, test.size());
485 test.replace(pos, random(0, test.size() - pos),
488 test.replace(pos, random(0, test.size() - pos), test);
490 pos = random(0, test.size());
492 randomString(&s, maxString);
493 test.replace(pos, pos + random(0, test.size() - pos), s);
494 auto pos1 = random(0, test.size());
495 auto pos2 = random(0, test.size());
497 test.replace(pos1, pos1 + random(0, test.size() - pos1),
499 pos2, pos2 + random(0, test.size() - pos2));
501 test.replace(pos1, pos1 + random(0, test.size() - pos1),
502 test, pos2, pos2 + random(0, test.size() - pos2));
504 pos1 = random(0, test.size());
506 randomString(&str, maxString);
507 pos2 = random(0, str.size());
508 test.replace(pos1, pos1 + random(0, test.size() - pos1),
509 str, pos2, pos2 + random(0, str.size() - pos2));
510 pos = random(0, test.size());
512 test.replace(pos, random(0, test.size() - pos),
513 String(test).c_str(), test.size());
515 test.replace(pos, random(0, test.size() - pos),
516 test.c_str(), test.size());
518 pos = random(0, test.size());
519 randomString(&str, maxString);
520 test.replace(pos, pos + random(0, test.size() - pos),
521 str.c_str(), str.size());
522 pos = random(0, test.size());
523 randomString(&str, maxString);
524 test.replace(pos, pos + random(0, test.size() - pos),
526 pos = random(0, test.size());
527 test.replace(pos, random(0, test.size() - pos),
528 random(0, maxString), random('a', 'z'));
529 pos = random(0, test.size());
531 auto newString = String(test);
534 test.begin() + pos + random(0, test.size() - pos),
539 test.begin() + pos + random(0, test.size() - pos),
542 pos = random(0, test.size());
544 auto newString = String(test);
547 test.begin() + pos + random(0, test.size() - pos),
549 test.size() - random(0, test.size()));
553 test.begin() + pos + random(0, test.size() - pos),
555 test.size() - random(0, test.size()));
557 pos = random(0, test.size());
558 auto const n = random(0, test.size() - pos);
559 typename String::iterator b = test.begin();
561 randomString(&str1, maxString);
562 const String & str3 = str1;
563 const typename String::value_type* ss = str3.c_str();
568 pos = random(0, test.size());
571 test.begin() + pos + random(0, test.size() - pos),
572 random(0, maxString), random('a', 'z'));
575 template <class String> void clause11_21_4_6_7(String & test) {
576 std::vector<typename String::value_type>
577 vec(random(0, maxString));
581 test.copy(vec.data(), vec.size(), random(0, test.size()));
584 template <class String> void clause11_21_4_6_8(String & test) {
586 randomString(&s, maxString);
590 template <class String> void clause11_21_4_7_1(String & test) {
591 // 21.3.6 string operations
592 // exercise c_str() and data()
593 assert(test.c_str() == test.data());
594 // exercise get_allocator()
596 randomString(&s, maxString);
597 DCHECK(test.get_allocator() == s.get_allocator());
600 template <class String> void clause11_21_4_7_2_a(String & test) {
601 String str = test.substr(
602 random(0, test.size()),
603 random(0, test.size()));
604 Num2String(test, test.find(str, random(0, test.size())));
607 template <class String> void clause11_21_4_7_2_a1(String & test) {
608 String str = String(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_a2(String & test) {
615 auto const& cTest = test;
616 String str = cTest.substr(
617 random(0, test.size()),
618 random(0, test.size()));
619 Num2String(test, test.find(str, random(0, test.size())));
622 template <class String> void clause11_21_4_7_2_b(String & test) {
623 auto from = random(0, test.size());
624 auto length = random(0, test.size() - from);
625 String str = test.substr(from, length);
626 Num2String(test, test.find(str.c_str(),
627 random(0, test.size()),
628 random(0, str.size())));
631 template <class String> void clause11_21_4_7_2_b1(String & test) {
632 auto from = random(0, test.size());
633 auto length = random(0, test.size() - from);
634 String str = String(test).substr(from, length);
635 Num2String(test, test.find(str.c_str(),
636 random(0, test.size()),
637 random(0, str.size())));
640 template <class String> void clause11_21_4_7_2_b2(String & test) {
641 auto from = random(0, test.size());
642 auto length = random(0, test.size() - from);
643 const auto& cTest = test;
644 String str = cTest.substr(from, length);
645 Num2String(test, test.find(str.c_str(),
646 random(0, test.size()),
647 random(0, str.size())));
650 template <class String> void clause11_21_4_7_2_c(String & test) {
651 String str = test.substr(
652 random(0, test.size()),
653 random(0, test.size()));
654 Num2String(test, test.find(str.c_str(),
655 random(0, test.size())));
658 template <class String> void clause11_21_4_7_2_c1(String & test) {
659 String str = String(test).substr(
660 random(0, test.size()),
661 random(0, test.size()));
662 Num2String(test, test.find(str.c_str(),
663 random(0, test.size())));
666 template <class String> void clause11_21_4_7_2_c2(String & test) {
667 const auto& cTest = test;
668 String str = cTest.substr(
669 random(0, test.size()),
670 random(0, test.size()));
671 Num2String(test, test.find(str.c_str(),
672 random(0, test.size())));
675 template <class String> void clause11_21_4_7_2_d(String & test) {
676 Num2String(test, test.find(
678 random(0, test.size())));
681 template <class String> void clause11_21_4_7_3_a(String & test) {
682 String str = test.substr(
683 random(0, test.size()),
684 random(0, test.size()));
685 Num2String(test, test.rfind(str, random(0, test.size())));
688 template <class String> void clause11_21_4_7_3_b(String & test) {
689 String str = test.substr(
690 random(0, test.size()),
691 random(0, test.size()));
692 Num2String(test, test.rfind(str.c_str(),
693 random(0, test.size()),
694 random(0, str.size())));
697 template <class String> void clause11_21_4_7_3_c(String & test) {
698 String str = test.substr(
699 random(0, test.size()),
700 random(0, test.size()));
701 Num2String(test, test.rfind(str.c_str(),
702 random(0, test.size())));
705 template <class String> void clause11_21_4_7_3_d(String & test) {
706 Num2String(test, test.rfind(
708 random(0, test.size())));
711 template <class String> void clause11_21_4_7_4_a(String & test) {
713 randomString(&str, maxString);
714 Num2String(test, test.find_first_of(str,
715 random(0, test.size())));
718 template <class String> void clause11_21_4_7_4_b(String & test) {
720 randomString(&str, maxString);
721 Num2String(test, test.find_first_of(str.c_str(),
722 random(0, test.size()),
723 random(0, str.size())));
726 template <class String> void clause11_21_4_7_4_c(String & test) {
728 randomString(&str, maxString);
729 Num2String(test, test.find_first_of(str.c_str(),
730 random(0, test.size())));
733 template <class String> void clause11_21_4_7_4_d(String & test) {
734 Num2String(test, test.find_first_of(
736 random(0, test.size())));
739 template <class String> void clause11_21_4_7_5_a(String & test) {
741 randomString(&str, maxString);
742 Num2String(test, test.find_last_of(str,
743 random(0, test.size())));
746 template <class String> void clause11_21_4_7_5_b(String & test) {
748 randomString(&str, maxString);
749 Num2String(test, test.find_last_of(str.c_str(),
750 random(0, test.size()),
751 random(0, str.size())));
754 template <class String> void clause11_21_4_7_5_c(String & test) {
756 randomString(&str, maxString);
757 Num2String(test, test.find_last_of(str.c_str(),
758 random(0, test.size())));
761 template <class String> void clause11_21_4_7_5_d(String & test) {
762 Num2String(test, test.find_last_of(
764 random(0, test.size())));
767 template <class String> void clause11_21_4_7_6_a(String & test) {
769 randomString(&str, maxString);
770 Num2String(test, test.find_first_not_of(str,
771 random(0, test.size())));
774 template <class String> void clause11_21_4_7_6_b(String & test) {
776 randomString(&str, maxString);
777 Num2String(test, test.find_first_not_of(str.c_str(),
778 random(0, test.size()),
779 random(0, str.size())));
782 template <class String> void clause11_21_4_7_6_c(String & test) {
784 randomString(&str, maxString);
785 Num2String(test, test.find_first_not_of(str.c_str(),
786 random(0, test.size())));
789 template <class String> void clause11_21_4_7_6_d(String & test) {
790 Num2String(test, test.find_first_not_of(
792 random(0, test.size())));
795 template <class String> void clause11_21_4_7_7_a(String & test) {
797 randomString(&str, maxString);
798 Num2String(test, test.find_last_not_of(str,
799 random(0, test.size())));
802 template <class String> void clause11_21_4_7_7_b(String & test) {
804 randomString(&str, maxString);
805 Num2String(test, test.find_last_not_of(str.c_str(),
806 random(0, test.size()),
807 random(0, str.size())));
810 template <class String> void clause11_21_4_7_7_c(String & test) {
812 randomString(&str, maxString);
813 Num2String(test, test.find_last_not_of(str.c_str(),
814 random(0, test.size())));
817 template <class String> void clause11_21_4_7_7_d(String & test) {
818 Num2String(test, test.find_last_not_of(
820 random(0, test.size())));
823 template <class String> void clause11_21_4_7_8(String & test) {
824 test = test.substr(random(0, test.size()), random(0, test.size()));
827 template <class String> void clause11_21_4_7_9_a(String & test) {
829 randomString(&s, maxString);
830 int tristate = test.compare(s);
831 if (tristate > 0) tristate = 1;
832 else if (tristate < 0) tristate = 2;
833 Num2String(test, tristate);
836 template <class String> void clause11_21_4_7_9_b(String & test) {
838 randomString(&s, maxString);
839 int tristate = test.compare(
840 random(0, test.size()),
841 random(0, test.size()),
843 if (tristate > 0) tristate = 1;
844 else if (tristate < 0) tristate = 2;
845 Num2String(test, tristate);
848 template <class String> void clause11_21_4_7_9_c(String & test) {
850 randomString(&str, maxString);
851 int tristate = test.compare(
852 random(0, test.size()),
853 random(0, test.size()),
855 random(0, str.size()),
856 random(0, str.size()));
857 if (tristate > 0) tristate = 1;
858 else if (tristate < 0) tristate = 2;
859 Num2String(test, tristate);
862 template <class String> void clause11_21_4_7_9_d(String & test) {
864 randomString(&s, maxString);
865 int tristate = test.compare(s.c_str());
866 if (tristate > 0) tristate = 1;
867 else if (tristate < 0) tristate = 2;
868 Num2String(test, tristate);
871 template <class String> void clause11_21_4_7_9_e(String & test) {
873 randomString(&str, maxString);
874 int tristate = test.compare(
875 random(0, test.size()),
876 random(0, test.size()),
878 random(0, str.size()));
879 if (tristate > 0) tristate = 1;
880 else if (tristate < 0) tristate = 2;
881 Num2String(test, tristate);
884 template <class String> void clause11_21_4_8_1_a(String & test) {
886 randomString(&s1, maxString);
888 randomString(&s2, maxString);
892 template <class String> void clause11_21_4_8_1_b(String & test) {
894 randomString(&s1, maxString);
896 randomString(&s2, maxString);
897 test = move(s1) + s2;
900 template <class String> void clause11_21_4_8_1_c(String & test) {
902 randomString(&s1, maxString);
904 randomString(&s2, maxString);
905 test = s1 + move(s2);
908 template <class String> void clause11_21_4_8_1_d(String & test) {
910 randomString(&s1, maxString);
912 randomString(&s2, maxString);
913 test = move(s1) + move(s2);
916 template <class String> void clause11_21_4_8_1_e(String & test) {
918 randomString(&s, maxString);
920 randomString(&s1, maxString);
921 test = s.c_str() + s1;
924 template <class String> void clause11_21_4_8_1_f(String & test) {
926 randomString(&s, maxString);
928 randomString(&s1, maxString);
929 test = s.c_str() + move(s1);
932 template <class String> void clause11_21_4_8_1_g(String & test) {
934 randomString(&s, maxString);
935 test = typename String::value_type(random('a', 'z')) + s;
938 template <class String> void clause11_21_4_8_1_h(String & test) {
940 randomString(&s, maxString);
941 test = typename String::value_type(random('a', 'z')) + move(s);
944 template <class String> void clause11_21_4_8_1_i(String & test) {
946 randomString(&s, maxString);
948 randomString(&s1, maxString);
949 test = s + s1.c_str();
952 template <class String> void clause11_21_4_8_1_j(String & test) {
954 randomString(&s, maxString);
956 randomString(&s1, maxString);
957 test = move(s) + s1.c_str();
960 template <class String> void clause11_21_4_8_1_k(String & test) {
962 randomString(&s, maxString);
963 test = s + typename String::value_type(random('a', 'z'));
966 template <class String> void clause11_21_4_8_1_l(String & test) {
968 randomString(&s, maxString);
970 randomString(&s1, maxString);
971 test = move(s) + s1.c_str();
974 // Numbering here is from C++11
975 template <class String> void clause11_21_4_8_9_a(String & test) {
976 basic_stringstream<typename String::value_type> stst(test.c_str());
984 TEST(FBString, testAllClauses) {
985 EXPECT_TRUE(1) << "Starting with seed: " << seed;
988 #if FOLLY_HAVE_WCHAR_SUPPORT
990 folly::basic_fbstring<wchar_t> wc;
994 auto l = [&](const char * const clause,
995 void(*f_string)(std::string&),
996 void(*f_fbstring)(folly::fbstring&),
997 void(*f_wfbstring)(folly::basic_fbstring<wchar_t>&)) {
999 if (1) {} else EXPECT_TRUE(1) << "Testing clause " << clause;
1003 #if FOLLY_HAVE_WCHAR_SUPPORT
1004 wr = std::wstring(r.begin(), r.end());
1005 wc = folly::basic_fbstring<wchar_t>(wr.c_str());
1007 auto localSeed = seed + count;
1008 rng = RandomT(localSeed);
1010 rng = RandomT(localSeed);
1013 << "Lengths: " << r.size() << " vs. " << c.size()
1014 << "\nReference: '" << r << "'"
1015 << "\nActual: '" << c.data()[0] << "'";
1016 #if FOLLY_HAVE_WCHAR_SUPPORT
1017 rng = RandomT(localSeed);
1019 int wret = wcslen(wc.c_str());
1020 auto mbv = std::vector<char>(wret + 1);
1021 auto mb = mbv.data();
1022 int ret = wcstombs(mb, wc.c_str(), wret + 1);
1023 if (ret == wret) mb[wret] = '\0';
1024 const char *mc = c.c_str();
1025 std::string one(mb);
1026 std::string two(mc);
1027 EXPECT_EQ(one, two);
1029 } while (++count % 100 != 0);
1032 #define TEST_CLAUSE(x) \
1034 clause11_##x<std::string>, \
1035 clause11_##x<folly::fbstring>, \
1036 clause11_##x<folly::basic_fbstring<wchar_t>>);
1038 TEST_CLAUSE(21_4_2_a);
1039 TEST_CLAUSE(21_4_2_b);
1040 TEST_CLAUSE(21_4_2_c);
1041 TEST_CLAUSE(21_4_2_d);
1042 TEST_CLAUSE(21_4_2_e);
1043 TEST_CLAUSE(21_4_2_f);
1044 TEST_CLAUSE(21_4_2_g);
1045 TEST_CLAUSE(21_4_2_h);
1046 TEST_CLAUSE(21_4_2_i);
1047 TEST_CLAUSE(21_4_2_j);
1048 TEST_CLAUSE(21_4_2_k);
1049 TEST_CLAUSE(21_4_2_l);
1050 TEST_CLAUSE(21_4_2_lprime);
1051 TEST_CLAUSE(21_4_2_m);
1052 TEST_CLAUSE(21_4_2_n);
1053 TEST_CLAUSE(21_4_3);
1054 TEST_CLAUSE(21_4_4);
1055 TEST_CLAUSE(21_4_5);
1056 TEST_CLAUSE(21_4_6_1);
1057 TEST_CLAUSE(21_4_6_2);
1058 TEST_CLAUSE(21_4_6_3_a);
1059 TEST_CLAUSE(21_4_6_3_b);
1060 TEST_CLAUSE(21_4_6_3_c);
1061 TEST_CLAUSE(21_4_6_3_d);
1062 TEST_CLAUSE(21_4_6_3_e);
1063 TEST_CLAUSE(21_4_6_3_f);
1064 TEST_CLAUSE(21_4_6_3_g);
1065 TEST_CLAUSE(21_4_6_3_h);
1066 TEST_CLAUSE(21_4_6_3_i);
1067 TEST_CLAUSE(21_4_6_3_j);
1068 TEST_CLAUSE(21_4_6_3_k);
1069 TEST_CLAUSE(21_4_6_4);
1070 TEST_CLAUSE(21_4_6_5);
1071 TEST_CLAUSE(21_4_6_6);
1072 TEST_CLAUSE(21_4_6_7);
1073 TEST_CLAUSE(21_4_6_8);
1074 TEST_CLAUSE(21_4_7_1);
1076 TEST_CLAUSE(21_4_7_2_a);
1077 TEST_CLAUSE(21_4_7_2_a1);
1078 TEST_CLAUSE(21_4_7_2_a2);
1079 TEST_CLAUSE(21_4_7_2_b);
1080 TEST_CLAUSE(21_4_7_2_b1);
1081 TEST_CLAUSE(21_4_7_2_b2);
1082 TEST_CLAUSE(21_4_7_2_c);
1083 TEST_CLAUSE(21_4_7_2_c1);
1084 TEST_CLAUSE(21_4_7_2_c2);
1085 TEST_CLAUSE(21_4_7_2_d);
1086 TEST_CLAUSE(21_4_7_3_a);
1087 TEST_CLAUSE(21_4_7_3_b);
1088 TEST_CLAUSE(21_4_7_3_c);
1089 TEST_CLAUSE(21_4_7_3_d);
1090 TEST_CLAUSE(21_4_7_4_a);
1091 TEST_CLAUSE(21_4_7_4_b);
1092 TEST_CLAUSE(21_4_7_4_c);
1093 TEST_CLAUSE(21_4_7_4_d);
1094 TEST_CLAUSE(21_4_7_5_a);
1095 TEST_CLAUSE(21_4_7_5_b);
1096 TEST_CLAUSE(21_4_7_5_c);
1097 TEST_CLAUSE(21_4_7_5_d);
1098 TEST_CLAUSE(21_4_7_6_a);
1099 TEST_CLAUSE(21_4_7_6_b);
1100 TEST_CLAUSE(21_4_7_6_c);
1101 TEST_CLAUSE(21_4_7_6_d);
1102 TEST_CLAUSE(21_4_7_7_a);
1103 TEST_CLAUSE(21_4_7_7_b);
1104 TEST_CLAUSE(21_4_7_7_c);
1105 TEST_CLAUSE(21_4_7_7_d);
1106 TEST_CLAUSE(21_4_7_8);
1107 TEST_CLAUSE(21_4_7_9_a);
1108 TEST_CLAUSE(21_4_7_9_b);
1109 TEST_CLAUSE(21_4_7_9_c);
1110 TEST_CLAUSE(21_4_7_9_d);
1111 TEST_CLAUSE(21_4_7_9_e);
1112 TEST_CLAUSE(21_4_8_1_a);
1113 TEST_CLAUSE(21_4_8_1_b);
1114 TEST_CLAUSE(21_4_8_1_c);
1115 TEST_CLAUSE(21_4_8_1_d);
1116 TEST_CLAUSE(21_4_8_1_e);
1117 TEST_CLAUSE(21_4_8_1_f);
1118 TEST_CLAUSE(21_4_8_1_g);
1119 TEST_CLAUSE(21_4_8_1_h);
1120 TEST_CLAUSE(21_4_8_1_i);
1121 TEST_CLAUSE(21_4_8_1_j);
1122 TEST_CLAUSE(21_4_8_1_k);
1123 TEST_CLAUSE(21_4_8_1_l);
1124 TEST_CLAUSE(21_4_8_9_a);
1127 TEST(FBString, testGetline) {
1129 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan \n\
1130 elit ut urna consectetur in sagittis mi auctor. Nulla facilisi. In nec \n\
1131 dolor leo, vitae imperdiet neque. Donec ut erat mauris, a faucibus \n\
1132 elit. Integer consectetur gravida augue, sit amet mattis mauris auctor \n\
1133 sed. Morbi congue libero eu nunc sodales adipiscing. In lectus nunc, \n\
1134 vulputate a fringilla at, venenatis quis justo. Proin eu velit \n\
1135 nibh. Maecenas vitae tellus eros. Pellentesque habitant morbi \n\
1136 tristique senectus et netus et malesuada fames ac turpis \n\
1137 egestas. Vivamus faucibus feugiat consequat. Donec fermentum neque sit \n\
1138 amet ligula suscipit porta. Phasellus facilisis felis in purus luctus \n\
1139 quis posuere leo tempor. Nam nunc purus, luctus a pharetra ut, \n\
1140 placerat at dui. Donec imperdiet, diam quis convallis pulvinar, dui \n\
1141 est commodo lorem, ut tincidunt diam nibh et nibh. Maecenas nec velit \n\
1142 massa, ut accumsan magna. Donec imperdiet tempor nisi et \n\
1143 laoreet. Phasellus lectus quam, ultricies ut tincidunt in, dignissim \n\
1144 id eros. Mauris vulputate tortor nec neque pellentesque sagittis quis \n\
1145 sed nisl. In diam lacus, lobortis ut posuere nec, ornare id quam.";
1148 boost::split(v, s1, boost::is_any_of("\n"));
1150 istringstream input(s1);
1153 EXPECT_TRUE(!getline(input, line).fail());
1154 EXPECT_EQ(line, *i);
1159 TEST(FBString, testMoveCtor) {
1160 // Move constructor. Make sure we allocate a large string, so the
1161 // small string optimization doesn't kick in.
1162 auto size = random(100, 2000);
1163 fbstring s(size, 'a');
1164 fbstring test = std::move(s);
1165 EXPECT_TRUE(s.empty());
1166 EXPECT_EQ(size, test.size());
1169 TEST(FBString, testMoveAssign) {
1170 // Move constructor. Make sure we allocate a large string, so the
1171 // small string optimization doesn't kick in.
1172 auto size = random(100, 2000);
1173 fbstring s(size, 'a');
1175 test = std::move(s);
1176 EXPECT_TRUE(s.empty());
1177 EXPECT_EQ(size, test.size());
1180 TEST(FBString, testMoveOperatorPlusLhs) {
1181 // Make sure we allocate a large string, so the
1182 // small string optimization doesn't kick in.
1183 auto size1 = random(100, 2000);
1184 auto size2 = random(100, 2000);
1185 fbstring s1(size1, 'a');
1186 fbstring s2(size2, 'b');
1188 test = std::move(s1) + s2;
1189 EXPECT_TRUE(s1.empty());
1190 EXPECT_EQ(size1 + size2, test.size());
1193 TEST(FBString, testMoveOperatorPlusRhs) {
1194 // Make sure we allocate a large string, so the
1195 // small string optimization doesn't kick in.
1196 auto size1 = random(100, 2000);
1197 auto size2 = random(100, 2000);
1198 fbstring s1(size1, 'a');
1199 fbstring s2(size2, 'b');
1201 test = s1 + std::move(s2);
1202 EXPECT_EQ(size1 + size2, test.size());
1205 // The GNU C++ standard library throws an std::logic_error when an std::string
1206 // is constructed with a null pointer. Verify that we mirror this behavior.
1208 // N.B. We behave this way even if the C++ library being used is something
1209 // other than libstdc++. Someday if we deem it important to present
1210 // identical undefined behavior for other platforms, we can re-visit this.
1211 TEST(FBString, testConstructionFromLiteralZero) {
1212 EXPECT_THROW(fbstring s(0), std::logic_error);
1215 TEST(FBString, testFixedBugs) {
1217 fbstring str(1337, 'f');
1221 EXPECT_EQ(str.front(), 'f');
1224 fbstring str(1337, 'f');
1225 for (int i = 0; i < 2; ++i) {
1228 EXPECT_EQ(cp.c_str()[cp.size()], '\0');
1234 fbstring str(1337, 'f');
1239 fbstring str(1337, 'f');
1245 folly::basic_fbstring<wchar_t> s;
1246 EXPECT_EQ(0, s.size());
1249 fbstring str(1337, 'f');
1250 std::swap(str, str);
1251 EXPECT_EQ(1337, str.size());
1253 { // D1012196, --allocator=malloc
1254 fbstring str(128, 'f');
1255 str.clear(); // Empty medium string.
1256 fbstring copy(str); // Medium string of 0 capacity.
1257 copy.push_back('b');
1258 EXPECT_GE(copy.capacity(), 1);
1262 s1.reserve(8); // Trigger the optimized code path.
1263 auto test1 = '\0' + std::move(s1);
1264 EXPECT_EQ(2, test1.size());
1266 fbstring s2(1, '\0');
1268 auto test2 = "a" + std::move(s2);
1269 EXPECT_EQ(2, test2.size());
1272 EXPECT_EQ(fbstring().find(fbstring(), 4), fbstring::npos);
1274 if (usingJEMalloc()) { // D4355440
1275 fbstring str(1337, 'f');
1277 EXPECT_NE(str.capacity(), 3840);
1280 std::atomic<size_t> refCount_;
1284 goodMallocSize(3840) - sizeof(dummyRefCounted) - sizeof(char));
1288 TEST(FBString, findWithNpos) {
1289 fbstring fbstr("localhost:80");
1290 EXPECT_EQ(fbstring::npos, fbstr.find(":", fbstring::npos));
1293 TEST(FBString, testHash) {
1300 std::hash<fbstring> hashfunc;
1301 EXPECT_NE(hashfunc(a), hashfunc(b));
1304 #if FOLLY_HAVE_WCHAR_SUPPORT
1305 TEST(FBString, testHashChar16) {
1306 using u16fbstring = folly::basic_fbstring<char16_t>;
1313 std::hash<u16fbstring> hashfunc;
1314 EXPECT_NE(hashfunc(a), hashfunc(b));
1318 TEST(FBString, testFrontBack) {
1319 fbstring str("hello");
1320 EXPECT_EQ(str.front(), 'h');
1321 EXPECT_EQ(str.back(), 'o');
1323 EXPECT_EQ(str.front(), 'H');
1325 EXPECT_EQ(str.back(), 'O');
1326 EXPECT_EQ(str, "HellO");
1329 TEST(FBString, noexcept) {
1330 EXPECT_TRUE(noexcept(fbstring()));
1332 EXPECT_FALSE(noexcept(fbstring(x)));
1333 EXPECT_TRUE(noexcept(fbstring(std::move(x))));
1335 EXPECT_FALSE(noexcept(y = x));
1336 EXPECT_TRUE(noexcept(y = std::move(x)));
1339 TEST(FBString, iomanip) {
1341 fbstring fbstr("Hello");
1343 ss << setw(6) << fbstr;
1344 EXPECT_EQ(ss.str(), " Hello");
1347 ss << left << setw(6) << fbstr;
1348 EXPECT_EQ(ss.str(), "Hello ");
1351 ss << right << setw(6) << fbstr;
1352 EXPECT_EQ(ss.str(), " Hello");
1355 ss << setw(4) << fbstr;
1356 EXPECT_EQ(ss.str(), "Hello");
1359 ss << setfill('^') << setw(6) << fbstr;
1360 EXPECT_EQ(ss.str(), "^Hello");
1364 TEST(FBString, rvalueIterators) {
1365 // you cannot take &* of a move-iterator, so use that for testing
1366 fbstring s = "base";
1367 fbstring r = "hello";
1368 r.replace(r.begin(), r.end(),
1369 make_move_iterator(s.begin()), make_move_iterator(s.end()));
1370 EXPECT_EQ("base", r);
1372 // The following test is probably not required by the standard.
1373 // i.e. this could be in the realm of undefined behavior.
1374 fbstring b = "123abcXYZ";
1375 auto ait = b.begin() + 3;
1376 auto Xit = b.begin() + 6;
1377 b.replace(ait, b.end(), b.begin(), Xit);
1378 EXPECT_EQ("123123abc", b); // if things go wrong, you'd get "123123123"
1381 TEST(FBString, moveTerminator) {
1382 // The source of a move must remain in a valid state
1383 fbstring s(100, 'x'); // too big to be in-situ
1387 EXPECT_EQ(0, s.size());
1388 EXPECT_EQ('\0', *s.c_str());
1393 * t8968589: Clang 3.7 refused to compile w/ certain constructors (specifically
1394 * those that were "explicit" and had a defaulted parameter, if they were used
1395 * in structs which were default-initialized). Exercise these just to ensure
1398 * In diff D2632953 the old constructor:
1399 * explicit basic_fbstring(const A& a = A()) noexcept;
1401 * was split into these two, as a workaround:
1402 * basic_fbstring() noexcept;
1403 * explicit basic_fbstring(const A& a) noexcept;
1406 struct TestStructDefaultAllocator {
1407 folly::basic_fbstring<char> stringMember;
1411 struct TestStructWithAllocator {
1412 folly::basic_fbstring<char, std::char_traits<char>, A> stringMember;
1415 std::atomic<size_t> allocatorConstructedCount(0);
1416 struct TestStructStringAllocator : std::allocator<char> {
1417 TestStructStringAllocator() {
1418 ++ allocatorConstructedCount;
1424 TEST(FBStringCtorTest, DefaultInitStructDefaultAlloc) {
1425 TestStructDefaultAllocator t1 { };
1426 EXPECT_TRUE(t1.stringMember.empty());
1429 TEST(FBStringCtorTest, DefaultInitStructAlloc) {
1430 EXPECT_EQ(allocatorConstructedCount.load(), 0);
1431 TestStructWithAllocator<TestStructStringAllocator> t2;
1432 EXPECT_TRUE(t2.stringMember.empty());
1433 EXPECT_EQ(allocatorConstructedCount.load(), 1);
1436 TEST(FBStringCtorTest, NullZeroConstruction) {
1439 folly::fbstring f(p, n);
1440 EXPECT_EQ(f.size(), 0);
1443 // Tests for the comparison operators. I use EXPECT_TRUE rather than EXPECT_LE
1444 // because what's under test is the operator rather than the relation between
1447 TEST(FBString, compareToStdString) {
1448 using folly::fbstring;
1449 using namespace std::string_literals;
1454 EXPECT_TRUE(stdA == fbA);
1455 EXPECT_TRUE(fbB == stdB);
1456 EXPECT_TRUE(stdA != fbB);
1457 EXPECT_TRUE(fbA != stdB);
1458 EXPECT_TRUE(stdA < fbB);
1459 EXPECT_TRUE(fbA < stdB);
1460 EXPECT_TRUE(stdB > fbA);
1461 EXPECT_TRUE(fbB > stdA);
1462 EXPECT_TRUE(stdA <= fbB);
1463 EXPECT_TRUE(fbA <= stdB);
1464 EXPECT_TRUE(stdA <= fbA);
1465 EXPECT_TRUE(fbA <= stdA);
1466 EXPECT_TRUE(stdB >= fbA);
1467 EXPECT_TRUE(fbB >= stdA);
1468 EXPECT_TRUE(stdB >= fbB);
1469 EXPECT_TRUE(fbB >= stdB);
1472 TEST(U16FBString, compareToStdU16String) {
1473 using folly::basic_fbstring;
1474 using namespace std::string_literals;
1477 basic_fbstring<char16_t> fbA(u"a");
1478 basic_fbstring<char16_t> fbB(u"b");
1479 EXPECT_TRUE(stdA == fbA);
1480 EXPECT_TRUE(fbB == stdB);
1481 EXPECT_TRUE(stdA != fbB);
1482 EXPECT_TRUE(fbA != stdB);
1483 EXPECT_TRUE(stdA < fbB);
1484 EXPECT_TRUE(fbA < stdB);
1485 EXPECT_TRUE(stdB > fbA);
1486 EXPECT_TRUE(fbB > stdA);
1487 EXPECT_TRUE(stdA <= fbB);
1488 EXPECT_TRUE(fbA <= stdB);
1489 EXPECT_TRUE(stdA <= fbA);
1490 EXPECT_TRUE(fbA <= stdA);
1491 EXPECT_TRUE(stdB >= fbA);
1492 EXPECT_TRUE(fbB >= stdA);
1493 EXPECT_TRUE(stdB >= fbB);
1494 EXPECT_TRUE(fbB >= stdB);
1497 TEST(U32FBString, compareToStdU32String) {
1498 using folly::basic_fbstring;
1499 using namespace std::string_literals;
1502 basic_fbstring<char32_t> fbA(U"a");
1503 basic_fbstring<char32_t> fbB(U"b");
1504 EXPECT_TRUE(stdA == fbA);
1505 EXPECT_TRUE(fbB == stdB);
1506 EXPECT_TRUE(stdA != fbB);
1507 EXPECT_TRUE(fbA != stdB);
1508 EXPECT_TRUE(stdA < fbB);
1509 EXPECT_TRUE(fbA < stdB);
1510 EXPECT_TRUE(stdB > fbA);
1511 EXPECT_TRUE(fbB > stdA);
1512 EXPECT_TRUE(stdA <= fbB);
1513 EXPECT_TRUE(fbA <= stdB);
1514 EXPECT_TRUE(stdA <= fbA);
1515 EXPECT_TRUE(fbA <= stdA);
1516 EXPECT_TRUE(stdB >= fbA);
1517 EXPECT_TRUE(fbB >= stdA);
1518 EXPECT_TRUE(stdB >= fbB);
1519 EXPECT_TRUE(fbB >= stdB);
1522 TEST(WFBString, compareToStdWString) {
1523 using folly::basic_fbstring;
1524 using namespace std::string_literals;
1527 basic_fbstring<wchar_t> fbA(L"a");
1528 basic_fbstring<wchar_t> fbB(L"b");
1529 EXPECT_TRUE(stdA == fbA);
1530 EXPECT_TRUE(fbB == stdB);
1531 EXPECT_TRUE(stdA != fbB);
1532 EXPECT_TRUE(fbA != stdB);
1533 EXPECT_TRUE(stdA < fbB);
1534 EXPECT_TRUE(fbA < stdB);
1535 EXPECT_TRUE(stdB > fbA);
1536 EXPECT_TRUE(fbB > stdA);
1537 EXPECT_TRUE(stdA <= fbB);
1538 EXPECT_TRUE(fbA <= stdB);
1539 EXPECT_TRUE(stdA <= fbA);
1540 EXPECT_TRUE(fbA <= stdA);
1541 EXPECT_TRUE(stdB >= fbA);
1542 EXPECT_TRUE(fbB >= stdA);
1543 EXPECT_TRUE(stdB >= fbB);
1544 EXPECT_TRUE(fbB >= stdB);
1547 // Same again, but with a more challenging input - a common prefix and different
1550 TEST(FBString, compareToStdStringLong) {
1551 using folly::fbstring;
1552 using namespace std::string_literals;
1553 auto stdA = "1234567890a"s;
1554 auto stdB = "1234567890ab"s;
1555 fbstring fbA("1234567890a");
1556 fbstring fbB("1234567890ab");
1557 EXPECT_TRUE(stdA == fbA);
1558 EXPECT_TRUE(fbB == stdB);
1559 EXPECT_TRUE(stdA != fbB);
1560 EXPECT_TRUE(fbA != stdB);
1561 EXPECT_TRUE(stdA < fbB);
1562 EXPECT_TRUE(fbA < stdB);
1563 EXPECT_TRUE(stdB > fbA);
1564 EXPECT_TRUE(fbB > stdA);
1565 EXPECT_TRUE(stdA <= fbB);
1566 EXPECT_TRUE(fbA <= stdB);
1567 EXPECT_TRUE(stdA <= fbA);
1568 EXPECT_TRUE(fbA <= stdA);
1569 EXPECT_TRUE(stdB >= fbA);
1570 EXPECT_TRUE(fbB >= stdA);
1571 EXPECT_TRUE(stdB >= fbB);
1572 EXPECT_TRUE(fbB >= stdB);
1575 TEST(U16FBString, compareToStdU16StringLong) {
1576 using folly::basic_fbstring;
1577 using namespace std::string_literals;
1578 auto stdA = u"1234567890a"s;
1579 auto stdB = u"1234567890ab"s;
1580 basic_fbstring<char16_t> fbA(u"1234567890a");
1581 basic_fbstring<char16_t> fbB(u"1234567890ab");
1582 EXPECT_TRUE(stdA == fbA);
1583 EXPECT_TRUE(fbB == stdB);
1584 EXPECT_TRUE(stdA != fbB);
1585 EXPECT_TRUE(fbA != stdB);
1586 EXPECT_TRUE(stdA < fbB);
1587 EXPECT_TRUE(fbA < stdB);
1588 EXPECT_TRUE(stdB > fbA);
1589 EXPECT_TRUE(fbB > stdA);
1590 EXPECT_TRUE(stdA <= fbB);
1591 EXPECT_TRUE(fbA <= stdB);
1592 EXPECT_TRUE(stdA <= fbA);
1593 EXPECT_TRUE(fbA <= stdA);
1594 EXPECT_TRUE(stdB >= fbA);
1595 EXPECT_TRUE(fbB >= stdA);
1596 EXPECT_TRUE(stdB >= fbB);
1597 EXPECT_TRUE(fbB >= stdB);
1600 #if FOLLY_HAVE_WCHAR_SUPPORT
1601 TEST(U32FBString, compareToStdU32StringLong) {
1602 using folly::basic_fbstring;
1603 using namespace std::string_literals;
1604 auto stdA = U"1234567890a"s;
1605 auto stdB = U"1234567890ab"s;
1606 basic_fbstring<char32_t> fbA(U"1234567890a");
1607 basic_fbstring<char32_t> fbB(U"1234567890ab");
1608 EXPECT_TRUE(stdA == fbA);
1609 EXPECT_TRUE(fbB == stdB);
1610 EXPECT_TRUE(stdA != fbB);
1611 EXPECT_TRUE(fbA != stdB);
1612 EXPECT_TRUE(stdA < fbB);
1613 EXPECT_TRUE(fbA < stdB);
1614 EXPECT_TRUE(stdB > fbA);
1615 EXPECT_TRUE(fbB > stdA);
1616 EXPECT_TRUE(stdA <= fbB);
1617 EXPECT_TRUE(fbA <= stdB);
1618 EXPECT_TRUE(stdA <= fbA);
1619 EXPECT_TRUE(fbA <= stdA);
1620 EXPECT_TRUE(stdB >= fbA);
1621 EXPECT_TRUE(fbB >= stdA);
1622 EXPECT_TRUE(stdB >= fbB);
1623 EXPECT_TRUE(fbB >= stdB);
1626 TEST(WFBString, compareToStdWStringLong) {
1627 using folly::basic_fbstring;
1628 using namespace std::string_literals;
1629 auto stdA = L"1234567890a"s;
1630 auto stdB = L"1234567890ab"s;
1631 basic_fbstring<wchar_t> fbA(L"1234567890a");
1632 basic_fbstring<wchar_t> fbB(L"1234567890ab");
1633 EXPECT_TRUE(stdA == fbA);
1634 EXPECT_TRUE(fbB == stdB);
1635 EXPECT_TRUE(stdA != fbB);
1636 EXPECT_TRUE(fbA != stdB);
1637 EXPECT_TRUE(stdA < fbB);
1638 EXPECT_TRUE(fbA < stdB);
1639 EXPECT_TRUE(stdB > fbA);
1640 EXPECT_TRUE(fbB > stdA);
1641 EXPECT_TRUE(stdA <= fbB);
1642 EXPECT_TRUE(fbA <= stdB);
1643 EXPECT_TRUE(stdA <= fbA);
1644 EXPECT_TRUE(fbA <= stdA);
1645 EXPECT_TRUE(stdB >= fbA);
1646 EXPECT_TRUE(fbB >= stdA);
1647 EXPECT_TRUE(stdB >= fbB);
1648 EXPECT_TRUE(fbB >= stdB);