315b3e4acd9c299bcf2b5b0ff82ef8801ce81977
[folly.git] / folly / test / FBStringTest.cpp
1 /*
2  * Copyright 2015 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 //
18 // Author: andrei.alexandrescu@fb.com
19
20 #include <folly/FBString.h>
21
22 #include <cstdlib>
23
24 #include <list>
25 #include <fstream>
26 #include <iomanip>
27 #include <boost/algorithm/string.hpp>
28 #include <boost/random.hpp>
29 #include <gtest/gtest.h>
30
31 #include <gflags/gflags.h>
32
33 #include <folly/Foreach.h>
34 #include <folly/Portability.h>
35 #include <folly/Random.h>
36 #include <folly/Conv.h>
37
38 using namespace std;
39 using namespace folly;
40
41 static const int seed = folly::randomNumberSeed();
42 typedef boost::mt19937 RandomT;
43 static RandomT rng(seed);
44 static const size_t maxString = 100;
45 static const bool avoidAliasing = true;
46
47 template <class Integral1, class Integral2>
48 Integral2 random(Integral1 low, Integral2 up) {
49   boost::uniform_int<> range(low, up);
50   return range(rng);
51 }
52
53 template <class String>
54 void randomString(String* toFill, unsigned int maxSize = 1000) {
55   assert(toFill);
56   toFill->resize(random(0, maxSize));
57   FOR_EACH (i, *toFill) {
58     *i = random('a', 'z');
59   }
60 }
61
62 template <class String, class Integral>
63 void Num2String(String& str, Integral n) {
64
65   std::string tmp = folly::to<std::string>(n);
66   str = String(tmp.begin(), tmp.end());
67 }
68
69 std::list<char> RandomList(unsigned int maxSize) {
70   std::list<char> lst(random(0u, maxSize));
71   std::list<char>::iterator i = lst.begin();
72   for (; i != lst.end(); ++i) {
73     *i = random('a', 'z');
74  }
75   return lst;
76 }
77
78 ////////////////////////////////////////////////////////////////////////////////
79 // Tests begin here
80 ////////////////////////////////////////////////////////////////////////////////
81
82 template <class String> void clause11_21_4_2_a(String & test) {
83   test.String::~String();
84   new(&test) String();
85 }
86 template <class String> void clause11_21_4_2_b(String & test) {
87   String test2(test);
88   assert(test2 == test);
89 }
90 template <class String> void clause11_21_4_2_c(String & test) {
91   // Test move constructor. There is a more specialized test, see
92   // TEST(FBString, testMoveCtor)
93   String donor(test);
94   String test2(std::move(donor));
95   EXPECT_EQ(test2, test);
96   // Technically not required, but all implementations that actually
97   // support move will move large strings. Make a guess for 128 as the
98   // maximum small string optimization that's reasonable.
99   EXPECT_LE(donor.size(), 128);
100 }
101 template <class String> void clause11_21_4_2_d(String & test) {
102   // Copy constructor with position and length
103   const size_t pos = random(0, test.size());
104   String s(test, pos, random(0, 9)
105            ? random(0, (size_t)(test.size() - pos))
106            : String::npos); // test for npos, too, in 10% of the cases
107   test = s;
108 }
109 template <class String> void clause11_21_4_2_e(String & test) {
110   // Constructor from char*, size_t
111   const size_t
112     pos = random(0, test.size()),
113     n = random(0, test.size() - pos);
114   String before(test.data(), test.size());
115   String s(test.c_str() + pos, n);
116   String after(test.data(), test.size());
117   EXPECT_EQ(before, after);
118   test.swap(s);
119 }
120 template <class String> void clause11_21_4_2_f(String & test) {
121   // Constructor from char*
122   const size_t
123     pos = random(0, test.size()),
124     n = random(0, test.size() - pos);
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);
129   test.swap(s);
130 }
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();
135   test = String(n, c);
136 }
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());
141   EXPECT_EQ(test, s1);
142   String s2(test.data(), test.data() + test.size());
143   EXPECT_EQ(test, s2);
144   // Constructor from other iterators
145   std::list<char> lst;
146   for (auto c : test) lst.push_back(c);
147   String s3(lst.begin(), lst.end());
148   EXPECT_EQ(test, s3);
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());
153   EXPECT_EQ(test, s4);
154   // Constructor from wchar_t pointers
155   wchar_t t[20];
156   t[0] = 'a';
157   t[1] = 'b';
158   fbstring s5(t, t + 2);;
159   EXPECT_EQ("ab", s5);
160 }
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' };
165   String s(il);
166   test.swap(s);
167 }
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');
175   }
176   test = s;
177 }
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');
185   }
186   test = std::move(s);
187   if (typeid(String) == typeid(fbstring)) {
188     EXPECT_LE(s.size(), 128);
189   }
190 }
191 template <class String> void clause11_21_4_2_l(String & test) {
192   // Assignment from char*
193   String s(random(0, 1000), '\0');
194   size_t i = 0;
195   for (; i != s.size(); ++i) {
196     s[i] = random('a', 'z');
197   }
198   test = s.c_str();
199 }
200 template <class String> void clause11_21_4_2_lprime(String & test) {
201   // Aliased assign
202   const size_t pos = random(0, test.size());
203   if (avoidAliasing) {
204     test = String(test.c_str() + pos);
205   } else {
206     test = test.c_str() + pos;
207   }
208 }
209 template <class String> void clause11_21_4_2_m(String & test) {
210   // Assignment from char
211   test = random('a', 'z');
212 }
213 template <class String> void clause11_21_4_2_n(String & test) {
214   // Assignment from initializer_list<char>
215   initializer_list<typename String::value_type>
216     il = { 'h', 'e', 'l', 'l', 'o' };
217   test = il;
218 }
219
220 template <class String> void clause11_21_4_3(String & test) {
221   // Iterators. The code below should leave test unchanged
222   EXPECT_EQ(test.size(), test.end() - test.begin());
223   EXPECT_EQ(test.size(), test.rend() - test.rbegin());
224   EXPECT_EQ(test.size(), test.cend() - test.cbegin());
225   EXPECT_EQ(test.size(), test.crend() - test.crbegin());
226
227   auto s = test.size();
228   test.resize(test.end() - test.begin());
229   EXPECT_EQ(s, test.size());
230   test.resize(test.rend() - test.rbegin());
231   EXPECT_EQ(s, test.size());
232 }
233
234 template <class String> void clause11_21_4_4(String & test) {
235   // exercise capacity, size, max_size
236   EXPECT_EQ(test.size(), test.length());
237   EXPECT_LE(test.size(), test.max_size());
238   EXPECT_LE(test.capacity(), test.max_size());
239   EXPECT_LE(test.size(), test.capacity());
240
241   // exercise shrink_to_fit. Nonbinding request so we can't really do
242   // much beyond calling it.
243   auto copy = test;
244   copy.reserve(copy.capacity() * 3);
245   copy.shrink_to_fit();
246   EXPECT_EQ(copy, test);
247
248   // exercise empty
249   string empty("empty");
250   string notempty("not empty");
251   if (test.empty()) test = String(empty.begin(), empty.end());
252   else test = String(notempty.begin(), notempty.end());
253 }
254
255 template <class String> void clause11_21_4_5(String & test) {
256   // exercise element access
257   if (!test.empty()) {
258     EXPECT_EQ(test[0], test.front());
259     EXPECT_EQ(test[test.size() - 1], test.back());
260     auto const i = random(0, test.size() - 1);
261     EXPECT_EQ(test[i], test.at(i));
262     test = test[i];
263   }
264 }
265
266 template <class String> void clause11_21_4_6_1(String & test) {
267   // 21.3.5 modifiers (+=)
268   String test1;
269   randomString(&test1);
270   assert(test1.size() == char_traits
271       <typename String::value_type>::length(test1.c_str()));
272   auto len = test.size();
273   test += test1;
274   EXPECT_EQ(test.size(), test1.size() + len);
275   FOR_EACH_RANGE (i, 0, test1.size()) {
276     EXPECT_EQ(test[len + i], test1[i]);
277   }
278   // aliasing modifiers
279   String test2 = test;
280   auto dt = test2.data();
281   auto sz = test.c_str();
282   len = test.size();
283   EXPECT_EQ(memcmp(sz, dt, len), 0);
284   String copy(test.data(), test.size());
285   EXPECT_EQ(char_traits
286       <typename String::value_type>::length(test.c_str()), len);
287   test += test;
288   //test.append(test);
289   EXPECT_EQ(test.size(), 2 * len);
290   EXPECT_EQ(char_traits
291       <typename String::value_type>::length(test.c_str()), 2 * len);
292   FOR_EACH_RANGE (i, 0, len) {
293     EXPECT_EQ(test[i], copy[i]);
294     EXPECT_EQ(test[i], test[len + i]);
295   }
296   len = test.size();
297   EXPECT_EQ(char_traits
298       <typename String::value_type>::length(test.c_str()), len);
299   // more aliasing
300   auto const pos = random(0, test.size());
301   EXPECT_EQ(char_traits
302       <typename String::value_type>::length(test.c_str() + pos), len - pos);
303   if (avoidAliasing) {
304     String addMe(test.c_str() + pos);
305     EXPECT_EQ(addMe.size(), len - pos);
306     test += addMe;
307   } else {
308     test += test.c_str() + pos;
309   }
310   EXPECT_EQ(test.size(), 2 * len - pos);
311   // single char
312   len = test.size();
313   test += random('a', 'z');
314   EXPECT_EQ(test.size(), len + 1);
315   // initializer_list
316   initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
317   test += il;
318 }
319
320 template <class String> void clause11_21_4_6_2(String & test) {
321   // 21.3.5 modifiers (append, push_back)
322   String s;
323
324   // Test with a small string first
325   char c = random('a', 'z');
326   s.push_back(c);
327   EXPECT_EQ(s[s.size() - 1], c);
328   EXPECT_EQ(s.size(), 1);
329   s.resize(s.size() - 1);
330
331   randomString(&s, maxString);
332   test.append(s);
333   randomString(&s, maxString);
334   test.append(s, random(0, s.size()), random(0, maxString));
335   randomString(&s, maxString);
336   test.append(s.c_str(), random(0, s.size()));
337   randomString(&s, maxString);
338   test.append(s.c_str());
339   test.append(random(0, maxString), random('a', 'z'));
340   std::list<char> lst(RandomList(maxString));
341   test.append(lst.begin(), lst.end());
342   c = random('a', 'z');
343   test.push_back(c);
344   EXPECT_EQ(test[test.size() - 1], c);
345   // initializer_list
346   initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
347   test.append(il);
348 }
349
350 template <class String> void clause11_21_4_6_3_a(String & test) {
351   // assign
352   String s;
353   randomString(&s);
354   test.assign(s);
355   EXPECT_EQ(test, s);
356   // move assign
357   test.assign(std::move(s));
358   if (typeid(String) == typeid(fbstring)) {
359     EXPECT_LE(s.size(), 128);
360   }
361 }
362
363 template <class String> void clause11_21_4_6_3_b(String & test) {
364   // assign
365   String s;
366   randomString(&s, maxString);
367   test.assign(s, random(0, s.size()), random(0, maxString));
368 }
369
370 template <class String> void clause11_21_4_6_3_c(String & test) {
371   // assign
372   String s;
373   randomString(&s, maxString);
374   test.assign(s.c_str(), random(0, s.size()));
375 }
376
377 template <class String> void clause11_21_4_6_3_d(String & test) {
378   // assign
379   String s;
380   randomString(&s, maxString);
381   test.assign(s.c_str());
382 }
383
384 template <class String> void clause11_21_4_6_3_e(String & test) {
385   // assign
386   String s;
387   randomString(&s, maxString);
388   test.assign(random(0, maxString), random('a', 'z'));
389 }
390
391 template <class String> void clause11_21_4_6_3_f(String & test) {
392   // assign from bidirectional iterator
393   std::list<char> lst(RandomList(maxString));
394   test.assign(lst.begin(), lst.end());
395 }
396
397 template <class String> void clause11_21_4_6_3_g(String & test) {
398   // assign from aliased source
399   test.assign(test);
400 }
401
402 template <class String> void clause11_21_4_6_3_h(String & test) {
403   // assign from aliased source
404   test.assign(test, random(0, test.size()), random(0, maxString));
405 }
406
407 template <class String> void clause11_21_4_6_3_i(String & test) {
408   // assign from aliased source
409   test.assign(test.c_str(), random(0, test.size()));
410 }
411
412 template <class String> void clause11_21_4_6_3_j(String & test) {
413   // assign from aliased source
414   test.assign(test.c_str());
415 }
416
417 template <class String> void clause11_21_4_6_3_k(String & test) {
418   // assign from initializer_list
419   initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
420   test.assign(il);
421 }
422
423 template <class String> void clause11_21_4_6_4(String & test) {
424   // insert
425   String s;
426   randomString(&s, maxString);
427   test.insert(random(0, test.size()), s);
428   randomString(&s, maxString);
429   test.insert(random(0, test.size()),
430               s, random(0, s.size()),
431               random(0, maxString));
432   randomString(&s, maxString);
433   test.insert(random(0, test.size()),
434               s.c_str(), random(0, s.size()));
435   randomString(&s, maxString);
436   test.insert(random(0, test.size()), s.c_str());
437   test.insert(random(0, test.size()),
438               random(0, maxString), random('a', 'z'));
439   typename String::size_type pos = random(0, test.size());
440   typename String::iterator res =
441     test.insert(test.begin() + pos, random('a', 'z'));
442   EXPECT_EQ(res - test.begin(), pos);
443   std::list<char> lst(RandomList(maxString));
444   pos = random(0, test.size());
445   // Uncomment below to see a bug in gcc
446   /*res = */test.insert(test.begin() + pos, lst.begin(), lst.end());
447   // insert from initializer_list
448   initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
449   pos = random(0, test.size());
450   // Uncomment below to see a bug in gcc
451   /*res = */test.insert(test.begin() + pos, il);
452
453   // Test with actual input iterators
454   stringstream ss;
455   ss << "hello cruel world";
456   auto i = istream_iterator<char>(ss);
457   test.insert(test.begin(), i, istream_iterator<char>());
458 }
459
460 template <class String> void clause11_21_4_6_5(String & test) {
461   // erase and pop_back
462   if (!test.empty()) {
463     test.erase(random(0, test.size()), random(0, maxString));
464   }
465   if (!test.empty()) {
466     // TODO: is erase(end()) allowed?
467     test.erase(test.begin() + random(0, test.size() - 1));
468   }
469   if (!test.empty()) {
470     auto const i = test.begin() + random(0, test.size());
471     if (i != test.end()) {
472       test.erase(i, i + random(0, size_t(test.end() - i)));
473     }
474   }
475   if (!test.empty()) {
476     // Can't test pop_back with std::string, doesn't support it yet.
477     //test.pop_back();
478   }
479 }
480
481 template <class String> void clause11_21_4_6_6(String & test) {
482   auto pos = random(0, test.size());
483   if (avoidAliasing) {
484     test.replace(pos, random(0, test.size() - pos),
485                  String(test));
486   } else {
487     test.replace(pos, random(0, test.size() - pos), test);
488   }
489   pos = random(0, test.size());
490   String s;
491   randomString(&s, maxString);
492   test.replace(pos, pos + random(0, test.size() - pos), s);
493   auto pos1 = random(0, test.size());
494   auto pos2 = random(0, test.size());
495   if (avoidAliasing) {
496     test.replace(pos1, pos1 + random(0, test.size() - pos1),
497                  String(test),
498                  pos2, pos2 + random(0, test.size() - pos2));
499   } else {
500     test.replace(pos1, pos1 + random(0, test.size() - pos1),
501                  test, pos2, pos2 + random(0, test.size() - pos2));
502   }
503   pos1 = random(0, test.size());
504   String str;
505   randomString(&str, maxString);
506   pos2 = random(0, str.size());
507   test.replace(pos1, pos1 + random(0, test.size() - pos1),
508                str, pos2, pos2 + random(0, str.size() - pos2));
509   pos = random(0, test.size());
510   if (avoidAliasing) {
511     test.replace(pos, random(0, test.size() - pos),
512                  String(test).c_str(), test.size());
513   } else {
514     test.replace(pos, random(0, test.size() - pos),
515                  test.c_str(), test.size());
516   }
517   pos = random(0, test.size());
518   randomString(&str, maxString);
519   test.replace(pos, pos + random(0, test.size() - pos),
520                str.c_str(), str.size());
521   pos = random(0, test.size());
522   randomString(&str, maxString);
523   test.replace(pos, pos + random(0, test.size() - pos),
524                str.c_str());
525   pos = random(0, test.size());
526   test.replace(pos, random(0, test.size() - pos),
527                random(0, maxString), random('a', 'z'));
528   pos = random(0, test.size());
529   if (avoidAliasing) {
530     auto newString = String(test);
531     test.replace(
532       test.begin() + pos,
533       test.begin() + pos + random(0, test.size() - pos),
534       newString);
535   } else {
536     test.replace(
537       test.begin() + pos,
538       test.begin() + pos + random(0, test.size() - pos),
539       test);
540   }
541   pos = random(0, test.size());
542   if (avoidAliasing) {
543     auto newString = String(test);
544     test.replace(
545       test.begin() + pos,
546       test.begin() + pos + random(0, test.size() - pos),
547       newString.c_str(),
548       test.size() - random(0, test.size()));
549   } else {
550     test.replace(
551       test.begin() + pos,
552       test.begin() + pos + random(0, test.size() - pos),
553       test.c_str(),
554       test.size() - random(0, test.size()));
555   }
556   pos = random(0, test.size());
557   auto const n = random(0, test.size() - pos);
558   typename String::iterator b = test.begin();
559   String str1;
560   randomString(&str1, maxString);
561   const String & str3 = str1;
562   const typename String::value_type* ss = str3.c_str();
563   test.replace(
564     b + pos,
565     b + pos + n,
566     ss);
567   pos = random(0, test.size());
568   test.replace(
569     test.begin() + pos,
570     test.begin() + pos + random(0, test.size() - pos),
571     random(0, maxString), random('a', 'z'));
572 }
573
574 template <class String> void clause11_21_4_6_7(String & test) {
575   std::vector<typename String::value_type>
576     vec(random(0, maxString));
577   test.copy(
578     &vec[0],
579     vec.size(),
580     random(0, test.size()));
581 }
582
583 template <class String> void clause11_21_4_6_8(String & test) {
584   String s;
585   randomString(&s, maxString);
586   s.swap(test);
587 }
588
589 template <class String> void clause11_21_4_7_1(String & test) {
590   // 21.3.6 string operations
591   // exercise c_str() and data()
592   assert(test.c_str() == test.data());
593   // exercise get_allocator()
594   String s;
595   randomString(&s, maxString);
596   assert(test.get_allocator() == s.get_allocator());
597 }
598
599 template <class String> void clause11_21_4_7_2_a(String & test) {
600   String str = test.substr(
601     random(0, test.size()),
602     random(0, test.size()));
603   Num2String(test, test.find(str, random(0, test.size())));
604 }
605
606 template <class String> void clause11_21_4_7_2_a1(String & test) {
607   String str = String(test).substr(
608     random(0, test.size()),
609     random(0, test.size()));
610   Num2String(test, test.find(str, random(0, test.size())));
611 }
612
613 template <class String> void clause11_21_4_7_2_a2(String & test) {
614   auto const& cTest = test;
615   String str = cTest.substr(
616     random(0, test.size()),
617     random(0, test.size()));
618   Num2String(test, test.find(str, random(0, test.size())));
619 }
620
621 template <class String> void clause11_21_4_7_2_b(String & test) {
622   auto from = random(0, test.size());
623   auto length = random(0, test.size() - from);
624   String str = test.substr(from, length);
625   Num2String(test, test.find(str.c_str(),
626                              random(0, test.size()),
627                              random(0, str.size())));
628 }
629
630 template <class String> void clause11_21_4_7_2_b1(String & test) {
631   auto from = random(0, test.size());
632   auto length = random(0, test.size() - from);
633   String str = String(test).substr(from, length);
634   Num2String(test, test.find(str.c_str(),
635                              random(0, test.size()),
636                              random(0, str.size())));
637 }
638
639 template <class String> void clause11_21_4_7_2_b2(String & test) {
640   auto from = random(0, test.size());
641   auto length = random(0, test.size() - from);
642   const auto& cTest = test;
643   String str = cTest.substr(from, length);
644   Num2String(test, test.find(str.c_str(),
645                              random(0, test.size()),
646                              random(0, str.size())));
647 }
648
649 template <class String> void clause11_21_4_7_2_c(String & test) {
650   String str = test.substr(
651     random(0, test.size()),
652     random(0, test.size()));
653   Num2String(test, test.find(str.c_str(),
654                              random(0, test.size())));
655 }
656
657 template <class String> void clause11_21_4_7_2_c1(String & test) {
658   String str = String(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())));
663 }
664
665 template <class String> void clause11_21_4_7_2_c2(String & test) {
666   const auto& cTest = test;
667   String str = cTest.substr(
668     random(0, test.size()),
669     random(0, test.size()));
670   Num2String(test, test.find(str.c_str(),
671                              random(0, test.size())));
672 }
673
674 template <class String> void clause11_21_4_7_2_d(String & test) {
675   Num2String(test, test.find(
676                random('a', 'z'),
677                random(0, test.size())));
678 }
679
680 template <class String> void clause11_21_4_7_3_a(String & test) {
681   String str = test.substr(
682     random(0, test.size()),
683     random(0, test.size()));
684   Num2String(test, test.rfind(str, random(0, test.size())));
685 }
686
687 template <class String> void clause11_21_4_7_3_b(String & test) {
688   String str = test.substr(
689     random(0, test.size()),
690     random(0, test.size()));
691   Num2String(test, test.rfind(str.c_str(),
692                               random(0, test.size()),
693                               random(0, str.size())));
694 }
695
696 template <class String> void clause11_21_4_7_3_c(String & test) {
697   String str = test.substr(
698     random(0, test.size()),
699     random(0, test.size()));
700   Num2String(test, test.rfind(str.c_str(),
701                               random(0, test.size())));
702 }
703
704 template <class String> void clause11_21_4_7_3_d(String & test) {
705   Num2String(test, test.rfind(
706                random('a', 'z'),
707                random(0, test.size())));
708 }
709
710 template <class String> void clause11_21_4_7_4_a(String & test) {
711   String str;
712   randomString(&str, maxString);
713   Num2String(test, test.find_first_of(str,
714                                       random(0, test.size())));
715 }
716
717 template <class String> void clause11_21_4_7_4_b(String & test) {
718   String str;
719   randomString(&str, maxString);
720   Num2String(test, test.find_first_of(str.c_str(),
721                                       random(0, test.size()),
722                                       random(0, str.size())));
723 }
724
725 template <class String> void clause11_21_4_7_4_c(String & test) {
726   String str;
727   randomString(&str, maxString);
728   Num2String(test, test.find_first_of(str.c_str(),
729                                       random(0, test.size())));
730 }
731
732 template <class String> void clause11_21_4_7_4_d(String & test) {
733   Num2String(test, test.find_first_of(
734                random('a', 'z'),
735                random(0, test.size())));
736 }
737
738 template <class String> void clause11_21_4_7_5_a(String & test) {
739   String str;
740   randomString(&str, maxString);
741   Num2String(test, test.find_last_of(str,
742                                      random(0, test.size())));
743 }
744
745 template <class String> void clause11_21_4_7_5_b(String & test) {
746   String str;
747   randomString(&str, maxString);
748   Num2String(test, test.find_last_of(str.c_str(),
749                                      random(0, test.size()),
750                                      random(0, str.size())));
751 }
752
753 template <class String> void clause11_21_4_7_5_c(String & test) {
754   String str;
755   randomString(&str, maxString);
756   Num2String(test, test.find_last_of(str.c_str(),
757                                      random(0, test.size())));
758 }
759
760 template <class String> void clause11_21_4_7_5_d(String & test) {
761   Num2String(test, test.find_last_of(
762                random('a', 'z'),
763                random(0, test.size())));
764 }
765
766 template <class String> void clause11_21_4_7_6_a(String & test) {
767   String str;
768   randomString(&str, maxString);
769   Num2String(test, test.find_first_not_of(str,
770                                           random(0, test.size())));
771 }
772
773 template <class String> void clause11_21_4_7_6_b(String & test) {
774   String str;
775   randomString(&str, maxString);
776   Num2String(test, test.find_first_not_of(str.c_str(),
777                                           random(0, test.size()),
778                                           random(0, str.size())));
779 }
780
781 template <class String> void clause11_21_4_7_6_c(String & test) {
782   String str;
783   randomString(&str, maxString);
784   Num2String(test, test.find_first_not_of(str.c_str(),
785                                           random(0, test.size())));
786 }
787
788 template <class String> void clause11_21_4_7_6_d(String & test) {
789   Num2String(test, test.find_first_not_of(
790                random('a', 'z'),
791                random(0, test.size())));
792 }
793
794 template <class String> void clause11_21_4_7_7_a(String & test) {
795   String str;
796   randomString(&str, maxString);
797   Num2String(test, test.find_last_not_of(str,
798                                          random(0, test.size())));
799 }
800
801 template <class String> void clause11_21_4_7_7_b(String & test) {
802   String str;
803   randomString(&str, maxString);
804   Num2String(test, test.find_last_not_of(str.c_str(),
805                                          random(0, test.size()),
806                                          random(0, str.size())));
807 }
808
809 template <class String> void clause11_21_4_7_7_c(String & test) {
810   String str;
811   randomString(&str, maxString);
812   Num2String(test, test.find_last_not_of(str.c_str(),
813                                          random(0, test.size())));
814 }
815
816 template <class String> void clause11_21_4_7_7_d(String & test) {
817   Num2String(test, test.find_last_not_of(
818                random('a', 'z'),
819                random(0, test.size())));
820 }
821
822 template <class String> void clause11_21_4_7_8(String & test) {
823   test = test.substr(random(0, test.size()), random(0, test.size()));
824 }
825
826 template <class String> void clause11_21_4_7_9_a(String & test) {
827   String s;
828   randomString(&s, maxString);
829   int tristate = test.compare(s);
830   if (tristate > 0) tristate = 1;
831   else if (tristate < 0) tristate = 2;
832   Num2String(test, tristate);
833 }
834
835 template <class String> void clause11_21_4_7_9_b(String & test) {
836   String s;
837   randomString(&s, maxString);
838   int tristate = test.compare(
839     random(0, test.size()),
840     random(0, test.size()),
841     s);
842   if (tristate > 0) tristate = 1;
843   else if (tristate < 0) tristate = 2;
844   Num2String(test, tristate);
845 }
846
847 template <class String> void clause11_21_4_7_9_c(String & test) {
848   String str;
849   randomString(&str, maxString);
850   int tristate = test.compare(
851     random(0, test.size()),
852     random(0, test.size()),
853     str,
854     random(0, str.size()),
855     random(0, str.size()));
856   if (tristate > 0) tristate = 1;
857   else if (tristate < 0) tristate = 2;
858   Num2String(test, tristate);
859 }
860
861 template <class String> void clause11_21_4_7_9_d(String & test) {
862   String s;
863   randomString(&s, maxString);
864   int tristate = test.compare(s.c_str());
865   if (tristate > 0) tristate = 1;
866   else if (tristate < 0) tristate = 2;
867                 Num2String(test, tristate);
868 }
869
870 template <class String> void clause11_21_4_7_9_e(String & test) {
871   String str;
872   randomString(&str, maxString);
873   int tristate = test.compare(
874     random(0, test.size()),
875     random(0, test.size()),
876     str.c_str(),
877     random(0, str.size()));
878   if (tristate > 0) tristate = 1;
879   else if (tristate < 0) tristate = 2;
880   Num2String(test, tristate);
881 }
882
883 template <class String> void clause11_21_4_8_1_a(String & test) {
884   String s1;
885   randomString(&s1, maxString);
886   String s2;
887   randomString(&s2, maxString);
888   test = s1 + s2;
889 }
890
891 template <class String> void clause11_21_4_8_1_b(String & test) {
892   String s1;
893   randomString(&s1, maxString);
894   String s2;
895   randomString(&s2, maxString);
896   test = move(s1) + s2;
897 }
898
899 template <class String> void clause11_21_4_8_1_c(String & test) {
900   String s1;
901   randomString(&s1, maxString);
902   String s2;
903   randomString(&s2, maxString);
904   test = s1 + move(s2);
905 }
906
907 template <class String> void clause11_21_4_8_1_d(String & test) {
908   String s1;
909   randomString(&s1, maxString);
910   String s2;
911   randomString(&s2, maxString);
912   test = move(s1) + move(s2);
913 }
914
915 template <class String> void clause11_21_4_8_1_e(String & test) {
916   String s;
917   randomString(&s, maxString);
918   String s1;
919   randomString(&s1, maxString);
920   test = s.c_str() + s1;
921 }
922
923 template <class String> void clause11_21_4_8_1_f(String & test) {
924   String s;
925   randomString(&s, maxString);
926   String s1;
927   randomString(&s1, maxString);
928   test = s.c_str() + move(s1);
929 }
930
931 template <class String> void clause11_21_4_8_1_g(String & test) {
932   String s;
933   randomString(&s, maxString);
934   test = typename String::value_type(random('a', 'z')) + s;
935 }
936
937 template <class String> void clause11_21_4_8_1_h(String & test) {
938   String s;
939   randomString(&s, maxString);
940   test = typename String::value_type(random('a', 'z')) + move(s);
941 }
942
943 template <class String> void clause11_21_4_8_1_i(String & test) {
944   String s;
945   randomString(&s, maxString);
946   String s1;
947   randomString(&s1, maxString);
948   test = s + s1.c_str();
949 }
950
951 template <class String> void clause11_21_4_8_1_j(String & test) {
952   String s;
953   randomString(&s, maxString);
954   String s1;
955   randomString(&s1, maxString);
956   test = move(s) + s1.c_str();
957 }
958
959 template <class String> void clause11_21_4_8_1_k(String & test) {
960   String s;
961   randomString(&s, maxString);
962   test = s + typename String::value_type(random('a', 'z'));
963 }
964
965 template <class String> void clause11_21_4_8_1_l(String & test) {
966   String s;
967   randomString(&s, maxString);
968   String s1;
969   randomString(&s1, maxString);
970   test = move(s) + s1.c_str();
971 }
972
973 // Numbering here is from C++11
974 template <class String> void clause11_21_4_8_9_a(String & test) {
975   basic_stringstream<typename String::value_type> stst(test.c_str());
976   String str;
977   while (stst) {
978     stst >> str;
979     test += str + test;
980   }
981 }
982
983 TEST(FBString, testAllClauses) {
984   EXPECT_TRUE(1) << "Starting with seed: " << seed;
985   std::string r;
986   std::wstring wr;
987   folly::fbstring c;
988   folly::basic_fbstring<wchar_t> wc;
989   int count = 0;
990
991   auto l = [&](const char * const clause,
992                void(*f_string)(std::string&),
993                void(*f_fbstring)(folly::fbstring&),
994                void(*f_wfbstring)(folly::basic_fbstring<wchar_t>&)) {
995     do {
996       if (1) {} else EXPECT_TRUE(1) << "Testing clause " << clause;
997       randomString(&r);
998       c = r;
999       EXPECT_EQ(c, r);
1000       wr = std::wstring(r.begin(), r.end());
1001       wc = folly::basic_fbstring<wchar_t>(wr.c_str());
1002       auto localSeed = seed + count;
1003       rng = RandomT(localSeed);
1004       f_string(r);
1005       rng = RandomT(localSeed);
1006       f_fbstring(c);
1007       EXPECT_EQ(r, c)
1008         << "Lengths: " << r.size() << " vs. " << c.size()
1009         << "\nReference: '" << r << "'"
1010         << "\nActual:    '" << c.data()[0] << "'";
1011       rng = RandomT(localSeed);
1012       f_wfbstring(wc);
1013       int wret = wcslen(wc.c_str());
1014       char mb[wret+1];
1015       int ret = wcstombs(mb, wc.c_str(), sizeof(mb));
1016       if (ret == wret) mb[wret] = '\0';
1017       const char *mc = c.c_str();
1018       std::string one(mb);
1019       std::string two(mc);
1020       EXPECT_EQ(one, two);
1021     } while (++count % 100 != 0);
1022   };
1023
1024 #define TEST_CLAUSE(x) \
1025   l(#x, \
1026     clause11_##x<std::string>, \
1027     clause11_##x<folly::fbstring>, \
1028     clause11_##x<folly::basic_fbstring<wchar_t>>);
1029
1030   TEST_CLAUSE(21_4_2_a);
1031   TEST_CLAUSE(21_4_2_b);
1032   TEST_CLAUSE(21_4_2_c);
1033   TEST_CLAUSE(21_4_2_d);
1034   TEST_CLAUSE(21_4_2_e);
1035   TEST_CLAUSE(21_4_2_f);
1036   TEST_CLAUSE(21_4_2_g);
1037   TEST_CLAUSE(21_4_2_h);
1038   TEST_CLAUSE(21_4_2_i);
1039   TEST_CLAUSE(21_4_2_j);
1040   TEST_CLAUSE(21_4_2_k);
1041   TEST_CLAUSE(21_4_2_l);
1042   TEST_CLAUSE(21_4_2_lprime);
1043   TEST_CLAUSE(21_4_2_m);
1044   TEST_CLAUSE(21_4_2_n);
1045   TEST_CLAUSE(21_4_3);
1046   TEST_CLAUSE(21_4_4);
1047   TEST_CLAUSE(21_4_5);
1048   TEST_CLAUSE(21_4_6_1);
1049   TEST_CLAUSE(21_4_6_2);
1050   TEST_CLAUSE(21_4_6_3_a);
1051   TEST_CLAUSE(21_4_6_3_b);
1052   TEST_CLAUSE(21_4_6_3_c);
1053   TEST_CLAUSE(21_4_6_3_d);
1054   TEST_CLAUSE(21_4_6_3_e);
1055   TEST_CLAUSE(21_4_6_3_f);
1056   TEST_CLAUSE(21_4_6_3_g);
1057   TEST_CLAUSE(21_4_6_3_h);
1058   TEST_CLAUSE(21_4_6_3_i);
1059   TEST_CLAUSE(21_4_6_3_j);
1060   TEST_CLAUSE(21_4_6_3_k);
1061   TEST_CLAUSE(21_4_6_4);
1062   TEST_CLAUSE(21_4_6_5);
1063   TEST_CLAUSE(21_4_6_6);
1064   TEST_CLAUSE(21_4_6_7);
1065   TEST_CLAUSE(21_4_6_8);
1066   TEST_CLAUSE(21_4_7_1);
1067
1068   TEST_CLAUSE(21_4_7_2_a);
1069   TEST_CLAUSE(21_4_7_2_a1);
1070   TEST_CLAUSE(21_4_7_2_a2);
1071   TEST_CLAUSE(21_4_7_2_b);
1072   TEST_CLAUSE(21_4_7_2_b1);
1073   TEST_CLAUSE(21_4_7_2_b2);
1074   TEST_CLAUSE(21_4_7_2_c);
1075   TEST_CLAUSE(21_4_7_2_c1);
1076   TEST_CLAUSE(21_4_7_2_c2);
1077   TEST_CLAUSE(21_4_7_2_d);
1078   TEST_CLAUSE(21_4_7_3_a);
1079   TEST_CLAUSE(21_4_7_3_b);
1080   TEST_CLAUSE(21_4_7_3_c);
1081   TEST_CLAUSE(21_4_7_3_d);
1082   TEST_CLAUSE(21_4_7_4_a);
1083   TEST_CLAUSE(21_4_7_4_b);
1084   TEST_CLAUSE(21_4_7_4_c);
1085   TEST_CLAUSE(21_4_7_4_d);
1086   TEST_CLAUSE(21_4_7_5_a);
1087   TEST_CLAUSE(21_4_7_5_b);
1088   TEST_CLAUSE(21_4_7_5_c);
1089   TEST_CLAUSE(21_4_7_5_d);
1090   TEST_CLAUSE(21_4_7_6_a);
1091   TEST_CLAUSE(21_4_7_6_b);
1092   TEST_CLAUSE(21_4_7_6_c);
1093   TEST_CLAUSE(21_4_7_6_d);
1094   TEST_CLAUSE(21_4_7_7_a);
1095   TEST_CLAUSE(21_4_7_7_b);
1096   TEST_CLAUSE(21_4_7_7_c);
1097   TEST_CLAUSE(21_4_7_7_d);
1098   TEST_CLAUSE(21_4_7_8);
1099   TEST_CLAUSE(21_4_7_9_a);
1100   TEST_CLAUSE(21_4_7_9_b);
1101   TEST_CLAUSE(21_4_7_9_c);
1102   TEST_CLAUSE(21_4_7_9_d);
1103   TEST_CLAUSE(21_4_7_9_e);
1104   TEST_CLAUSE(21_4_8_1_a);
1105   TEST_CLAUSE(21_4_8_1_b);
1106   TEST_CLAUSE(21_4_8_1_c);
1107   TEST_CLAUSE(21_4_8_1_d);
1108   TEST_CLAUSE(21_4_8_1_e);
1109   TEST_CLAUSE(21_4_8_1_f);
1110   TEST_CLAUSE(21_4_8_1_g);
1111   TEST_CLAUSE(21_4_8_1_h);
1112   TEST_CLAUSE(21_4_8_1_i);
1113   TEST_CLAUSE(21_4_8_1_j);
1114   TEST_CLAUSE(21_4_8_1_k);
1115   TEST_CLAUSE(21_4_8_1_l);
1116   TEST_CLAUSE(21_4_8_9_a);
1117 }
1118
1119 TEST(FBString, testGetline) {
1120   fbstring s1 = "\
1121 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan \n\
1122 elit ut urna consectetur in sagittis mi auctor. Nulla facilisi. In nec \n\
1123 dolor leo, vitae imperdiet neque. Donec ut erat mauris, a faucibus \n\
1124 elit. Integer consectetur gravida augue, sit amet mattis mauris auctor \n\
1125 sed. Morbi congue libero eu nunc sodales adipiscing. In lectus nunc, \n\
1126 vulputate a fringilla at, venenatis quis justo. Proin eu velit \n\
1127 nibh. Maecenas vitae tellus eros. Pellentesque habitant morbi \n\
1128 tristique senectus et netus et malesuada fames ac turpis \n\
1129 egestas. Vivamus faucibus feugiat consequat. Donec fermentum neque sit \n\
1130 amet ligula suscipit porta. Phasellus facilisis felis in purus luctus \n\
1131 quis posuere leo tempor. Nam nunc purus, luctus a pharetra ut, \n\
1132 placerat at dui. Donec imperdiet, diam quis convallis pulvinar, dui \n\
1133 est commodo lorem, ut tincidunt diam nibh et nibh. Maecenas nec velit \n\
1134 massa, ut accumsan magna. Donec imperdiet tempor nisi et \n\
1135 laoreet. Phasellus lectus quam, ultricies ut tincidunt in, dignissim \n\
1136 id eros. Mauris vulputate tortor nec neque pellentesque sagittis quis \n\
1137 sed nisl. In diam lacus, lobortis ut posuere nec, ornare id quam.";
1138   char f[] = "/tmp/fbstring_testing.XXXXXX";
1139   int fd = mkstemp(f);
1140   EXPECT_TRUE(fd > 0);
1141   if (fd > 0) {
1142     close(fd);  // Yeah
1143     std::ofstream out(f);
1144     if (!(out << s1)) {
1145       EXPECT_TRUE(0) << "Couldn't write to temp file.";
1146       return;
1147     }
1148   }
1149   vector<fbstring> v;
1150   boost::split(v, s1, boost::is_any_of("\n"));
1151   {
1152     ifstream input(f);
1153     fbstring line;
1154     FOR_EACH (i, v) {
1155       EXPECT_TRUE(!getline(input, line).fail());
1156       EXPECT_EQ(line, *i);
1157     }
1158   }
1159   unlink(f);
1160 }
1161
1162 TEST(FBString, testMoveCtor) {
1163   // Move constructor. Make sure we allocate a large string, so the
1164   // small string optimization doesn't kick in.
1165   auto size = random(100, 2000);
1166   fbstring s(size, 'a');
1167   fbstring test = std::move(s);
1168   EXPECT_TRUE(s.empty());
1169   EXPECT_EQ(size, test.size());
1170 }
1171
1172 TEST(FBString, testMoveAssign) {
1173   // Move constructor. Make sure we allocate a large string, so the
1174   // small string optimization doesn't kick in.
1175   auto size = random(100, 2000);
1176   fbstring s(size, 'a');
1177   fbstring test;
1178   test = std::move(s);
1179   EXPECT_TRUE(s.empty());
1180   EXPECT_EQ(size, test.size());
1181 }
1182
1183 TEST(FBString, testMoveOperatorPlusLhs) {
1184   // Make sure we allocate a large string, so the
1185   // small string optimization doesn't kick in.
1186   auto size1 = random(100, 2000);
1187   auto size2 = random(100, 2000);
1188   fbstring s1(size1, 'a');
1189   fbstring s2(size2, 'b');
1190   fbstring test;
1191   test = std::move(s1) + s2;
1192   EXPECT_TRUE(s1.empty());
1193   EXPECT_EQ(size1 + size2, test.size());
1194 }
1195
1196 TEST(FBString, testMoveOperatorPlusRhs) {
1197   // Make sure we allocate a large string, so the
1198   // small string optimization doesn't kick in.
1199   auto size1 = random(100, 2000);
1200   auto size2 = random(100, 2000);
1201   fbstring s1(size1, 'a');
1202   fbstring s2(size2, 'b');
1203   fbstring test;
1204   test = s1 + std::move(s2);
1205   EXPECT_EQ(size1 + size2, test.size());
1206 }
1207
1208 // The GNU C++ standard library throws an std::logic_error when an std::string
1209 // is constructed with a null pointer. Verify that we mirror this behavior.
1210 //
1211 // N.B. We behave this way even if the C++ library being used is something
1212 //      other than libstdc++. Someday if we deem it important to present
1213 //      identical undefined behavior for other platforms, we can re-visit this.
1214 TEST(FBString, testConstructionFromLiteralZero) {
1215   EXPECT_THROW(fbstring s(0), std::logic_error);
1216 }
1217
1218 TEST(FBString, testFixedBugs) {
1219   { // D479397
1220     fbstring str(1337, 'f');
1221     fbstring cp = str;
1222     cp.clear();
1223     cp.c_str();
1224     EXPECT_EQ(str.front(), 'f');
1225   }
1226   { // D481173
1227     fbstring str(1337, 'f');
1228     for (int i = 0; i < 2; ++i) {
1229       fbstring cp = str;
1230       cp[1] = 'b';
1231       EXPECT_EQ(cp.c_str()[cp.size()], '\0');
1232       cp.push_back('?');
1233     }
1234   }
1235   { // D580267
1236     {
1237       fbstring str(1337, 'f');
1238       fbstring cp = str;
1239       cp.push_back('f');
1240     }
1241     {
1242       fbstring str(1337, 'f');
1243       fbstring cp = str;
1244       cp += "bb";
1245     }
1246   }
1247   { // D661622
1248     folly::basic_fbstring<wchar_t> s;
1249     EXPECT_EQ(0, s.size());
1250   }
1251   { // D785057
1252     fbstring str(1337, 'f');
1253     std::swap(str, str);
1254     EXPECT_EQ(1337, str.size());
1255   }
1256   { // D1012196, --allocator=malloc
1257     fbstring str(128, 'f');
1258     str.clear();  // Empty medium string.
1259     fbstring copy(str);  // Medium string of 0 capacity.
1260     copy.push_back('b');
1261     EXPECT_GE(copy.capacity(), 1);
1262   }
1263 }
1264
1265 TEST(FBString, findWithNpos) {
1266   fbstring fbstr("localhost:80");
1267   EXPECT_EQ(fbstring::npos, fbstr.find(":", fbstring::npos));
1268 }
1269
1270 TEST(FBString, testHash) {
1271   fbstring a;
1272   fbstring b;
1273   a.push_back(0);
1274   a.push_back(1);
1275   b.push_back(0);
1276   b.push_back(2);
1277   std::hash<fbstring> hashfunc;
1278   EXPECT_NE(hashfunc(a), hashfunc(b));
1279 }
1280
1281 TEST(FBString, testFrontBack) {
1282   fbstring str("hello");
1283   EXPECT_EQ(str.front(), 'h');
1284   EXPECT_EQ(str.back(), 'o');
1285   str.front() = 'H';
1286   EXPECT_EQ(str.front(), 'H');
1287   str.back() = 'O';
1288   EXPECT_EQ(str.back(), 'O');
1289   EXPECT_EQ(str, "HellO");
1290 }
1291
1292 TEST(FBString, noexcept) {
1293   EXPECT_TRUE(noexcept(fbstring()));
1294   fbstring x;
1295   EXPECT_FALSE(noexcept(fbstring(x)));
1296   EXPECT_TRUE(noexcept(fbstring(std::move(x))));
1297   fbstring y;
1298   EXPECT_FALSE(noexcept(y = x));
1299   EXPECT_TRUE(noexcept(y = std::move(x)));
1300 }
1301
1302 TEST(FBString, iomanip) {
1303   stringstream ss;
1304   fbstring fbstr("Hello");
1305
1306   ss << setw(6) << fbstr;
1307   EXPECT_EQ(ss.str(), " Hello");
1308   ss.str("");
1309
1310   ss << left << setw(6) << fbstr;
1311   EXPECT_EQ(ss.str(), "Hello ");
1312   ss.str("");
1313
1314   ss << right << setw(6) << fbstr;
1315   EXPECT_EQ(ss.str(), " Hello");
1316   ss.str("");
1317
1318   ss << setw(4) << fbstr;
1319   EXPECT_EQ(ss.str(), "Hello");
1320   ss.str("");
1321
1322   ss << setfill('^') << setw(6) << fbstr;
1323   EXPECT_EQ(ss.str(), "^Hello");
1324   ss.str("");
1325 }
1326
1327 TEST(FBString, rvalueIterators) {
1328   // you cannot take &* of a move-iterator, so use that for testing
1329   fbstring s = "base";
1330   fbstring r = "hello";
1331   r.replace(r.begin(), r.end(),
1332       make_move_iterator(s.begin()), make_move_iterator(s.end()));
1333   EXPECT_EQ("base", r);
1334
1335   // The following test is probably not required by the standard.
1336   // i.e. this could be in the realm of undefined behavior.
1337   fbstring b = "123abcXYZ";
1338   auto ait = b.begin() + 3;
1339   auto Xit = b.begin() + 6;
1340   b.replace(ait, b.end(), b.begin(), Xit);
1341   EXPECT_EQ("123123abc", b); // if things go wrong, you'd get "123123123"
1342 }
1343
1344 TEST(FBString, moveTerminator) {
1345   // The source of a move must remain in a valid state
1346   fbstring s(100, 'x'); // too big to be in-situ
1347   fbstring k;
1348   k = std::move(s);
1349
1350   EXPECT_EQ(0, s.size());
1351   EXPECT_EQ('\0', *s.c_str());
1352 }
1353
1354 int main(int argc, char** argv) {
1355   testing::InitGoogleTest(&argc, argv);
1356   gflags::ParseCommandLineFlags(&argc, &argv, true);
1357   return RUN_ALL_TESTS();
1358 }