Bring fbstring::operator+ to date with C++11
[folly.git] / folly / test / FBStringTest.cpp
index 428bed28fd33d6e5d55493b918d43ba1375711a7..2e2a9617011bd7c2f96a70babbefb3313fab24c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2014 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 //
 // Author: andrei.alexandrescu@fb.com
 
-#include "folly/FBString.h"
+#include <folly/FBString.h>
 
 #include <cstdlib>
 
 #include <list>
 #include <fstream>
+#include <iomanip>
 #include <boost/algorithm/string.hpp>
 #include <boost/random.hpp>
 #include <gtest/gtest.h>
 
 #include <gflags/gflags.h>
 
-#include "folly/Foreach.h"
-#include "folly/Random.h"
+#include <folly/Foreach.h>
+#include <folly/Portability.h>
+#include <folly/Random.h>
+#include <folly/Conv.h>
 
 using namespace std;
 using namespace folly;
@@ -58,9 +61,9 @@ void randomString(String* toFill, unsigned int maxSize = 1000) {
 
 template <class String, class Integral>
 void Num2String(String& str, Integral n) {
-  str.resize(30, '\0');
-  sprintf(&str[0], "%lu", static_cast<unsigned long>(n));
-  str.resize(strlen(str.c_str()));
+
+  std::string tmp = folly::to<std::string>(n);
+  str = String(tmp.begin(), tmp.end());
 }
 
 std::list<char> RandomList(unsigned int maxSize) {
@@ -76,55 +79,94 @@ std::list<char> RandomList(unsigned int maxSize) {
 // Tests begin here
 ////////////////////////////////////////////////////////////////////////////////
 
-template <class String> void clause_21_3_1_a(String & test) {
+template <class String> void clause11_21_4_2_a(String & test) {
   test.String::~String();
   new(&test) String();
 }
-template <class String> void clause_21_3_1_b(String & test) {
-  // Copy constructor
+template <class String> void clause11_21_4_2_b(String & test) {
+  String test2(test);
+  assert(test2 == test);
+}
+template <class String> void clause11_21_4_2_c(String & test) {
+  // Test move constructor. There is a more specialized test, see
+  // TEST(FBString, testMoveCtor)
+  String donor(test);
+  String test2(std::move(donor));
+  EXPECT_EQ(test2, test);
+  // Technically not required, but all implementations that actually
+  // support move will move large strings. Make a guess for 128 as the
+  // maximum small string optimization that's reasonable.
+  EXPECT_LE(donor.size(), 128);
+}
+template <class String> void clause11_21_4_2_d(String & test) {
+  // Copy constructor with position and length
   const size_t pos = random(0, test.size());
-  String s(test, pos, random(0, (size_t)(test.size() - pos)));
+  String s(test, pos, random(0, 9)
+           ? random(0, (size_t)(test.size() - pos))
+           : String::npos); // test for npos, too, in 10% of the cases
   test = s;
 }
-template <class String> void clause_21_3_1_c(String & test) {
+template <class String> void clause11_21_4_2_e(String & test) {
   // Constructor from char*, size_t
   const size_t
     pos = random(0, test.size()),
     n = random(0, test.size() - pos);
-  std::string before(test.data(), test.size());
+  String before(test.data(), test.size());
   String s(test.c_str() + pos, n);
-  std::string after(test.data(), test.size());
+  String after(test.data(), test.size());
   EXPECT_EQ(before, after);
-
+  test.swap(s);
+}
+template <class String> void clause11_21_4_2_f(String & test) {
+  // Constructor from char*
+  const size_t
+    pos = random(0, test.size()),
+    n = random(0, test.size() - pos);
+  String before(test.data(), test.size());
+  String s(test.c_str() + pos);
+  String after(test.data(), test.size());
+  EXPECT_EQ(before, after);
+  test.swap(s);
+}
+template <class String> void clause11_21_4_2_g(String & test) {
+  // Constructor from size_t, char
+  const size_t n = random(0, test.size());
+  const auto c = test.front();
+  test = String(n, c);
+}
+template <class String> void clause11_21_4_2_h(String & test) {
+  // Constructors from various iterator pairs
   // Constructor from char*, char*
   String s1(test.begin(), test.end());
   EXPECT_EQ(test, s1);
   String s2(test.data(), test.data() + test.size());
   EXPECT_EQ(test, s2);
-
-  // Constructor from iterators
+  // Constructor from other iterators
   std::list<char> lst;
   for (auto c : test) lst.push_back(c);
   String s3(lst.begin(), lst.end());
   EXPECT_EQ(test, s3);
-
   // Constructor from wchar_t iterators
   std::list<wchar_t> lst1;
   for (auto c : test) lst1.push_back(c);
   String s4(lst1.begin(), lst1.end());
   EXPECT_EQ(test, s4);
-
   // Constructor from wchar_t pointers
   wchar_t t[20];
   t[0] = 'a';
   t[1] = 'b';
-  String s5(t, t + 2);;
+  fbstring s5(t, t + 2);;
   EXPECT_EQ("ab", s5);
-
-  test = s;
 }
-template <class String> void clause_21_3_1_d(String & test) {
-  // Assignment
+template <class String> void clause11_21_4_2_i(String & test) {
+  // From initializer_list<char>
+  std::initializer_list<typename String::value_type>
+    il = { 'h', 'e', 'l', 'l', 'o' };
+  String s(il);
+  test.swap(s);
+}
+template <class String> void clause11_21_4_2_j(String & test) {
+  // Assignment from const String&
   auto size = random(0, 2000);
   String s(size, '\0');
   EXPECT_EQ(s.size(), size);
@@ -133,7 +175,20 @@ template <class String> void clause_21_3_1_d(String & test) {
   }
   test = s;
 }
-template <class String> void clause_21_3_1_e(String & test) {
+template <class String> void clause11_21_4_2_k(String & test) {
+  // Assignment from String&&
+  auto size = random(0, 2000);
+  String s(size, '\0');
+  EXPECT_EQ(s.size(), size);
+  FOR_EACH_RANGE (i, 0, s.size()) {
+    s[i] = random('a', 'z');
+  }
+  test = std::move(s);
+  if (typeid(String) == typeid(fbstring)) {
+    EXPECT_LE(s.size(), 128);
+  }
+}
+template <class String> void clause11_21_4_2_l(String & test) {
   // Assignment from char*
   String s(random(0, 1000), '\0');
   size_t i = 0;
@@ -142,7 +197,7 @@ template <class String> void clause_21_3_1_e(String & test) {
   }
   test = s.c_str();
 }
-template <class String> void clause_21_3_1_f(String & test) {
+template <class String> void clause11_21_4_2_lprime(String & test) {
   // Aliased assign
   const size_t pos = random(0, test.size());
   if (avoidAliasing) {
@@ -151,15 +206,23 @@ template <class String> void clause_21_3_1_f(String & test) {
     test = test.c_str() + pos;
   }
 }
-template <class String> void clause_21_3_1_g(String & test) {
+template <class String> void clause11_21_4_2_m(String & test) {
   // Assignment from char
   test = random('a', 'z');
 }
+template <class String> void clause11_21_4_2_n(String & test) {
+  // Assignment from initializer_list<char>
+  initializer_list<typename String::value_type>
+    il = { 'h', 'e', 'l', 'l', 'o' };
+  test = il;
+}
 
-template <class String> void clause_21_3_2(String & test) {
+template <class String> void clause11_21_4_3(String & test) {
   // Iterators. The code below should leave test unchanged
   EXPECT_EQ(test.size(), test.end() - test.begin());
   EXPECT_EQ(test.size(), test.rend() - test.rbegin());
+  EXPECT_EQ(test.size(), test.cend() - test.cbegin());
+  EXPECT_EQ(test.size(), test.crend() - test.crbegin());
 
   auto s = test.size();
   test.resize(test.end() - test.begin());
@@ -168,31 +231,44 @@ template <class String> void clause_21_3_2(String & test) {
   EXPECT_EQ(s, test.size());
 }
 
-template <class String> void clause_21_3_3(String & test) {
+template <class String> void clause11_21_4_4(String & test) {
   // exercise capacity, size, max_size
   EXPECT_EQ(test.size(), test.length());
   EXPECT_LE(test.size(), test.max_size());
   EXPECT_LE(test.capacity(), test.max_size());
   EXPECT_LE(test.size(), test.capacity());
+
+  // exercise shrink_to_fit. Nonbinding request so we can't really do
+  // much beyond calling it.
+  auto copy = test;
+  copy.reserve(copy.capacity() * 3);
+  copy.shrink_to_fit();
+  EXPECT_EQ(copy, test);
+
   // exercise empty
-  if (test.empty()) test = "empty";
-  else test = "not empty";
+  string empty("empty");
+  string notempty("not empty");
+  if (test.empty()) test = String(empty.begin(), empty.end());
+  else test = String(notempty.begin(), notempty.end());
 }
 
-template <class String> void clause_21_3_4(String & test) {
-  // exercise element access 21.3.4
+template <class String> void clause11_21_4_5(String & test) {
+  // exercise element access
   if (!test.empty()) {
+    EXPECT_EQ(test[0], test.front());
+    EXPECT_EQ(test[test.size() - 1], test.back());
     auto const i = random(0, test.size() - 1);
     EXPECT_EQ(test[i], test.at(i));
     test = test[i];
   }
 }
 
-template <class String> void clause_21_3_5_a(String & test) {
+template <class String> void clause11_21_4_6_1(String & test) {
   // 21.3.5 modifiers (+=)
   String test1;
   randomString(&test1);
-  assert(test1.size() == strlen(test1.c_str()));
+  assert(test1.size() == char_traits
+      <typename String::value_type>::length(test1.c_str()));
   auto len = test.size();
   test += test1;
   EXPECT_EQ(test.size(), test1.size() + len);
@@ -206,20 +282,24 @@ template <class String> void clause_21_3_5_a(String & test) {
   len = test.size();
   EXPECT_EQ(memcmp(sz, dt, len), 0);
   String copy(test.data(), test.size());
-  EXPECT_EQ(strlen(test.c_str()), len);
+  EXPECT_EQ(char_traits
+      <typename String::value_type>::length(test.c_str()), len);
   test += test;
   //test.append(test);
   EXPECT_EQ(test.size(), 2 * len);
-  EXPECT_EQ(strlen(test.c_str()), 2 * len);
+  EXPECT_EQ(char_traits
+      <typename String::value_type>::length(test.c_str()), 2 * len);
   FOR_EACH_RANGE (i, 0, len) {
     EXPECT_EQ(test[i], copy[i]);
     EXPECT_EQ(test[i], test[len + i]);
   }
   len = test.size();
-  EXPECT_EQ(strlen(test.c_str()), len);
+  EXPECT_EQ(char_traits
+      <typename String::value_type>::length(test.c_str()), len);
   // more aliasing
   auto const pos = random(0, test.size());
-  EXPECT_EQ(strlen(test.c_str() + pos), len - pos);
+  EXPECT_EQ(char_traits
+      <typename String::value_type>::length(test.c_str() + pos), len - pos);
   if (avoidAliasing) {
     String addMe(test.c_str() + pos);
     EXPECT_EQ(addMe.size(), len - pos);
@@ -232,9 +312,12 @@ template <class String> void clause_21_3_5_a(String & test) {
   len = test.size();
   test += random('a', 'z');
   EXPECT_EQ(test.size(), len + 1);
+  // initializer_list
+  initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
+  test += il;
 }
 
-template <class String> void clause_21_3_5_b(String & test) {
+template <class String> void clause11_21_4_6_2(String & test) {
   // 21.3.5 modifiers (append, push_back)
   String s;
 
@@ -259,70 +342,85 @@ template <class String> void clause_21_3_5_b(String & test) {
   c = random('a', 'z');
   test.push_back(c);
   EXPECT_EQ(test[test.size() - 1], c);
+  // initializer_list
+  initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
+  test.append(il);
 }
 
-template <class String> void clause_21_3_5_c(String & test) {
+template <class String> void clause11_21_4_6_3_a(String & test) {
   // assign
   String s;
   randomString(&s);
   test.assign(s);
+  EXPECT_EQ(test, s);
+  // move assign
+  test.assign(std::move(s));
+  if (typeid(String) == typeid(fbstring)) {
+    EXPECT_LE(s.size(), 128);
+  }
 }
 
-template <class String> void clause_21_3_5_d(String & test) {
+template <class String> void clause11_21_4_6_3_b(String & test) {
   // assign
   String s;
   randomString(&s, maxString);
   test.assign(s, random(0, s.size()), random(0, maxString));
 }
 
-template <class String> void clause_21_3_5_e(String & test) {
+template <class String> void clause11_21_4_6_3_c(String & test) {
   // assign
   String s;
   randomString(&s, maxString);
   test.assign(s.c_str(), random(0, s.size()));
 }
 
-template <class String> void clause_21_3_5_f(String & test) {
+template <class String> void clause11_21_4_6_3_d(String & test) {
   // assign
   String s;
   randomString(&s, maxString);
   test.assign(s.c_str());
 }
 
-template <class String> void clause_21_3_5_g(String & test) {
+template <class String> void clause11_21_4_6_3_e(String & test) {
   // assign
   String s;
   randomString(&s, maxString);
   test.assign(random(0, maxString), random('a', 'z'));
 }
 
-template <class String> void clause_21_3_5_h(String & test) {
+template <class String> void clause11_21_4_6_3_f(String & test) {
   // assign from bidirectional iterator
   std::list<char> lst(RandomList(maxString));
   test.assign(lst.begin(), lst.end());
 }
 
-template <class String> void clause_21_3_5_i(String & test) {
+template <class String> void clause11_21_4_6_3_g(String & test) {
   // assign from aliased source
   test.assign(test);
 }
 
-template <class String> void clause_21_3_5_j(String & test) {
+template <class String> void clause11_21_4_6_3_h(String & test) {
   // assign from aliased source
   test.assign(test, random(0, test.size()), random(0, maxString));
 }
 
-template <class String> void clause_21_3_5_k(String & test) {
+template <class String> void clause11_21_4_6_3_i(String & test) {
   // assign from aliased source
   test.assign(test.c_str(), random(0, test.size()));
 }
 
-template <class String> void clause_21_3_5_l(String & test) {
+template <class String> void clause11_21_4_6_3_j(String & test) {
   // assign from aliased source
   test.assign(test.c_str());
 }
 
-template <class String> void clause_21_3_5_m(String & test) {
+template <class String> void clause11_21_4_6_3_k(String & test) {
+  // assign from initializer_list
+  initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
+  test.assign(il);
+}
+
+template <class String> void clause11_21_4_6_4(String & test) {
   // insert
   String s;
   randomString(&s, maxString);
@@ -338,15 +436,29 @@ template <class String> void clause_21_3_5_m(String & test) {
   test.insert(random(0, test.size()), s.c_str());
   test.insert(random(0, test.size()),
               random(0, maxString), random('a', 'z'));
-  test.insert(test.begin() + random(0, test.size()),
-              random('a', 'z'));
+  typename String::size_type pos = random(0, test.size());
+  typename String::iterator res =
+    test.insert(test.begin() + pos, random('a', 'z'));
+  EXPECT_EQ(res - test.begin(), pos);
   std::list<char> lst(RandomList(maxString));
-  test.insert(test.begin() + random(0, test.size()),
-              lst.begin(), lst.end());
+  pos = random(0, test.size());
+  // Uncomment below to see a bug in gcc
+  /*res = */test.insert(test.begin() + pos, lst.begin(), lst.end());
+  // insert from initializer_list
+  initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
+  pos = random(0, test.size());
+  // Uncomment below to see a bug in gcc
+  /*res = */test.insert(test.begin() + pos, il);
+
+  // Test with actual input iterators
+  stringstream ss;
+  ss << "hello cruel world";
+  auto i = istream_iterator<char>(ss);
+  test.insert(test.begin(), i, istream_iterator<char>());
 }
 
-template <class String> void clause_21_3_5_n(String & test) {
-  // erase
+template <class String> void clause11_21_4_6_5(String & test) {
+  // erase and pop_back
   if (!test.empty()) {
     test.erase(random(0, test.size()), random(0, maxString));
   }
@@ -360,9 +472,13 @@ template <class String> void clause_21_3_5_n(String & test) {
       test.erase(i, i + random(0, size_t(test.end() - i)));
     }
   }
+  if (!test.empty()) {
+    // Can't test pop_back with std::string, doesn't support it yet.
+    //test.pop_back();
+  }
 }
 
-template <class String> void clause_21_3_5_o(String & test) {
+template <class String> void clause11_21_4_6_6(String & test) {
   auto pos = random(0, test.size());
   if (avoidAliasing) {
     test.replace(pos, random(0, test.size() - pos),
@@ -411,10 +527,11 @@ template <class String> void clause_21_3_5_o(String & test) {
                random(0, maxString), random('a', 'z'));
   pos = random(0, test.size());
   if (avoidAliasing) {
+    auto newString = String(test);
     test.replace(
       test.begin() + pos,
       test.begin() + pos + random(0, test.size() - pos),
-      String(test));
+      newString);
   } else {
     test.replace(
       test.begin() + pos,
@@ -423,10 +540,11 @@ template <class String> void clause_21_3_5_o(String & test) {
   }
   pos = random(0, test.size());
   if (avoidAliasing) {
+    auto newString = String(test);
     test.replace(
       test.begin() + pos,
       test.begin() + pos + random(0, test.size() - pos),
-      String(test).c_str(),
+      newString.c_str(),
       test.size() - random(0, test.size()));
   } else {
     test.replace(
@@ -453,7 +571,7 @@ template <class String> void clause_21_3_5_o(String & test) {
     random(0, maxString), random('a', 'z'));
 }
 
-template <class String> void clause_21_3_5_p(String & test) {
+template <class String> void clause11_21_4_6_7(String & test) {
   std::vector<typename String::value_type>
     vec(random(0, maxString));
   test.copy(
@@ -462,13 +580,13 @@ template <class String> void clause_21_3_5_p(String & test) {
     random(0, test.size()));
 }
 
-template <class String> void clause_21_3_5_q(String & test) {
+template <class String> void clause11_21_4_6_8(String & test) {
   String s;
   randomString(&s, maxString);
   s.swap(test);
 }
 
-template <class String> void clause_21_3_6_a(String & test) {
+template <class String> void clause11_21_4_7_1(String & test) {
   // 21.3.6 string operations
   // exercise c_str() and data()
   assert(test.c_str() == test.data());
@@ -478,14 +596,29 @@ template <class String> void clause_21_3_6_a(String & test) {
   assert(test.get_allocator() == s.get_allocator());
 }
 
-template <class String> void clause_21_3_6_b(String & test) {
+template <class String> void clause11_21_4_7_2_a(String & test) {
   String str = test.substr(
     random(0, test.size()),
     random(0, test.size()));
   Num2String(test, test.find(str, random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_c(String & test) {
+template <class String> void clause11_21_4_7_2_a1(String & test) {
+  String str = String(test).substr(
+    random(0, test.size()),
+    random(0, test.size()));
+  Num2String(test, test.find(str, random(0, test.size())));
+}
+
+template <class String> void clause11_21_4_7_2_a2(String & test) {
+  auto const& cTest = test;
+  String str = cTest.substr(
+    random(0, test.size()),
+    random(0, test.size()));
+  Num2String(test, test.find(str, random(0, test.size())));
+}
+
+template <class String> void clause11_21_4_7_2_b(String & test) {
   auto from = random(0, test.size());
   auto length = random(0, test.size() - from);
   String str = test.substr(from, length);
@@ -494,7 +627,26 @@ template <class String> void clause_21_3_6_c(String & test) {
                              random(0, str.size())));
 }
 
-template <class String> void clause_21_3_6_d(String & test) {
+template <class String> void clause11_21_4_7_2_b1(String & test) {
+  auto from = random(0, test.size());
+  auto length = random(0, test.size() - from);
+  String str = String(test).substr(from, length);
+  Num2String(test, test.find(str.c_str(),
+                             random(0, test.size()),
+                             random(0, str.size())));
+}
+
+template <class String> void clause11_21_4_7_2_b2(String & test) {
+  auto from = random(0, test.size());
+  auto length = random(0, test.size() - from);
+  const auto& cTest = test;
+  String str = cTest.substr(from, length);
+  Num2String(test, test.find(str.c_str(),
+                             random(0, test.size()),
+                             random(0, str.size())));
+}
+
+template <class String> void clause11_21_4_7_2_c(String & test) {
   String str = test.substr(
     random(0, test.size()),
     random(0, test.size()));
@@ -502,20 +654,37 @@ template <class String> void clause_21_3_6_d(String & test) {
                              random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_e(String & test) {
+template <class String> void clause11_21_4_7_2_c1(String & test) {
+  String str = String(test).substr(
+    random(0, test.size()),
+    random(0, test.size()));
+  Num2String(test, test.find(str.c_str(),
+                             random(0, test.size())));
+}
+
+template <class String> void clause11_21_4_7_2_c2(String & test) {
+  const auto& cTest = test;
+  String str = cTest.substr(
+    random(0, test.size()),
+    random(0, test.size()));
+  Num2String(test, test.find(str.c_str(),
+                             random(0, test.size())));
+}
+
+template <class String> void clause11_21_4_7_2_d(String & test) {
   Num2String(test, test.find(
                random('a', 'z'),
                random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_f(String & test) {
+template <class String> void clause11_21_4_7_3_a(String & test) {
   String str = test.substr(
     random(0, test.size()),
     random(0, test.size()));
   Num2String(test, test.rfind(str, random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_g(String & test) {
+template <class String> void clause11_21_4_7_3_b(String & test) {
   String str = test.substr(
     random(0, test.size()),
     random(0, test.size()));
@@ -524,7 +693,7 @@ template <class String> void clause_21_3_6_g(String & test) {
                               random(0, str.size())));
 }
 
-template <class String> void clause_21_3_6_h(String & test) {
+template <class String> void clause11_21_4_7_3_c(String & test) {
   String str = test.substr(
     random(0, test.size()),
     random(0, test.size()));
@@ -532,20 +701,20 @@ template <class String> void clause_21_3_6_h(String & test) {
                               random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_i(String & test) {
+template <class String> void clause11_21_4_7_3_d(String & test) {
   Num2String(test, test.rfind(
                random('a', 'z'),
                random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_j(String & test) {
+template <class String> void clause11_21_4_7_4_a(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_first_of(str,
                                       random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_k(String & test) {
+template <class String> void clause11_21_4_7_4_b(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_first_of(str.c_str(),
@@ -553,27 +722,27 @@ template <class String> void clause_21_3_6_k(String & test) {
                                       random(0, str.size())));
 }
 
-template <class String> void clause_21_3_6_l(String & test) {
+template <class String> void clause11_21_4_7_4_c(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_first_of(str.c_str(),
                                       random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_m(String & test) {
+template <class String> void clause11_21_4_7_4_d(String & test) {
   Num2String(test, test.find_first_of(
                random('a', 'z'),
                random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_n(String & test) {
+template <class String> void clause11_21_4_7_5_a(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_last_of(str,
                                      random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_o(String & test) {
+template <class String> void clause11_21_4_7_5_b(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_last_of(str.c_str(),
@@ -581,27 +750,27 @@ template <class String> void clause_21_3_6_o(String & test) {
                                      random(0, str.size())));
 }
 
-template <class String> void clause_21_3_6_p(String & test) {
+template <class String> void clause11_21_4_7_5_c(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_last_of(str.c_str(),
                                      random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_q(String & test) {
+template <class String> void clause11_21_4_7_5_d(String & test) {
   Num2String(test, test.find_last_of(
                random('a', 'z'),
                random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_r(String & test) {
+template <class String> void clause11_21_4_7_6_a(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_first_not_of(str,
                                           random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_s(String & test) {
+template <class String> void clause11_21_4_7_6_b(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_first_not_of(str.c_str(),
@@ -609,27 +778,27 @@ template <class String> void clause_21_3_6_s(String & test) {
                                           random(0, str.size())));
 }
 
-template <class String> void clause_21_3_6_t(String & test) {
+template <class String> void clause11_21_4_7_6_c(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_first_not_of(str.c_str(),
                                           random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_u(String & test) {
+template <class String> void clause11_21_4_7_6_d(String & test) {
   Num2String(test, test.find_first_not_of(
                random('a', 'z'),
                random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_v(String & test) {
+template <class String> void clause11_21_4_7_7_a(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_last_not_of(str,
                                          random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_w(String & test) {
+template <class String> void clause11_21_4_7_7_b(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_last_not_of(str.c_str(),
@@ -637,24 +806,24 @@ template <class String> void clause_21_3_6_w(String & test) {
                                          random(0, str.size())));
 }
 
-template <class String> void clause_21_3_6_x(String & test) {
+template <class String> void clause11_21_4_7_7_c(String & test) {
   String str;
   randomString(&str, maxString);
   Num2String(test, test.find_last_not_of(str.c_str(),
                                          random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_y(String & test) {
+template <class String> void clause11_21_4_7_7_d(String & test) {
   Num2String(test, test.find_last_not_of(
                random('a', 'z'),
                random(0, test.size())));
 }
 
-template <class String> void clause_21_3_6_z(String & test) {
+template <class String> void clause11_21_4_7_8(String & test) {
   test = test.substr(random(0, test.size()), random(0, test.size()));
 }
 
-template <class String> void clause_21_3_7_a(String & test) {
+template <class String> void clause11_21_4_7_9_a(String & test) {
   String s;
   randomString(&s, maxString);
   int tristate = test.compare(s);
@@ -663,7 +832,7 @@ template <class String> void clause_21_3_7_a(String & test) {
   Num2String(test, tristate);
 }
 
-template <class String> void clause_21_3_7_b(String & test) {
+template <class String> void clause11_21_4_7_9_b(String & test) {
   String s;
   randomString(&s, maxString);
   int tristate = test.compare(
@@ -675,7 +844,7 @@ template <class String> void clause_21_3_7_b(String & test) {
   Num2String(test, tristate);
 }
 
-template <class String> void clause_21_3_7_c(String & test) {
+template <class String> void clause11_21_4_7_9_c(String & test) {
   String str;
   randomString(&str, maxString);
   int tristate = test.compare(
@@ -689,7 +858,7 @@ template <class String> void clause_21_3_7_c(String & test) {
   Num2String(test, tristate);
 }
 
-template <class String> void clause_21_3_7_d(String & test) {
+template <class String> void clause11_21_4_7_9_d(String & test) {
   String s;
   randomString(&s, maxString);
   int tristate = test.compare(s.c_str());
@@ -698,7 +867,7 @@ template <class String> void clause_21_3_7_d(String & test) {
                 Num2String(test, tristate);
 }
 
-template <class String> void clause_21_3_7_e(String & test) {
+template <class String> void clause11_21_4_7_9_e(String & test) {
   String str;
   randomString(&str, maxString);
   int tristate = test.compare(
@@ -711,7 +880,7 @@ template <class String> void clause_21_3_7_e(String & test) {
   Num2String(test, tristate);
 }
 
-template <class String> void clause_21_3_7_f(String & test) {
+template <class String> void clause11_21_4_8_1_a(String & test) {
   String s1;
   randomString(&s1, maxString);
   String s2;
@@ -719,7 +888,31 @@ template <class String> void clause_21_3_7_f(String & test) {
   test = s1 + s2;
 }
 
-template <class String> void clause_21_3_7_g(String & test) {
+template <class String> void clause11_21_4_8_1_b(String & test) {
+  String s1;
+  randomString(&s1, maxString);
+  String s2;
+  randomString(&s2, maxString);
+  test = move(s1) + s2;
+}
+
+template <class String> void clause11_21_4_8_1_c(String & test) {
+  String s1;
+  randomString(&s1, maxString);
+  String s2;
+  randomString(&s2, maxString);
+  test = s1 + move(s2);
+}
+
+template <class String> void clause11_21_4_8_1_d(String & test) {
+  String s1;
+  randomString(&s1, maxString);
+  String s2;
+  randomString(&s2, maxString);
+  test = move(s1) + move(s2);
+}
+
+template <class String> void clause11_21_4_8_1_e(String & test) {
   String s;
   randomString(&s, maxString);
   String s1;
@@ -727,13 +920,27 @@ template <class String> void clause_21_3_7_g(String & test) {
   test = s.c_str() + s1;
 }
 
-template <class String> void clause_21_3_7_h(String & test) {
+template <class String> void clause11_21_4_8_1_f(String & test) {
+  String s;
+  randomString(&s, maxString);
+  String s1;
+  randomString(&s1, maxString);
+  test = s.c_str() + move(s1);
+}
+
+template <class String> void clause11_21_4_8_1_g(String & test) {
   String s;
   randomString(&s, maxString);
   test = typename String::value_type(random('a', 'z')) + s;
 }
 
-template <class String> void clause_21_3_7_i(String & test) {
+template <class String> void clause11_21_4_8_1_h(String & test) {
+  String s;
+  randomString(&s, maxString);
+  test = typename String::value_type(random('a', 'z')) + move(s);
+}
+
+template <class String> void clause11_21_4_8_1_i(String & test) {
   String s;
   randomString(&s, maxString);
   String s1;
@@ -741,26 +948,34 @@ template <class String> void clause_21_3_7_i(String & test) {
   test = s + s1.c_str();
 }
 
-template <class String> void clause_21_3_7_j(String & test) {
+template <class String> void clause11_21_4_8_1_j(String & test) {
   String s;
   randomString(&s, maxString);
   String s1;
   randomString(&s1, maxString);
-  test = s + s1.c_str();
+  test = move(s) + s1.c_str();
 }
 
-template <class String> void clause_21_3_7_k(String & test) {
+template <class String> void clause11_21_4_8_1_k(String & test) {
   String s;
   randomString(&s, maxString);
   test = s + typename String::value_type(random('a', 'z'));
 }
 
+template <class String> void clause11_21_4_8_1_l(String & test) {
+  String s;
+  randomString(&s, maxString);
+  String s1;
+  randomString(&s1, maxString);
+  test = move(s) + s1.c_str();
+}
+
 // Numbering here is from C++11
-template <class String> void clause_21_4_8_9_a(String & test) {
-  stringstream s("asd asdfjhuhdf    asdfasdf\tasdsdf");
+template <class String> void clause11_21_4_8_9_a(String & test) {
+  basic_stringstream<typename String::value_type> stst(test.c_str());
   String str;
-  while (s) {
-    s >> str;
+  while (stst) {
+    stst >> str;
     test += str + test;
   }
 }
@@ -768,92 +983,136 @@ template <class String> void clause_21_4_8_9_a(String & test) {
 TEST(FBString, testAllClauses) {
   EXPECT_TRUE(1) << "Starting with seed: " << seed;
   std::string r;
+  std::wstring wr;
   folly::fbstring c;
-#define TEST_CLAUSE(x)                                              \
-  do {                                                              \
-      if (1) {} else EXPECT_TRUE(1) << "Testing clause " << #x;     \
-      randomString(&r);                                             \
-      c = r;                                                        \
-      EXPECT_EQ(c, r);                                              \
-      auto localSeed = seed + count;                                \
-      rng = RandomT(localSeed);                                     \
-      clause_##x(r);                                                \
-      rng = RandomT(localSeed);                                     \
-      clause_##x(c);                                                \
-      EXPECT_EQ(r, c)                                               \
-        << "Lengths: " << r.size() << " vs. " << c.size()           \
-        << "\nReference: '" << r << "'"                             \
-        << "\nActual:    '" << c.data()[0] << "'";                  \
-    } while (++count % 100 != 0)
-
+  folly::basic_fbstring<wchar_t> wc;
   int count = 0;
-  TEST_CLAUSE(21_3_1_a);
-  TEST_CLAUSE(21_3_1_b);
-  TEST_CLAUSE(21_3_1_c);
-  TEST_CLAUSE(21_3_1_d);
-  TEST_CLAUSE(21_3_1_e);
-  TEST_CLAUSE(21_3_1_f);
-  TEST_CLAUSE(21_3_1_g);
-
-  TEST_CLAUSE(21_3_2);
-  TEST_CLAUSE(21_3_3);
-  TEST_CLAUSE(21_3_4);
-  TEST_CLAUSE(21_3_5_a);
-  TEST_CLAUSE(21_3_5_b);
-  TEST_CLAUSE(21_3_5_c);
-  TEST_CLAUSE(21_3_5_d);
-  TEST_CLAUSE(21_3_5_e);
-  TEST_CLAUSE(21_3_5_f);
-  TEST_CLAUSE(21_3_5_g);
-  TEST_CLAUSE(21_3_5_h);
-  TEST_CLAUSE(21_3_5_i);
-  TEST_CLAUSE(21_3_5_j);
-  TEST_CLAUSE(21_3_5_k);
-  TEST_CLAUSE(21_3_5_l);
-  TEST_CLAUSE(21_3_5_m);
-  TEST_CLAUSE(21_3_5_n);
-  TEST_CLAUSE(21_3_5_o);
-  TEST_CLAUSE(21_3_5_p);
-
-  TEST_CLAUSE(21_3_6_a);
-  TEST_CLAUSE(21_3_6_b);
-  TEST_CLAUSE(21_3_6_c);
-  TEST_CLAUSE(21_3_6_d);
-  TEST_CLAUSE(21_3_6_e);
-  TEST_CLAUSE(21_3_6_f);
-  TEST_CLAUSE(21_3_6_g);
-  TEST_CLAUSE(21_3_6_h);
-  TEST_CLAUSE(21_3_6_i);
-  TEST_CLAUSE(21_3_6_j);
-  TEST_CLAUSE(21_3_6_k);
-  TEST_CLAUSE(21_3_6_l);
-  TEST_CLAUSE(21_3_6_m);
-  TEST_CLAUSE(21_3_6_n);
-  TEST_CLAUSE(21_3_6_o);
-  TEST_CLAUSE(21_3_6_p);
-  TEST_CLAUSE(21_3_6_q);
-  TEST_CLAUSE(21_3_6_r);
-  TEST_CLAUSE(21_3_6_s);
-  TEST_CLAUSE(21_3_6_t);
-  TEST_CLAUSE(21_3_6_u);
-  TEST_CLAUSE(21_3_6_v);
-  TEST_CLAUSE(21_3_6_w);
-  TEST_CLAUSE(21_3_6_x);
-  TEST_CLAUSE(21_3_6_y);
-  TEST_CLAUSE(21_3_6_z);
-
-  TEST_CLAUSE(21_3_7_a);
-  TEST_CLAUSE(21_3_7_b);
-  TEST_CLAUSE(21_3_7_c);
-  TEST_CLAUSE(21_3_7_d);
-  TEST_CLAUSE(21_3_7_e);
-  TEST_CLAUSE(21_3_7_f);
-  TEST_CLAUSE(21_3_7_g);
-  TEST_CLAUSE(21_3_7_h);
-  TEST_CLAUSE(21_3_7_i);
-  TEST_CLAUSE(21_3_7_j);
-  TEST_CLAUSE(21_3_7_k);
 
+  auto l = [&](const char * const clause,
+               void(*f_string)(std::string&),
+               void(*f_fbstring)(folly::fbstring&),
+               void(*f_wfbstring)(folly::basic_fbstring<wchar_t>&)) {
+    do {
+      if (1) {} else EXPECT_TRUE(1) << "Testing clause " << clause;
+      randomString(&r);
+      c = r;
+      EXPECT_EQ(c, r);
+      wr = std::wstring(r.begin(), r.end());
+      wc = folly::basic_fbstring<wchar_t>(wr.c_str());
+      auto localSeed = seed + count;
+      rng = RandomT(localSeed);
+      f_string(r);
+      rng = RandomT(localSeed);
+      f_fbstring(c);
+      EXPECT_EQ(r, c)
+        << "Lengths: " << r.size() << " vs. " << c.size()
+        << "\nReference: '" << r << "'"
+        << "\nActual:    '" << c.data()[0] << "'";
+      rng = RandomT(localSeed);
+      f_wfbstring(wc);
+      int wret = wcslen(wc.c_str());
+      char mb[wret+1];
+      int ret = wcstombs(mb, wc.c_str(), sizeof(mb));
+      if (ret == wret) mb[wret] = '\0';
+      const char *mc = c.c_str();
+      std::string one(mb);
+      std::string two(mc);
+      EXPECT_EQ(one, two);
+    } while (++count % 100 != 0);
+  };
+
+#define TEST_CLAUSE(x) \
+  l(#x, \
+    clause11_##x<std::string>, \
+    clause11_##x<folly::fbstring>, \
+    clause11_##x<folly::basic_fbstring<wchar_t>>);
+
+  TEST_CLAUSE(21_4_2_a);
+  TEST_CLAUSE(21_4_2_b);
+  TEST_CLAUSE(21_4_2_c);
+  TEST_CLAUSE(21_4_2_d);
+  TEST_CLAUSE(21_4_2_e);
+  TEST_CLAUSE(21_4_2_f);
+  TEST_CLAUSE(21_4_2_g);
+  TEST_CLAUSE(21_4_2_h);
+  TEST_CLAUSE(21_4_2_i);
+  TEST_CLAUSE(21_4_2_j);
+  TEST_CLAUSE(21_4_2_k);
+  TEST_CLAUSE(21_4_2_l);
+  TEST_CLAUSE(21_4_2_lprime);
+  TEST_CLAUSE(21_4_2_m);
+  TEST_CLAUSE(21_4_2_n);
+  TEST_CLAUSE(21_4_3);
+  TEST_CLAUSE(21_4_4);
+  TEST_CLAUSE(21_4_5);
+  TEST_CLAUSE(21_4_6_1);
+  TEST_CLAUSE(21_4_6_2);
+  TEST_CLAUSE(21_4_6_3_a);
+  TEST_CLAUSE(21_4_6_3_b);
+  TEST_CLAUSE(21_4_6_3_c);
+  TEST_CLAUSE(21_4_6_3_d);
+  TEST_CLAUSE(21_4_6_3_e);
+  TEST_CLAUSE(21_4_6_3_f);
+  TEST_CLAUSE(21_4_6_3_g);
+  TEST_CLAUSE(21_4_6_3_h);
+  TEST_CLAUSE(21_4_6_3_i);
+  TEST_CLAUSE(21_4_6_3_j);
+  TEST_CLAUSE(21_4_6_3_k);
+  TEST_CLAUSE(21_4_6_4);
+  TEST_CLAUSE(21_4_6_5);
+  TEST_CLAUSE(21_4_6_6);
+  TEST_CLAUSE(21_4_6_7);
+  TEST_CLAUSE(21_4_6_8);
+  TEST_CLAUSE(21_4_7_1);
+
+  TEST_CLAUSE(21_4_7_2_a);
+  TEST_CLAUSE(21_4_7_2_a1);
+  TEST_CLAUSE(21_4_7_2_a2);
+  TEST_CLAUSE(21_4_7_2_b);
+  TEST_CLAUSE(21_4_7_2_b1);
+  TEST_CLAUSE(21_4_7_2_b2);
+  TEST_CLAUSE(21_4_7_2_c);
+  TEST_CLAUSE(21_4_7_2_c1);
+  TEST_CLAUSE(21_4_7_2_c2);
+  TEST_CLAUSE(21_4_7_2_d);
+  TEST_CLAUSE(21_4_7_3_a);
+  TEST_CLAUSE(21_4_7_3_b);
+  TEST_CLAUSE(21_4_7_3_c);
+  TEST_CLAUSE(21_4_7_3_d);
+  TEST_CLAUSE(21_4_7_4_a);
+  TEST_CLAUSE(21_4_7_4_b);
+  TEST_CLAUSE(21_4_7_4_c);
+  TEST_CLAUSE(21_4_7_4_d);
+  TEST_CLAUSE(21_4_7_5_a);
+  TEST_CLAUSE(21_4_7_5_b);
+  TEST_CLAUSE(21_4_7_5_c);
+  TEST_CLAUSE(21_4_7_5_d);
+  TEST_CLAUSE(21_4_7_6_a);
+  TEST_CLAUSE(21_4_7_6_b);
+  TEST_CLAUSE(21_4_7_6_c);
+  TEST_CLAUSE(21_4_7_6_d);
+  TEST_CLAUSE(21_4_7_7_a);
+  TEST_CLAUSE(21_4_7_7_b);
+  TEST_CLAUSE(21_4_7_7_c);
+  TEST_CLAUSE(21_4_7_7_d);
+  TEST_CLAUSE(21_4_7_8);
+  TEST_CLAUSE(21_4_7_9_a);
+  TEST_CLAUSE(21_4_7_9_b);
+  TEST_CLAUSE(21_4_7_9_c);
+  TEST_CLAUSE(21_4_7_9_d);
+  TEST_CLAUSE(21_4_7_9_e);
+  TEST_CLAUSE(21_4_8_1_a);
+  TEST_CLAUSE(21_4_8_1_b);
+  TEST_CLAUSE(21_4_8_1_c);
+  TEST_CLAUSE(21_4_8_1_d);
+  TEST_CLAUSE(21_4_8_1_e);
+  TEST_CLAUSE(21_4_8_1_f);
+  TEST_CLAUSE(21_4_8_1_g);
+  TEST_CLAUSE(21_4_8_1_h);
+  TEST_CLAUSE(21_4_8_1_i);
+  TEST_CLAUSE(21_4_8_1_j);
+  TEST_CLAUSE(21_4_8_1_k);
+  TEST_CLAUSE(21_4_8_1_l);
   TEST_CLAUSE(21_4_8_9_a);
 }
 
@@ -893,7 +1152,7 @@ sed nisl. In diam lacus, lobortis ut posuere nec, ornare id quam.";
     ifstream input(f);
     fbstring line;
     FOR_EACH (i, v) {
-      EXPECT_TRUE(getline(input, line));
+      EXPECT_TRUE(!getline(input, line).fail());
       EXPECT_EQ(line, *i);
     }
   }
@@ -946,22 +1205,14 @@ TEST(FBString, testMoveOperatorPlusRhs) {
   EXPECT_EQ(size1 + size2, test.size());
 }
 
+// The GNU C++ standard library throws an std::logic_error when an std::string
+// is constructed with a null pointer. Verify that we mirror this behavior.
+//
+// N.B. We behave this way even if the C++ library being used is something
+//      other than libstdc++. Someday if we deem it important to present
+//      identical undefined behavior for other platforms, we can re-visit this.
 TEST(FBString, testConstructionFromLiteralZero) {
-  try {
-    std::string s(0);
-    EXPECT_TRUE(false);
-  } catch (const std::logic_error&) {
-  } catch (...) {
-    EXPECT_TRUE(false);
-  }
-
-  try {
-    fbstring s(0);
-    EXPECT_TRUE(false);
-  } catch (const std::logic_error& e) {
-  } catch (...) {
-    EXPECT_TRUE(false);
-  }
+  EXPECT_THROW(fbstring s(0), std::logic_error);
 }
 
 TEST(FBString, testFixedBugs) {
@@ -972,7 +1223,7 @@ TEST(FBString, testFixedBugs) {
     cp.c_str();
     EXPECT_EQ(str.front(), 'f');
   }
-  { // D481173, --extra-cxxflags=-DFBSTRING_CONSERVATIVE
+  { // D481173
     fbstring str(1337, 'f');
     for (int i = 0; i < 2; ++i) {
       fbstring cp = str;
@@ -993,10 +1244,118 @@ TEST(FBString, testFixedBugs) {
       cp += "bb";
     }
   }
+  { // D661622
+    folly::basic_fbstring<wchar_t> s;
+    EXPECT_EQ(0, s.size());
+  }
+  { // D785057
+    fbstring str(1337, 'f');
+    std::swap(str, str);
+    EXPECT_EQ(1337, str.size());
+  }
+  { // D1012196, --allocator=malloc
+    fbstring str(128, 'f');
+    str.clear();  // Empty medium string.
+    fbstring copy(str);  // Medium string of 0 capacity.
+    copy.push_back('b');
+    EXPECT_GE(copy.capacity(), 1);
+  }
+}
+
+TEST(FBString, findWithNpos) {
+  fbstring fbstr("localhost:80");
+  EXPECT_EQ(fbstring::npos, fbstr.find(":", fbstring::npos));
+}
+
+TEST(FBString, testHash) {
+  fbstring a;
+  fbstring b;
+  a.push_back(0);
+  a.push_back(1);
+  b.push_back(0);
+  b.push_back(2);
+  std::hash<fbstring> hashfunc;
+  EXPECT_NE(hashfunc(a), hashfunc(b));
+}
+
+TEST(FBString, testFrontBack) {
+  fbstring str("hello");
+  EXPECT_EQ(str.front(), 'h');
+  EXPECT_EQ(str.back(), 'o');
+  str.front() = 'H';
+  EXPECT_EQ(str.front(), 'H');
+  str.back() = 'O';
+  EXPECT_EQ(str.back(), 'O');
+  EXPECT_EQ(str, "HellO");
+}
+
+TEST(FBString, noexcept) {
+  EXPECT_TRUE(noexcept(fbstring()));
+  // std::move is not marked noexcept in gcc 4.6, sigh
+#if __GNUC_PREREQ(4, 7)
+  fbstring x;
+  EXPECT_FALSE(noexcept(fbstring(x)));
+  EXPECT_TRUE(noexcept(fbstring(std::move(x))));
+  fbstring y;
+  EXPECT_FALSE(noexcept(y = x));
+  EXPECT_TRUE(noexcept(y = std::move(x)));
+#endif
+}
+
+TEST(FBString, iomanip) {
+  stringstream ss;
+  fbstring fbstr("Hello");
+
+  ss << setw(6) << fbstr;
+  EXPECT_EQ(ss.str(), " Hello");
+  ss.str("");
+
+  ss << left << setw(6) << fbstr;
+  EXPECT_EQ(ss.str(), "Hello ");
+  ss.str("");
+
+  ss << right << setw(6) << fbstr;
+  EXPECT_EQ(ss.str(), " Hello");
+  ss.str("");
+
+  ss << setw(4) << fbstr;
+  EXPECT_EQ(ss.str(), "Hello");
+  ss.str("");
+
+  ss << setfill('^') << setw(6) << fbstr;
+  EXPECT_EQ(ss.str(), "^Hello");
+  ss.str("");
+}
+
+TEST(FBString, rvalueIterators) {
+  // you cannot take &* of a move-iterator, so use that for testing
+  fbstring s = "base";
+  fbstring r = "hello";
+  r.replace(r.begin(), r.end(),
+      make_move_iterator(s.begin()), make_move_iterator(s.end()));
+  EXPECT_EQ("base", r);
+
+  // The following test is probably not required by the standard.
+  // i.e. this could be in the realm of undefined behavior.
+  fbstring b = "123abcXYZ";
+  auto ait = b.begin() + 3;
+  auto Xit = b.begin() + 6;
+  b.replace(ait, b.end(), b.begin(), Xit);
+  EXPECT_EQ("123123abc", b); // if things go wrong, you'd get "123123123"
+}
+
+TEST(FBString, moveTerminator) {
+  // The source of a move must remain in a valid state
+  fbstring s(100, 'x'); // too big to be in-situ
+  fbstring k;
+  k = std::move(s);
+
+  EXPECT_EQ(0, s.size());
+  EXPECT_EQ('\0', *s.c_str());
 }
 
 int main(int argc, char** argv) {
   testing::InitGoogleTest(&argc, argv);
-  google::ParseCommandLineFlags(&argc, &argv, true);
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
   return RUN_ALL_TESTS();
 }