2 * Copyright 2012 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"
24 #include <boost/algorithm/string.hpp>
25 #include <boost/random.hpp>
26 #include <gtest/gtest.h>
28 #include <gflags/gflags.h>
30 #include "folly/Foreach.h"
31 #include "folly/Random.h"
32 #include "folly/Benchmark.h"
35 using namespace folly;
37 static const int seed = folly::randomNumberSeed();
38 typedef boost::mt19937 RandomT;
39 static RandomT rng(seed);
40 static const size_t maxString = 100;
41 static const bool avoidAliasing = true;
43 template <class Integral1, class Integral2>
44 Integral2 random(Integral1 low, Integral2 up) {
45 boost::uniform_int<> range(low, up);
49 template <class String>
50 void randomString(String* toFill, unsigned int maxSize = 1000) {
52 toFill->resize(random(0, maxSize));
53 FOR_EACH (i, *toFill) {
54 *i = random('a', 'z');
58 template <class String, class Integral>
59 void Num2String(String& str, Integral n) {
61 sprintf(&str[0], "%lu", static_cast<unsigned long>(n));
62 str.resize(strlen(str.c_str()));
65 std::list<char> RandomList(unsigned int maxSize) {
66 std::list<char> lst(random(0u, maxSize));
67 std::list<char>::iterator i = lst.begin();
68 for (; i != lst.end(); ++i) {
69 *i = random('a', 'z');
74 // void preventOptimization(void * p) {
75 // return folly::preventOptimization((int)(long) p);
78 ////////////////////////////////////////////////////////////////////////////////
80 ////////////////////////////////////////////////////////////////////////////////
82 template <class String> void clause_21_3_1_a(String & test) {
83 test.String::~String();
86 template <class String> void clause_21_3_1_b(String & test) {
88 const size_t pos = random(0, test.size());
89 String s(test, pos, random(0, (size_t)(test.size() - pos)));
92 template <class String> void clause_21_3_1_c(String & test) {
93 // Constructor from char*, size_t
95 pos = random(0, test.size()),
96 n = random(0, test.size() - pos);
97 std::string before(test.data(), test.size());
98 String s(test.c_str() + pos, n);
99 std::string after(test.data(), test.size());
100 EXPECT_EQ(before, after);
102 // Constructor from char*, char*
103 String s1(test.begin(), test.end());
105 String s2(test.data(), test.data() + test.size());
108 // Constructor from iterators
110 for (auto c : test) lst.push_back(c);
111 String s3(lst.begin(), lst.end());
114 // Constructor from wchar_t iterators
115 std::list<wchar_t> lst1;
116 for (auto c : test) lst1.push_back(c);
117 String s4(lst1.begin(), lst1.end());
120 // Constructor from wchar_t pointers
124 String s5(t, t + 2);;
129 template <class String> void clause_21_3_1_d(String & test) {
131 auto size = random(0, 2000);
132 String s(size, '\0');
133 EXPECT_EQ(s.size(), size);
134 FOR_EACH_RANGE (i, 0, s.size()) {
135 s[i] = random('a', 'z');
139 template <class String> void clause_21_3_1_e(String & test) {
140 // Assignment from char*
141 String s(random(0, 1000), '\0');
143 for (; i != s.size(); ++i) {
144 s[i] = random('a', 'z');
148 template <class String> void clause_21_3_1_f(String & test) {
150 const size_t pos = random(0, test.size());
152 test = String(test.c_str() + pos);
154 test = test.c_str() + pos;
157 template <class String> void clause_21_3_1_g(String & test) {
158 // Assignment from char
159 test = random('a', 'z');
162 template <class String> void clause_21_3_2(String & test) {
163 // Iterators. The code below should leave test unchanged
164 EXPECT_EQ(test.size(), test.end() - test.begin());
165 EXPECT_EQ(test.size(), test.rend() - test.rbegin());
167 auto s = test.size();
168 test.resize(test.end() - test.begin());
169 EXPECT_EQ(s, test.size());
170 test.resize(test.rend() - test.rbegin());
171 EXPECT_EQ(s, test.size());
174 template <class String> void clause_21_3_3(String & test) {
175 // exercise capacity, size, max_size
176 EXPECT_EQ(test.size(), test.length());
177 EXPECT_LE(test.size(), test.max_size());
178 EXPECT_LE(test.capacity(), test.max_size());
179 EXPECT_LE(test.size(), test.capacity());
181 if (test.empty()) test = "empty";
182 else test = "not empty";
185 template <class String> void clause_21_3_4(String & test) {
186 // exercise element access 21.3.4
188 auto const i = random(0, test.size() - 1);
189 EXPECT_EQ(test[i], test.at(i));
194 template <class String> void clause_21_3_5_a(String & test) {
195 // 21.3.5 modifiers (+=)
197 randomString(&test1);
198 assert(test1.size() == strlen(test1.c_str()));
199 auto len = test.size();
201 EXPECT_EQ(test.size(), test1.size() + len);
202 FOR_EACH_RANGE (i, 0, test1.size()) {
203 EXPECT_EQ(test[len + i], test1[i]);
205 // aliasing modifiers
207 auto dt = test2.data();
208 auto sz = test.c_str();
210 EXPECT_EQ(memcmp(sz, dt, len), 0);
211 String copy(test.data(), test.size());
212 EXPECT_EQ(strlen(test.c_str()), len);
215 EXPECT_EQ(test.size(), 2 * len);
216 EXPECT_EQ(strlen(test.c_str()), 2 * len);
217 FOR_EACH_RANGE (i, 0, len) {
218 EXPECT_EQ(test[i], copy[i]);
219 EXPECT_EQ(test[i], test[len + i]);
222 EXPECT_EQ(strlen(test.c_str()), len);
224 auto const pos = random(0, test.size());
225 EXPECT_EQ(strlen(test.c_str() + pos), len - pos);
227 String addMe(test.c_str() + pos);
228 EXPECT_EQ(addMe.size(), len - pos);
231 test += test.c_str() + pos;
233 EXPECT_EQ(test.size(), 2 * len - pos);
236 test += random('a', 'z');
237 EXPECT_EQ(test.size(), len + 1);
240 template <class String> void clause_21_3_5_b(String & test) {
241 // 21.3.5 modifiers (append, push_back)
244 // Test with a small string first
245 char c = random('a', 'z');
247 EXPECT_EQ(s[s.size() - 1], c);
248 EXPECT_EQ(s.size(), 1);
249 s.resize(s.size() - 1);
251 randomString(&s, maxString);
253 randomString(&s, maxString);
254 test.append(s, random(0, s.size()), random(0, maxString));
255 randomString(&s, maxString);
256 test.append(s.c_str(), random(0, s.size()));
257 randomString(&s, maxString);
258 test.append(s.c_str());
259 test.append(random(0, maxString), random('a', 'z'));
260 std::list<char> lst(RandomList(maxString));
261 test.append(lst.begin(), lst.end());
262 c = random('a', 'z');
264 EXPECT_EQ(test[test.size() - 1], c);
267 template <class String> void clause_21_3_5_c(String & test) {
274 template <class String> void clause_21_3_5_d(String & test) {
277 randomString(&s, maxString);
278 test.assign(s, random(0, s.size()), random(0, maxString));
281 template <class String> void clause_21_3_5_e(String & test) {
284 randomString(&s, maxString);
285 test.assign(s.c_str(), random(0, s.size()));
288 template <class String> void clause_21_3_5_f(String & test) {
291 randomString(&s, maxString);
292 test.assign(s.c_str());
295 template <class String> void clause_21_3_5_g(String & test) {
298 randomString(&s, maxString);
299 test.assign(random(0, maxString), random('a', 'z'));
302 template <class String> void clause_21_3_5_h(String & test) {
303 // assign from bidirectional iterator
304 std::list<char> lst(RandomList(maxString));
305 test.assign(lst.begin(), lst.end());
308 template <class String> void clause_21_3_5_i(String & test) {
309 // assign from aliased source
313 template <class String> void clause_21_3_5_j(String & test) {
314 // assign from aliased source
315 test.assign(test, random(0, test.size()), random(0, maxString));
318 template <class String> void clause_21_3_5_k(String & test) {
319 // assign from aliased source
320 test.assign(test.c_str(), random(0, test.size()));
323 template <class String> void clause_21_3_5_l(String & test) {
324 // assign from aliased source
325 test.assign(test.c_str());
328 template <class String> void clause_21_3_5_m(String & test) {
331 randomString(&s, maxString);
332 test.insert(random(0, test.size()), s);
333 randomString(&s, maxString);
334 test.insert(random(0, test.size()),
335 s, random(0, s.size()),
336 random(0, maxString));
337 randomString(&s, maxString);
338 test.insert(random(0, test.size()),
339 s.c_str(), random(0, s.size()));
340 randomString(&s, maxString);
341 test.insert(random(0, test.size()), s.c_str());
342 test.insert(random(0, test.size()),
343 random(0, maxString), random('a', 'z'));
344 test.insert(test.begin() + random(0, test.size()),
346 std::list<char> lst(RandomList(maxString));
347 test.insert(test.begin() + random(0, test.size()),
348 lst.begin(), lst.end());
351 template <class String> void clause_21_3_5_n(String & test) {
354 test.erase(random(0, test.size()), random(0, maxString));
357 // TODO: is erase(end()) allowed?
358 test.erase(test.begin() + random(0, test.size() - 1));
361 auto const i = test.begin() + random(0, test.size());
362 if (i != test.end()) {
363 test.erase(i, i + random(0, size_t(test.end() - i)));
368 template <class String> void clause_21_3_5_o(String & test) {
369 auto pos = random(0, test.size());
371 test.replace(pos, random(0, test.size() - pos),
374 test.replace(pos, random(0, test.size() - pos), test);
376 pos = random(0, test.size());
378 randomString(&s, maxString);
379 test.replace(pos, pos + random(0, test.size() - pos), s);
380 auto pos1 = random(0, test.size());
381 auto pos2 = random(0, test.size());
383 test.replace(pos1, pos1 + random(0, test.size() - pos1),
385 pos2, pos2 + random(0, test.size() - pos2));
387 test.replace(pos1, pos1 + random(0, test.size() - pos1),
388 test, pos2, pos2 + random(0, test.size() - pos2));
390 pos1 = random(0, test.size());
392 randomString(&str, maxString);
393 pos2 = random(0, str.size());
394 test.replace(pos1, pos1 + random(0, test.size() - pos1),
395 str, pos2, pos2 + random(0, str.size() - pos2));
396 pos = random(0, test.size());
398 test.replace(pos, random(0, test.size() - pos),
399 String(test).c_str(), test.size());
401 test.replace(pos, random(0, test.size() - pos),
402 test.c_str(), test.size());
404 pos = random(0, test.size());
405 randomString(&str, maxString);
406 test.replace(pos, pos + random(0, test.size() - pos),
407 str.c_str(), str.size());
408 pos = random(0, test.size());
409 randomString(&str, maxString);
410 test.replace(pos, pos + random(0, test.size() - pos),
412 pos = random(0, test.size());
413 test.replace(pos, random(0, test.size() - pos),
414 random(0, maxString), random('a', 'z'));
415 pos = random(0, test.size());
419 test.begin() + pos + random(0, test.size() - pos),
424 test.begin() + pos + random(0, test.size() - pos),
427 pos = random(0, test.size());
431 test.begin() + pos + random(0, test.size() - pos),
432 String(test).c_str(),
433 test.size() - random(0, test.size()));
437 test.begin() + pos + random(0, test.size() - pos),
439 test.size() - random(0, test.size()));
441 pos = random(0, test.size());
442 auto const n = random(0, test.size() - pos);
443 typename String::iterator b = test.begin();
445 randomString(&str1, maxString);
446 const String & str3 = str1;
447 const typename String::value_type* ss = str3.c_str();
452 pos = random(0, test.size());
455 test.begin() + pos + random(0, test.size() - pos),
456 random(0, maxString), random('a', 'z'));
459 template <class String> void clause_21_3_5_p(String & test) {
460 std::vector<typename String::value_type>
461 vec(random(0, maxString));
465 random(0, test.size()));
468 template <class String> void clause_21_3_5_q(String & test) {
470 randomString(&s, maxString);
474 template <class String> void clause_21_3_6_a(String & test) {
475 // 21.3.6 string operations
476 // exercise c_str() and data()
477 assert(test.c_str() == test.data());
478 // exercise get_allocator()
480 randomString(&s, maxString);
481 assert(test.get_allocator() == s.get_allocator());
484 template <class String> void clause_21_3_6_b(String & test) {
485 String str = test.substr(
486 random(0, test.size()),
487 random(0, test.size()));
488 Num2String(test, test.find(str, random(0, test.size())));
491 template <class String> void clause_21_3_6_c(String & test) {
492 auto from = random(0, test.size());
493 auto length = random(0, test.size() - from);
494 String str = test.substr(from, length);
495 Num2String(test, test.find(str.c_str(),
496 random(0, test.size()),
497 random(0, str.size())));
500 template <class String> void clause_21_3_6_d(String & test) {
501 String str = test.substr(
502 random(0, test.size()),
503 random(0, test.size()));
504 Num2String(test, test.find(str.c_str(),
505 random(0, test.size())));
508 template <class String> void clause_21_3_6_e(String & test) {
509 Num2String(test, test.find(
511 random(0, test.size())));
514 template <class String> void clause_21_3_6_f(String & test) {
515 String str = test.substr(
516 random(0, test.size()),
517 random(0, test.size()));
518 Num2String(test, test.rfind(str, random(0, test.size())));
521 template <class String> void clause_21_3_6_g(String & test) {
522 String str = test.substr(
523 random(0, test.size()),
524 random(0, test.size()));
525 Num2String(test, test.rfind(str.c_str(),
526 random(0, test.size()),
527 random(0, str.size())));
530 template <class String> void clause_21_3_6_h(String & test) {
531 String str = test.substr(
532 random(0, test.size()),
533 random(0, test.size()));
534 Num2String(test, test.rfind(str.c_str(),
535 random(0, test.size())));
538 template <class String> void clause_21_3_6_i(String & test) {
539 Num2String(test, test.rfind(
541 random(0, test.size())));
544 template <class String> void clause_21_3_6_j(String & test) {
546 randomString(&str, maxString);
547 Num2String(test, test.find_first_of(str,
548 random(0, test.size())));
551 template <class String> void clause_21_3_6_k(String & test) {
553 randomString(&str, maxString);
554 Num2String(test, test.find_first_of(str.c_str(),
555 random(0, test.size()),
556 random(0, str.size())));
559 template <class String> void clause_21_3_6_l(String & test) {
561 randomString(&str, maxString);
562 Num2String(test, test.find_first_of(str.c_str(),
563 random(0, test.size())));
566 template <class String> void clause_21_3_6_m(String & test) {
567 Num2String(test, test.find_first_of(
569 random(0, test.size())));
572 template <class String> void clause_21_3_6_n(String & test) {
574 randomString(&str, maxString);
575 Num2String(test, test.find_last_of(str,
576 random(0, test.size())));
579 template <class String> void clause_21_3_6_o(String & test) {
581 randomString(&str, maxString);
582 Num2String(test, test.find_last_of(str.c_str(),
583 random(0, test.size()),
584 random(0, str.size())));
587 template <class String> void clause_21_3_6_p(String & test) {
589 randomString(&str, maxString);
590 Num2String(test, test.find_last_of(str.c_str(),
591 random(0, test.size())));
594 template <class String> void clause_21_3_6_q(String & test) {
595 Num2String(test, test.find_last_of(
597 random(0, test.size())));
600 template <class String> void clause_21_3_6_r(String & test) {
602 randomString(&str, maxString);
603 Num2String(test, test.find_first_not_of(str,
604 random(0, test.size())));
607 template <class String> void clause_21_3_6_s(String & test) {
609 randomString(&str, maxString);
610 Num2String(test, test.find_first_not_of(str.c_str(),
611 random(0, test.size()),
612 random(0, str.size())));
615 template <class String> void clause_21_3_6_t(String & test) {
617 randomString(&str, maxString);
618 Num2String(test, test.find_first_not_of(str.c_str(),
619 random(0, test.size())));
622 template <class String> void clause_21_3_6_u(String & test) {
623 Num2String(test, test.find_first_not_of(
625 random(0, test.size())));
628 template <class String> void clause_21_3_6_v(String & test) {
630 randomString(&str, maxString);
631 Num2String(test, test.find_last_not_of(str,
632 random(0, test.size())));
635 template <class String> void clause_21_3_6_w(String & test) {
637 randomString(&str, maxString);
638 Num2String(test, test.find_last_not_of(str.c_str(),
639 random(0, test.size()),
640 random(0, str.size())));
643 template <class String> void clause_21_3_6_x(String & test) {
645 randomString(&str, maxString);
646 Num2String(test, test.find_last_not_of(str.c_str(),
647 random(0, test.size())));
650 template <class String> void clause_21_3_6_y(String & test) {
651 Num2String(test, test.find_last_not_of(
653 random(0, test.size())));
656 template <class String> void clause_21_3_6_z(String & test) {
657 test = test.substr(random(0, test.size()), random(0, test.size()));
660 template <class String> void clause_21_3_7_a(String & test) {
662 randomString(&s, maxString);
663 int tristate = test.compare(s);
664 if (tristate > 0) tristate = 1;
665 else if (tristate < 0) tristate = 2;
666 Num2String(test, tristate);
669 template <class String> void clause_21_3_7_b(String & test) {
671 randomString(&s, maxString);
672 int tristate = test.compare(
673 random(0, test.size()),
674 random(0, test.size()),
676 if (tristate > 0) tristate = 1;
677 else if (tristate < 0) tristate = 2;
678 Num2String(test, tristate);
681 template <class String> void clause_21_3_7_c(String & test) {
683 randomString(&str, maxString);
684 int tristate = test.compare(
685 random(0, test.size()),
686 random(0, test.size()),
688 random(0, str.size()),
689 random(0, str.size()));
690 if (tristate > 0) tristate = 1;
691 else if (tristate < 0) tristate = 2;
692 Num2String(test, tristate);
695 template <class String> void clause_21_3_7_d(String & test) {
697 randomString(&s, maxString);
698 int tristate = test.compare(s.c_str());
699 if (tristate > 0) tristate = 1;
700 else if (tristate < 0) tristate = 2;
701 Num2String(test, tristate);
704 template <class String> void clause_21_3_7_e(String & test) {
706 randomString(&str, maxString);
707 int tristate = test.compare(
708 random(0, test.size()),
709 random(0, test.size()),
711 random(0, str.size()));
712 if (tristate > 0) tristate = 1;
713 else if (tristate < 0) tristate = 2;
714 Num2String(test, tristate);
717 template <class String> void clause_21_3_7_f(String & test) {
719 randomString(&s1, maxString);
721 randomString(&s2, maxString);
725 template <class String> void clause_21_3_7_g(String & test) {
727 randomString(&s, maxString);
729 randomString(&s1, maxString);
730 test = s.c_str() + s1;
733 template <class String> void clause_21_3_7_h(String & test) {
735 randomString(&s, maxString);
736 test = typename String::value_type(random('a', 'z')) + s;
739 template <class String> void clause_21_3_7_i(String & test) {
741 randomString(&s, maxString);
743 randomString(&s1, maxString);
744 test = s + s1.c_str();
747 template <class String> void clause_21_3_7_j(String & test) {
749 randomString(&s, maxString);
751 randomString(&s1, maxString);
752 test = s + s1.c_str();
755 template <class String> void clause_21_3_7_k(String & test) {
757 randomString(&s, maxString);
758 test = s + typename String::value_type(random('a', 'z'));
761 // Numbering here is from C++11
762 template <class String> void clause_21_4_8_9_a(String & test) {
763 stringstream s("asd asdfjhuhdf asdfasdf\tasdsdf");
771 TEST(FBString, testAllClauses) {
772 EXPECT_TRUE(1) << "Starting with seed: " << seed;
775 #define TEST_CLAUSE(x) \
777 if (1) {} else EXPECT_TRUE(1) << "Testing clause " << #x; \
781 auto localSeed = seed + count; \
782 rng = RandomT(localSeed); \
784 rng = RandomT(localSeed); \
787 << "Lengths: " << r.size() << " vs. " << c.size() \
788 << "\nReference: '" << r << "'" \
789 << "\nActual: '" << c.data()[0] << "'"; \
790 } while (++count % 100 != 0)
793 TEST_CLAUSE(21_3_1_a);
794 TEST_CLAUSE(21_3_1_b);
795 TEST_CLAUSE(21_3_1_c);
796 TEST_CLAUSE(21_3_1_d);
797 TEST_CLAUSE(21_3_1_e);
798 TEST_CLAUSE(21_3_1_f);
799 TEST_CLAUSE(21_3_1_g);
804 TEST_CLAUSE(21_3_5_a);
805 TEST_CLAUSE(21_3_5_b);
806 TEST_CLAUSE(21_3_5_c);
807 TEST_CLAUSE(21_3_5_d);
808 TEST_CLAUSE(21_3_5_e);
809 TEST_CLAUSE(21_3_5_f);
810 TEST_CLAUSE(21_3_5_g);
811 TEST_CLAUSE(21_3_5_h);
812 TEST_CLAUSE(21_3_5_i);
813 TEST_CLAUSE(21_3_5_j);
814 TEST_CLAUSE(21_3_5_k);
815 TEST_CLAUSE(21_3_5_l);
816 TEST_CLAUSE(21_3_5_m);
817 TEST_CLAUSE(21_3_5_n);
818 TEST_CLAUSE(21_3_5_o);
819 TEST_CLAUSE(21_3_5_p);
821 TEST_CLAUSE(21_3_6_a);
822 TEST_CLAUSE(21_3_6_b);
823 TEST_CLAUSE(21_3_6_c);
824 TEST_CLAUSE(21_3_6_d);
825 TEST_CLAUSE(21_3_6_e);
826 TEST_CLAUSE(21_3_6_f);
827 TEST_CLAUSE(21_3_6_g);
828 TEST_CLAUSE(21_3_6_h);
829 TEST_CLAUSE(21_3_6_i);
830 TEST_CLAUSE(21_3_6_j);
831 TEST_CLAUSE(21_3_6_k);
832 TEST_CLAUSE(21_3_6_l);
833 TEST_CLAUSE(21_3_6_m);
834 TEST_CLAUSE(21_3_6_n);
835 TEST_CLAUSE(21_3_6_o);
836 TEST_CLAUSE(21_3_6_p);
837 TEST_CLAUSE(21_3_6_q);
838 TEST_CLAUSE(21_3_6_r);
839 TEST_CLAUSE(21_3_6_s);
840 TEST_CLAUSE(21_3_6_t);
841 TEST_CLAUSE(21_3_6_u);
842 TEST_CLAUSE(21_3_6_v);
843 TEST_CLAUSE(21_3_6_w);
844 TEST_CLAUSE(21_3_6_x);
845 TEST_CLAUSE(21_3_6_y);
846 TEST_CLAUSE(21_3_6_z);
848 TEST_CLAUSE(21_3_7_a);
849 TEST_CLAUSE(21_3_7_b);
850 TEST_CLAUSE(21_3_7_c);
851 TEST_CLAUSE(21_3_7_d);
852 TEST_CLAUSE(21_3_7_e);
853 TEST_CLAUSE(21_3_7_f);
854 TEST_CLAUSE(21_3_7_g);
855 TEST_CLAUSE(21_3_7_h);
856 TEST_CLAUSE(21_3_7_i);
857 TEST_CLAUSE(21_3_7_j);
858 TEST_CLAUSE(21_3_7_k);
860 TEST_CLAUSE(21_4_8_9_a);
863 TEST(FBString, testGetline) {
865 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan \n\
866 elit ut urna consectetur in sagittis mi auctor. Nulla facilisi. In nec \n\
867 dolor leo, vitae imperdiet neque. Donec ut erat mauris, a faucibus \n\
868 elit. Integer consectetur gravida augue, sit amet mattis mauris auctor \n\
869 sed. Morbi congue libero eu nunc sodales adipiscing. In lectus nunc, \n\
870 vulputate a fringilla at, venenatis quis justo. Proin eu velit \n\
871 nibh. Maecenas vitae tellus eros. Pellentesque habitant morbi \n\
872 tristique senectus et netus et malesuada fames ac turpis \n\
873 egestas. Vivamus faucibus feugiat consequat. Donec fermentum neque sit \n\
874 amet ligula suscipit porta. Phasellus facilisis felis in purus luctus \n\
875 quis posuere leo tempor. Nam nunc purus, luctus a pharetra ut, \n\
876 placerat at dui. Donec imperdiet, diam quis convallis pulvinar, dui \n\
877 est commodo lorem, ut tincidunt diam nibh et nibh. Maecenas nec velit \n\
878 massa, ut accumsan magna. Donec imperdiet tempor nisi et \n\
879 laoreet. Phasellus lectus quam, ultricies ut tincidunt in, dignissim \n\
880 id eros. Mauris vulputate tortor nec neque pellentesque sagittis quis \n\
881 sed nisl. In diam lacus, lobortis ut posuere nec, ornare id quam.";
882 const char* f = "/tmp/fbstring_testing";
884 std::ofstream out(f);
886 EXPECT_TRUE(0) << "Couldn't write to temp file.";
891 boost::split(v, s1, boost::is_any_of("\n"));
895 EXPECT_TRUE(getline(input, line));
900 TEST(FBString, testMoveCtor) {
901 // Move constructor. Make sure we allocate a large string, so the
902 // small string optimization doesn't kick in.
903 auto size = random(100, 2000);
904 fbstring s(size, 'a');
905 fbstring test = std::move(s);
906 EXPECT_TRUE(s.empty());
907 EXPECT_EQ(size, test.size());
910 TEST(FBString, testMoveAssign) {
911 // Move constructor. Make sure we allocate a large string, so the
912 // small string optimization doesn't kick in.
913 auto size = random(100, 2000);
914 fbstring s(size, 'a');
917 EXPECT_TRUE(s.empty());
918 EXPECT_EQ(size, test.size());
921 TEST(FBString, testMoveOperatorPlusLhs) {
922 // Make sure we allocate a large string, so the
923 // small string optimization doesn't kick in.
924 auto size1 = random(100, 2000);
925 auto size2 = random(100, 2000);
926 fbstring s1(size1, 'a');
927 fbstring s2(size2, 'b');
929 test = std::move(s1) + s2;
930 EXPECT_TRUE(s1.empty());
931 EXPECT_EQ(size1 + size2, test.size());
934 TEST(FBString, testMoveOperatorPlusRhs) {
935 // Make sure we allocate a large string, so the
936 // small string optimization doesn't kick in.
937 auto size1 = random(100, 2000);
938 auto size2 = random(100, 2000);
939 fbstring s1(size1, 'a');
940 fbstring s2(size2, 'b');
942 test = s1 + std::move(s2);
943 EXPECT_EQ(size1 + size2, test.size());
946 TEST(FBString, testConstructionFromLiteralZero) {
950 } catch (const std::logic_error&) {
958 } catch (const std::logic_error& e) {
964 TEST(FBString, testFixedBugs) {
966 fbstring str(1337, 'f');
970 EXPECT_EQ(str.front(), 'f');
972 { // D481173, --extra-cxxflags=-DFBSTRING_CONSERVATIVE
973 fbstring str(1337, 'f');
974 for (int i = 0; i < 2; ++i) {
977 EXPECT_EQ(cp.c_str()[cp.size()], '\0');
983 #define CONCAT(A, B) CONCAT_HELPER(A, B)
984 #define CONCAT_HELPER(A, B) A##B
985 #define BENCHFUN(F) CONCAT(CONCAT(BM_, F), CONCAT(_, STRING))
987 #define STRING string
988 #include "folly/test/FBStringTestBenchmarks.cpp.h"
990 #define STRING fbstring
991 #include "folly/test/FBStringTestBenchmarks.cpp.h"
994 int main(int argc, char** argv) {
995 testing::InitGoogleTest(&argc, argv);
996 google::ParseCommandLineFlags(&argc, &argv, true);
997 auto ret = RUN_ALL_TESTS();
998 if (!ret && FLAGS_benchmark) {
999 folly::runBenchmarks();
1008 BENCHFUN(defaultCtor) 100000 1.426 s 14.26 us 68.47 k
1009 BM_copyCtor_string/32k 100000 63.48 ms 634.8 ns 1.502 M
1010 BM_ctorFromArray_string/32k 100000 303.3 ms 3.033 us 321.9 k
1011 BM_ctorFromChar_string/1M 100000 9.915 ms 99.15 ns 9.619 M
1012 BM_assignmentOp_string/256 100000 69.09 ms 690.9 ns 1.38 M
1013 BENCHFUN(assignmentFill) 100000 1.775 ms 17.75 ns 53.73 M
1014 BM_resize_string/512k 100000 1.667 s 16.67 us 58.58 k
1015 BM_findSuccessful_string/512k 100000 287.3 ms 2.873 us 339.9 k
1016 BM_findUnsuccessful_string/512k 100000 320.3 ms 3.203 us 304.9 k
1017 BM_replace_string/256 100000 69.68 ms 696.8 ns 1.369 M
1018 BM_push_back_string/1k 100000 433.1 ms 4.331 us 225.5 k
1020 BENCHFUN(defaultCtor) 100000 1.086 s 10.86 us 89.91 k
1021 BM_copyCtor_fbstring/32k 100000 4.218 ms 42.18 ns 22.61 M
1022 BM_ctorFromArray_fbstring/32k 100000 145.2 ms 1.452 us 672.7 k
1023 BM_ctorFromChar_fbstring/1M 100000 9.21 ms 92.1 ns 10.35 M
1024 BM_assignmentOp_fbstring/256 100000 61.95 ms 619.5 ns 1.54 M
1025 BENCHFUN(assignmentFill) 100000 1.41 ms 14.1 ns 67.64 M
1026 BM_resize_fbstring/512k 100000 1.668 s 16.68 us 58.56 k
1027 BM_findSuccessful_fbstring/512k 100000 20.6 ms 206 ns 4.629 M
1028 BM_findUnsuccessful_fbstring/512k 100000 141.3 ms 1.413 us 691.1 k
1029 BM_replace_fbstring/256 100000 77.12 ms 771.2 ns 1.237 M
1030 BM_push_back_fbstring/1k 100000 1.745 s 17.45 us 55.95 k
1034 BENCHFUN(defaultCtor) 100000 1.426 s 14.26 us 68.5 k
1035 BM_copyCtor_string/32k 100000 275.7 ms 2.757 us 354.2 k
1036 BM_ctorFromArray_string/32k 100000 270 ms 2.7 us 361.7 k
1037 BM_ctorFromChar_string/1M 100000 10.36 ms 103.6 ns 9.206 M
1038 BM_assignmentOp_string/256 100000 70.44 ms 704.3 ns 1.354 M
1039 BENCHFUN(assignmentFill) 100000 1.766 ms 17.66 ns 54 M
1040 BM_resize_string/512k 100000 1.675 s 16.75 us 58.29 k
1041 BM_findSuccessful_string/512k 100000 90.89 ms 908.9 ns 1.049 M
1042 BM_findUnsuccessful_string/512k 100000 315.1 ms 3.151 us 309.9 k
1043 BM_replace_string/256 100000 71.14 ms 711.4 ns 1.341 M
1044 BM_push_back_string/1k 100000 425.1 ms 4.251 us 229.7 k
1046 BENCHFUN(defaultCtor) 100000 1.082 s 10.82 us 90.23 k
1047 BM_copyCtor_fbstring/32k 100000 4.213 ms 42.13 ns 22.64 M
1048 BM_ctorFromArray_fbstring/32k 100000 113.2 ms 1.132 us 863 k
1049 BM_ctorFromChar_fbstring/1M 100000 9.162 ms 91.62 ns 10.41 M
1050 BM_assignmentOp_fbstring/256 100000 61.34 ms 613.4 ns 1.555 M
1051 BENCHFUN(assignmentFill) 100000 1.408 ms 14.08 ns 67.73 M
1052 BM_resize_fbstring/512k 100000 1.671 s 16.71 us 58.43 k
1053 BM_findSuccessful_fbstring/512k 100000 8.723 ms 87.23 ns 10.93 M
1054 BM_findUnsuccessful_fbstring/512k 100000 141.3 ms 1.413 us 691.2 k
1055 BM_replace_fbstring/256 100000 77.83 ms 778.3 ns 1.225 M
1056 BM_push_back_fbstring/1k 100000 1.744 s 17.44 us 55.99 k