Fill out the rest of the StringPiece functions for 16-bit.

I was originally opposed to these since we didn't need them and they were complicated. But I'm wanting to use some of these functions in a different patch, so it seems like a good time to fill out the std::string-like finding functions for StringPiece16.

This deletes the old StringPieceDetails for which the only point was to share the common stuff between the two BasicStringPiece specializations.

I used the pattern of having two versions of each function declared in the header and then expanding the template in the .cc file, to avoid template bloat in the header.

This replaces all of the size_type goop with size_t. Chrome code assumes these are the same and we encourage people to just use size_t in loops, for example, rather than using the size_type of the template they're iterating over. This makes the code more readable in many places. It also solves a problem with declaration ordering since most of the functions that used size_type are now moved above where the size_type is actually declared.

[email protected]
TBR=akalin, ben

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=255397

Review URL: https://codereview.chromium.org/187793004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@256311 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/strings/string_piece.cc b/base/strings/string_piece.cc
index 79a42d7..4c7f112 100644
--- a/base/strings/string_piece.cc
+++ b/base/strings/string_piece.cc
@@ -9,14 +9,30 @@
 #include <ostream>
 
 namespace base {
+namespace {
+
+// For each character in characters_wanted, sets the index corresponding
+// to the ASCII code of that character to 1 in table.  This is used by
+// the find_.*_of methods below to tell whether or not a character is in
+// the lookup table in constant time.
+// The argument `table' must be an array that is large enough to hold all
+// the possible values of an unsigned char.  Thus it should be be declared
+// as follows:
+//   bool table[UCHAR_MAX + 1]
+inline void BuildLookupTable(const StringPiece& characters_wanted,
+                             bool* table) {
+  const size_t length = characters_wanted.length();
+  const char* const data = characters_wanted.data();
+  for (size_t i = 0; i < length; ++i) {
+    table[static_cast<unsigned char>(data[i])] = true;
+  }
+}
+
+}  // namespace
 
 // MSVC doesn't like complex extern templates and DLLs.
 #if !defined(COMPILER_MSVC)
-namespace internal {
-template class StringPieceDetail<std::string>;
-template class StringPieceDetail<string16>;
-}  // namespace internal
-
+template class BasicStringPiece<std::string>;
 template class BasicStringPiece<string16>;
 #endif
 
@@ -33,101 +49,153 @@
 }
 
 namespace internal {
-void CopyToString(const StringPiece& self, std::string* target) {
-  target->assign(!self.empty() ? self.data() : "", self.size());
+
+template<typename STR>
+void CopyToStringT(const BasicStringPiece<STR>& self, STR* target) {
+  if (self.empty())
+    target->clear();
+  else
+    target->assign(self.data(), self.size());
 }
 
-void AppendToString(const StringPiece& self, std::string* target) {
+void CopyToString(const StringPiece& self, std::string* target) {
+  CopyToStringT(self, target);
+}
+
+void CopyToString(const StringPiece16& self, string16* target) {
+  CopyToStringT(self, target);
+}
+
+template<typename STR>
+void AppendToStringT(const BasicStringPiece<STR>& self, STR* target) {
   if (!self.empty())
     target->append(self.data(), self.size());
 }
 
-StringPiece::size_type copy(const StringPiece& self,
-                            char* buf,
-                            StringPiece::size_type n,
-                            StringPiece::size_type pos) {
-  StringPiece::size_type ret = std::min(self.size() - pos, n);
-  memcpy(buf, self.data() + pos, ret);
+void AppendToString(const StringPiece& self, std::string* target) {
+  AppendToStringT(self, target);
+}
+
+void AppendToString(const StringPiece16& self, string16* target) {
+  AppendToStringT(self, target);
+}
+
+template<typename STR>
+size_t copyT(const BasicStringPiece<STR>& self,
+             typename STR::value_type* buf,
+             size_t n,
+             size_t pos) {
+  size_t ret = std::min(self.size() - pos, n);
+  memcpy(buf, self.data() + pos, ret * sizeof(typename STR::value_type));
   return ret;
 }
 
-StringPiece::size_type find(const StringPiece& self,
-                            const StringPiece& s,
-                            StringPiece::size_type pos) {
-  if (pos > self.size())
-    return StringPiece::npos;
-
-  StringPiece::const_iterator result =
-      std::search(self.begin() + pos, self.end(), s.begin(), s.end());
-  const StringPiece::size_type xpos =
-    static_cast<size_t>(result - self.begin());
-  return xpos + s.size() <= self.size() ? xpos : StringPiece::npos;
+size_t copy(const StringPiece& self, char* buf, size_t n, size_t pos) {
+  return copyT(self, buf, n, pos);
 }
 
-StringPiece::size_type find(const StringPiece& self,
-                            char c,
-                            StringPiece::size_type pos) {
-  if (pos >= self.size())
-    return StringPiece::npos;
+size_t copy(const StringPiece16& self, char16* buf, size_t n, size_t pos) {
+  return copyT(self, buf, n, pos);
+}
 
-  StringPiece::const_iterator result =
+template<typename STR>
+size_t findT(const BasicStringPiece<STR>& self,
+             const BasicStringPiece<STR>& s,
+             size_t pos) {
+  if (pos > self.size())
+    return BasicStringPiece<STR>::npos;
+
+  typename BasicStringPiece<STR>::const_iterator result =
+      std::search(self.begin() + pos, self.end(), s.begin(), s.end());
+  const size_t xpos =
+    static_cast<size_t>(result - self.begin());
+  return xpos + s.size() <= self.size() ? xpos : BasicStringPiece<STR>::npos;
+}
+
+size_t find(const StringPiece& self, const StringPiece& s, size_t pos) {
+  return findT(self, s, pos);
+}
+
+size_t find(const StringPiece16& self, const StringPiece16& s, size_t pos) {
+  return findT(self, s, pos);
+}
+
+template<typename STR>
+size_t findT(const BasicStringPiece<STR>& self,
+             typename STR::value_type c,
+             size_t pos) {
+  if (pos >= self.size())
+    return BasicStringPiece<STR>::npos;
+
+  typename BasicStringPiece<STR>::const_iterator result =
       std::find(self.begin() + pos, self.end(), c);
   return result != self.end() ?
-      static_cast<size_t>(result - self.begin()) : StringPiece::npos;
+      static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos;
 }
 
-StringPiece::size_type rfind(const StringPiece& self,
-                             const StringPiece& s,
-                             StringPiece::size_type pos) {
+size_t find(const StringPiece& self, char c, size_t pos) {
+  return findT(self, c, pos);
+}
+
+size_t find(const StringPiece16& self, char16 c, size_t pos) {
+  return findT(self, c, pos);
+}
+
+template<typename STR>
+size_t rfindT(const BasicStringPiece<STR>& self,
+              const BasicStringPiece<STR>& s,
+              size_t pos) {
   if (self.size() < s.size())
-    return StringPiece::npos;
+    return BasicStringPiece<STR>::npos;
 
   if (s.empty())
     return std::min(self.size(), pos);
 
-  StringPiece::const_iterator last =
+  typename BasicStringPiece<STR>::const_iterator last =
       self.begin() + std::min(self.size() - s.size(), pos) + s.size();
-  StringPiece::const_iterator result =
+  typename BasicStringPiece<STR>::const_iterator result =
       std::find_end(self.begin(), last, s.begin(), s.end());
   return result != last ?
-      static_cast<size_t>(result - self.begin()) : StringPiece::npos;
+      static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos;
 }
 
-StringPiece::size_type rfind(const StringPiece& self,
-                             char c,
-                             StringPiece::size_type pos) {
-  if (self.size() == 0)
-    return StringPiece::npos;
+size_t rfind(const StringPiece& self, const StringPiece& s, size_t pos) {
+  return rfindT(self, s, pos);
+}
 
-  for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) {
+size_t rfind(const StringPiece16& self, const StringPiece16& s, size_t pos) {
+  return rfindT(self, s, pos);
+}
+
+template<typename STR>
+size_t rfindT(const BasicStringPiece<STR>& self,
+              typename STR::value_type c,
+              size_t pos) {
+  if (self.size() == 0)
+    return BasicStringPiece<STR>::npos;
+
+  for (size_t i = std::min(pos, self.size() - 1); ;
+       --i) {
     if (self.data()[i] == c)
       return i;
     if (i == 0)
       break;
   }
-  return StringPiece::npos;
+  return BasicStringPiece<STR>::npos;
 }
 
-// For each character in characters_wanted, sets the index corresponding
-// to the ASCII code of that character to 1 in table.  This is used by
-// the find_.*_of methods below to tell whether or not a character is in
-// the lookup table in constant time.
-// The argument `table' must be an array that is large enough to hold all
-// the possible values of an unsigned char.  Thus it should be be declared
-// as follows:
-//   bool table[UCHAR_MAX + 1]
-static inline void BuildLookupTable(const StringPiece& characters_wanted,
-                                    bool* table) {
-  const StringPiece::size_type length = characters_wanted.length();
-  const char* const data = characters_wanted.data();
-  for (StringPiece::size_type i = 0; i < length; ++i) {
-    table[static_cast<unsigned char>(data[i])] = true;
-  }
+size_t rfind(const StringPiece& self, char c, size_t pos) {
+  return rfindT(self, c, pos);
 }
 
-StringPiece::size_type find_first_of(const StringPiece& self,
-                                     const StringPiece& s,
-                                     StringPiece::size_type pos) {
+size_t rfind(const StringPiece16& self, char16 c, size_t pos) {
+  return rfindT(self, c, pos);
+}
+
+// 8-bit version using lookup table.
+size_t find_first_of(const StringPiece& self,
+                     const StringPiece& s,
+                     size_t pos) {
   if (self.size() == 0 || s.size() == 0)
     return StringPiece::npos;
 
@@ -137,7 +205,7 @@
 
   bool lookup[UCHAR_MAX + 1] = { false };
   BuildLookupTable(s, lookup);
-  for (StringPiece::size_type i = pos; i < self.size(); ++i) {
+  for (size_t i = pos; i < self.size(); ++i) {
     if (lookup[static_cast<unsigned char>(self.data()[i])]) {
       return i;
     }
@@ -145,9 +213,21 @@
   return StringPiece::npos;
 }
 
-StringPiece::size_type find_first_not_of(const StringPiece& self,
-                                         const StringPiece& s,
-                                         StringPiece::size_type pos) {
+// 16-bit brute force version.
+size_t find_first_of(const StringPiece16& self,
+                     const StringPiece16& s,
+                     size_t pos) {
+  StringPiece16::const_iterator found =
+      std::find_first_of(self.begin() + pos, self.end(), s.begin(), s.end());
+  if (found == self.end())
+    return StringPiece16::npos;
+  return found - self.begin();
+}
+
+// 8-bit version using lookup table.
+size_t find_first_not_of(const StringPiece& self,
+                         const StringPiece& s,
+                         size_t pos) {
   if (self.size() == 0)
     return StringPiece::npos;
 
@@ -160,7 +240,7 @@
 
   bool lookup[UCHAR_MAX + 1] = { false };
   BuildLookupTable(s, lookup);
-  for (StringPiece::size_type i = pos; i < self.size(); ++i) {
+  for (size_t i = pos; i < self.size(); ++i) {
     if (!lookup[static_cast<unsigned char>(self.data()[i])]) {
       return i;
     }
@@ -168,23 +248,56 @@
   return StringPiece::npos;
 }
 
-StringPiece::size_type find_first_not_of(const StringPiece& self,
-                                         char c,
-                                         StringPiece::size_type pos) {
+// 16-bit brute-force version.
+BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
+                                     const StringPiece16& s,
+                                     size_t pos) {
   if (self.size() == 0)
-    return StringPiece::npos;
+    return StringPiece16::npos;
+
+  for (size_t self_i = pos; self_i < self.size(); ++self_i) {
+    bool found = false;
+    for (size_t s_i = 0; s_i < s.size(); ++s_i) {
+      if (self[self_i] == s[s_i]) {
+        found = true;
+        break;
+      }
+    }
+    if (!found)
+      return self_i;
+  }
+  return StringPiece16::npos;
+}
+
+template<typename STR>
+size_t find_first_not_ofT(const BasicStringPiece<STR>& self,
+                          typename STR::value_type c,
+                          size_t pos) {
+  if (self.size() == 0)
+    return BasicStringPiece<STR>::npos;
 
   for (; pos < self.size(); ++pos) {
     if (self.data()[pos] != c) {
       return pos;
     }
   }
-  return StringPiece::npos;
+  return BasicStringPiece<STR>::npos;
 }
 
-StringPiece::size_type find_last_of(const StringPiece& self,
-                                    const StringPiece& s,
-                                    StringPiece::size_type pos) {
+size_t find_first_not_of(const StringPiece& self,
+                         char c,
+                         size_t pos) {
+  return find_first_not_ofT(self, c, pos);
+}
+
+size_t find_first_not_of(const StringPiece16& self,
+                         char16 c,
+                         size_t pos) {
+  return find_first_not_ofT(self, c, pos);
+}
+
+// 8-bit version using lookup table.
+size_t find_last_of(const StringPiece& self, const StringPiece& s, size_t pos) {
   if (self.size() == 0 || s.size() == 0)
     return StringPiece::npos;
 
@@ -194,7 +307,7 @@
 
   bool lookup[UCHAR_MAX + 1] = { false };
   BuildLookupTable(s, lookup);
-  for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) {
+  for (size_t i = std::min(pos, self.size() - 1); ; --i) {
     if (lookup[static_cast<unsigned char>(self.data()[i])])
       return i;
     if (i == 0)
@@ -203,13 +316,33 @@
   return StringPiece::npos;
 }
 
-StringPiece::size_type find_last_not_of(const StringPiece& self,
-                                        const StringPiece& s,
-                                        StringPiece::size_type pos) {
+// 16-bit brute-force version.
+size_t find_last_of(const StringPiece16& self,
+                    const StringPiece16& s,
+                    size_t pos) {
+  if (self.size() == 0)
+    return StringPiece16::npos;
+
+  for (size_t self_i = std::min(pos, self.size() - 1); ;
+       --self_i) {
+    for (size_t s_i = 0; s_i < s.size(); s_i++) {
+      if (self.data()[self_i] == s[s_i])
+        return self_i;
+    }
+    if (self_i == 0)
+      break;
+  }
+  return StringPiece16::npos;
+}
+
+// 8-bit version using lookup table.
+size_t find_last_not_of(const StringPiece& self,
+                        const StringPiece& s,
+                        size_t pos) {
   if (self.size() == 0)
     return StringPiece::npos;
 
-  StringPiece::size_type i = std::min(pos, self.size() - 1);
+  size_t i = std::min(pos, self.size() - 1);
   if (s.size() == 0)
     return i;
 
@@ -228,27 +361,76 @@
   return StringPiece::npos;
 }
 
-StringPiece::size_type find_last_not_of(const StringPiece& self,
-                                        char c,
-                                        StringPiece::size_type pos) {
+// 16-bit brute-force version.
+size_t find_last_not_of(const StringPiece16& self,
+                        const StringPiece16& s,
+                        size_t pos) {
   if (self.size() == 0)
     return StringPiece::npos;
 
-  for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) {
+  for (size_t self_i = std::min(pos, self.size() - 1); ; --self_i) {
+    bool found = false;
+    for (size_t s_i = 0; s_i < s.size(); s_i++) {
+      if (self.data()[self_i] == s[s_i]) {
+        found = true;
+        break;
+      }
+    }
+    if (!found)
+      return self_i;
+    if (self_i == 0)
+      break;
+  }
+  return StringPiece16::npos;
+}
+
+template<typename STR>
+size_t find_last_not_ofT(const BasicStringPiece<STR>& self,
+                         typename STR::value_type c,
+                         size_t pos) {
+  if (self.size() == 0)
+    return BasicStringPiece<STR>::npos;
+
+  for (size_t i = std::min(pos, self.size() - 1); ; --i) {
     if (self.data()[i] != c)
       return i;
     if (i == 0)
       break;
   }
-  return StringPiece::npos;
+  return BasicStringPiece<STR>::npos;
+}
+
+size_t find_last_not_of(const StringPiece& self,
+                        char c,
+                        size_t pos) {
+  return find_last_not_ofT(self, c, pos);
+}
+
+size_t find_last_not_of(const StringPiece16& self,
+                        char16 c,
+                        size_t pos) {
+  return find_last_not_ofT(self, c, pos);
+}
+
+template<typename STR>
+BasicStringPiece<STR> substrT(const BasicStringPiece<STR>& self,
+                              size_t pos,
+                              size_t n) {
+  if (pos > self.size()) pos = self.size();
+  if (n > self.size() - pos) n = self.size() - pos;
+  return BasicStringPiece<STR>(self.data() + pos, n);
 }
 
 StringPiece substr(const StringPiece& self,
-                   StringPiece::size_type pos,
-                   StringPiece::size_type n) {
-  if (pos > self.size()) pos = self.size();
-  if (n > self.size() - pos) n = self.size() - pos;
-  return StringPiece(self.data() + pos, n);
+                   size_t pos,
+                   size_t n) {
+  return substrT(self, pos, n);
+}
+
+StringPiece16 substr(const StringPiece16& self,
+                     size_t pos,
+                     size_t n) {
+  return substrT(self, pos, n);
 }
 
 }  // namespace internal
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index 818d6ca5..38e2277e 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -39,14 +39,124 @@
 typedef BasicStringPiece<std::string> StringPiece;
 typedef BasicStringPiece<string16> StringPiece16;
 
+// internal --------------------------------------------------------------------
+
+// Many of the StringPiece functions use different implementations for the
+// 8-bit and 16-bit versions, and we don't want lots of template expansions in
+// this (very common) header that will slow down compilation.
+//
+// So here we define overloaded functions called by the StringPiece template.
+// For those that share an implementation, the two versions will expand to a
+// template internal to the .cc file.
 namespace internal {
 
+BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target);
+BASE_EXPORT void CopyToString(const StringPiece16& self, string16* target);
+
+BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target);
+BASE_EXPORT void AppendToString(const StringPiece16& self, string16* target);
+
+BASE_EXPORT size_t copy(const StringPiece& self,
+                        char* buf,
+                        size_t n,
+                        size_t pos);
+BASE_EXPORT size_t copy(const StringPiece16& self,
+                        char16* buf,
+                        size_t n,
+                        size_t pos);
+
+BASE_EXPORT size_t find(const StringPiece& self,
+                        const StringPiece& s,
+                        size_t pos);
+BASE_EXPORT size_t find(const StringPiece16& self,
+                        const StringPiece16& s,
+                        size_t pos);
+BASE_EXPORT size_t find(const StringPiece& self,
+                        char c,
+                        size_t pos);
+BASE_EXPORT size_t find(const StringPiece16& self,
+                        char16 c,
+                        size_t pos);
+
+BASE_EXPORT size_t rfind(const StringPiece& self,
+                         const StringPiece& s,
+                         size_t pos);
+BASE_EXPORT size_t rfind(const StringPiece16& self,
+                         const StringPiece16& s,
+                         size_t pos);
+BASE_EXPORT size_t rfind(const StringPiece& self,
+                         char c,
+                         size_t pos);
+BASE_EXPORT size_t rfind(const StringPiece16& self,
+                         char16 c,
+                         size_t pos);
+
+BASE_EXPORT size_t find_first_of(const StringPiece& self,
+                                 const StringPiece& s,
+                                 size_t pos);
+BASE_EXPORT size_t find_first_of(const StringPiece16& self,
+                                 const StringPiece16& s,
+                                 size_t pos);
+
+BASE_EXPORT size_t find_first_not_of(const StringPiece& self,
+                                     const StringPiece& s,
+                                     size_t pos);
+BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
+                                     const StringPiece16& s,
+                                     size_t pos);
+BASE_EXPORT size_t find_first_not_of(const StringPiece& self,
+                                     char c,
+                                     size_t pos);
+BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
+                                     char16 c,
+                                     size_t pos);
+
+BASE_EXPORT size_t find_last_of(const StringPiece& self,
+                                const StringPiece& s,
+                                size_t pos);
+BASE_EXPORT size_t find_last_of(const StringPiece16& self,
+                                const StringPiece16& s,
+                                size_t pos);
+BASE_EXPORT size_t find_last_of(const StringPiece& self,
+                                char c,
+                                size_t pos);
+BASE_EXPORT size_t find_last_of(const StringPiece16& self,
+                                char16 c,
+                                size_t pos);
+
+BASE_EXPORT size_t find_last_not_of(const StringPiece& self,
+                                    const StringPiece& s,
+                                    size_t pos);
+BASE_EXPORT size_t find_last_not_of(const StringPiece16& self,
+                                    const StringPiece16& s,
+                                    size_t pos);
+BASE_EXPORT size_t find_last_not_of(const StringPiece16& self,
+                                    char16 c,
+                                    size_t pos);
+BASE_EXPORT size_t find_last_not_of(const StringPiece& self,
+                                    char c,
+                                    size_t pos);
+
+BASE_EXPORT StringPiece substr(const StringPiece& self,
+                               size_t pos,
+                               size_t n);
+BASE_EXPORT StringPiece16 substr(const StringPiece16& self,
+                                 size_t pos,
+                                 size_t n);
+
+}  // namespace internal
+
+// BasicStringPiece ------------------------------------------------------------
+
 // Defines the types, methods, operators, and data members common to both
 // StringPiece and StringPiece16. Do not refer to this class directly, but
 // rather to BasicStringPiece, StringPiece, or StringPiece16.
-template <typename STRING_TYPE> class StringPieceDetail {
+//
+// This is templatized by string class type rather than character type, so
+// BasicStringPiece<std::string> or BasicStringPiece<base::string16>.
+template <typename STRING_TYPE> class BasicStringPiece {
  public:
-  // standard STL container boilerplate
+  // Standard STL container boilerplate.
   typedef size_t size_type;
   typedef typename STRING_TYPE::value_type value_type;
   typedef const value_type* pointer;
@@ -62,15 +172,15 @@
   // We provide non-explicit singleton constructors so users can pass
   // in a "const char*" or a "string" wherever a "StringPiece" is
   // expected (likewise for char16, string16, StringPiece16).
-  StringPieceDetail() : ptr_(NULL), length_(0) {}
-  StringPieceDetail(const value_type* str)
+  BasicStringPiece() : ptr_(NULL), length_(0) {}
+  BasicStringPiece(const value_type* str)
       : ptr_(str),
         length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
-  StringPieceDetail(const STRING_TYPE& str)
+  BasicStringPiece(const STRING_TYPE& str)
       : ptr_(str.data()), length_(str.size()) {}
-  StringPieceDetail(const value_type* offset, size_type len)
+  BasicStringPiece(const value_type* offset, size_type len)
       : ptr_(offset), length_(len) {}
-  StringPieceDetail(const typename STRING_TYPE::const_iterator& begin,
+  BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
                     const typename STRING_TYPE::const_iterator& end)
       : ptr_((end > begin) ? &(*begin) : NULL),
         length_((end > begin) ? (size_type)(end - begin) : 0) {}
@@ -141,213 +251,113 @@
     return STRING_TYPE::traits_type::compare(p, p2, N);
   }
 
+  // Sets the value of the given string target type to be the current string.
+  // This saves a temporary over doing |a = b.as_string()|
+  void CopyToString(STRING_TYPE* target) const {
+    internal::CopyToString(*this, target);
+  }
+
+  void AppendToString(STRING_TYPE* target) const {
+    internal::AppendToString(*this, target);
+  }
+
+  size_type copy(value_type* buf, size_type n, size_type pos = 0) const {
+    return internal::copy(*this, buf, n, pos);
+  }
+
+  // Does "this" start with "x"
+  bool starts_with(const BasicStringPiece& x) const {
+    return ((this->length_ >= x.length_) &&
+            (wordmemcmp(this->ptr_, x.ptr_, x.length_) == 0));
+  }
+
+  // Does "this" end with "x"
+  bool ends_with(const BasicStringPiece& x) const {
+    return ((this->length_ >= x.length_) &&
+            (wordmemcmp(this->ptr_ + (this->length_-x.length_),
+                        x.ptr_, x.length_) == 0));
+  }
+
+  // find: Search for a character or substring at a given offset.
+  size_type find(const BasicStringPiece<STRING_TYPE>& s,
+                 size_type pos = 0) const {
+    return internal::find(*this, s, pos);
+  }
+  size_type find(value_type c, size_type pos = 0) const {
+    return internal::find(*this, c, pos);
+  }
+
+  // rfind: Reverse find.
+  size_type rfind(const BasicStringPiece& s,
+                  size_type pos = BasicStringPiece::npos) const {
+    return internal::rfind(*this, s, pos);
+  }
+  size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const {
+    return internal::rfind(*this, c, pos);
+  }
+
+  // find_first_of: Find the first occurence of one of a set of characters.
+  size_type find_first_of(const BasicStringPiece& s,
+                          size_type pos = 0) const {
+    return internal::find_first_of(*this, s, pos);
+  }
+  size_type find_first_of(value_type c, size_type pos = 0) const {
+    return find(c, pos);
+  }
+
+  // find_first_not_of: Find the first occurence not of a set of characters.
+  size_type find_first_not_of(const BasicStringPiece& s,
+                              size_type pos = 0) const {
+    return internal::find_first_not_of(*this, s, pos);
+  }
+  size_type find_first_not_of(value_type c, size_type pos = 0) const {
+    return internal::find_first_not_of(*this, c, pos);
+  }
+
+  // find_last_of: Find the last occurence of one of a set of characters.
+  size_type find_last_of(const BasicStringPiece& s,
+                         size_type pos = BasicStringPiece::npos) const {
+    return internal::find_last_of(*this, s, pos);
+  }
+  size_type find_last_of(value_type c,
+                         size_type pos = BasicStringPiece::npos) const {
+    return rfind(c, pos);
+  }
+
+  // find_last_not_of: Find the last occurence not of a set of characters.
+  size_type find_last_not_of(const BasicStringPiece& s,
+                             size_type pos = BasicStringPiece::npos) const {
+    return internal::find_last_not_of(*this, s, pos);
+  }
+  size_type find_last_not_of(value_type c,
+                             size_type pos = BasicStringPiece::npos) const {
+    return internal::find_last_not_of(*this, c, pos);
+  }
+
+  // substr.
+  BasicStringPiece substr(size_type pos,
+                          size_type n = BasicStringPiece::npos) const {
+    return internal::substr(*this, pos, n);
+  }
+
  protected:
   const value_type* ptr_;
   size_type     length_;
 };
 
 template <typename STRING_TYPE>
-const typename StringPieceDetail<STRING_TYPE>::size_type
-StringPieceDetail<STRING_TYPE>::npos =
-    typename StringPieceDetail<STRING_TYPE>::size_type(-1);
+const typename BasicStringPiece<STRING_TYPE>::size_type
+BasicStringPiece<STRING_TYPE>::npos =
+    typename BasicStringPiece<STRING_TYPE>::size_type(-1);
 
 // MSVC doesn't like complex extern templates and DLLs.
 #if !defined(COMPILER_MSVC)
-extern template class BASE_EXPORT StringPieceDetail<std::string>;
-extern template class BASE_EXPORT StringPieceDetail<string16>;
-#endif
-
-BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target);
-BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target);
-BASE_EXPORT StringPieceDetail<std::string>::size_type copy(
-    const StringPiece& self,
-    char* buf,
-    StringPieceDetail<std::string>::size_type n,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find(
-    const StringPiece& self,
-    const StringPiece& s,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find(
-    const StringPiece& self,
-    char c,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
-    const StringPiece& self,
-    const StringPiece& s,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
-    const StringPiece& self,
-    char c,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of(
-    const StringPiece& self,
-    const StringPiece& s,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
-    const StringPiece& self,
-    const StringPiece& s,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
-    const StringPiece& self,
-    char c,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
-    const StringPiece& self,
-    const StringPiece& s,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
-    const StringPiece& self,
-    char c,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
-    const StringPiece& self,
-    const StringPiece& s,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
-    const StringPiece& self,
-    char c,
-    StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPiece substr(const StringPiece& self,
-                               StringPieceDetail<std::string>::size_type pos,
-                               StringPieceDetail<std::string>::size_type n);
-}  // namespace internal
-
-// Defines the template type that is instantiated as either StringPiece or
-// StringPiece16.
-template <typename STRING_TYPE> class BasicStringPiece :
-    public internal::StringPieceDetail<STRING_TYPE> {
- public:
-  typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type
-      value_type;
-  typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type
-      size_type;
-
-  BasicStringPiece() {}
-  BasicStringPiece(const value_type*str)
-      : internal::StringPieceDetail<STRING_TYPE>(str) {}
-  BasicStringPiece(const STRING_TYPE& str)
-      : internal::StringPieceDetail<STRING_TYPE>(str) {}
-  BasicStringPiece(const value_type* offset, size_type len)
-      : internal::StringPieceDetail<STRING_TYPE>(offset, len) {}
-  BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
-                   const typename STRING_TYPE::const_iterator& end)
-      : internal::StringPieceDetail<STRING_TYPE>(begin, end) {}
-};
-
-// Specializes BasicStringPiece for std::string to add a few operations that
-// are not needed for string16.
-template <> class BasicStringPiece<std::string> :
-    public internal::StringPieceDetail<std::string> {
- public:
-  BasicStringPiece() {}
-  BasicStringPiece(const char* str)
-      : internal::StringPieceDetail<std::string>(str) {}
-  BasicStringPiece(const std::string& str)
-      : internal::StringPieceDetail<std::string>(str) {}
-  BasicStringPiece(const char* offset, size_type len)
-      : internal::StringPieceDetail<std::string>(offset, len) {}
-  BasicStringPiece(const std::string::const_iterator& begin,
-                   const std::string::const_iterator& end)
-      : internal::StringPieceDetail<std::string>(begin, end) {}
-
-  // Prevent the following overload of set() from hiding the definitions in the
-  // base class.
-  using internal::StringPieceDetail<std::string>::set;
-
-  void set(const void* data, size_type len) {
-    ptr_ = reinterpret_cast<const value_type*>(data);
-    length_ = len;
-  }
-
-  void CopyToString(std::string* target) const {
-    internal::CopyToString(*this, target);
-  }
-
-  void AppendToString(std::string* target) const {
-    internal::AppendToString(*this, target);
-  }
-
-  // Does "this" start with "x"
-  bool starts_with(const BasicStringPiece& x) const {
-    return ((length_ >= x.length_) &&
-            (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
-  }
-
-  // Does "this" end with "x"
-  bool ends_with(const BasicStringPiece& x) const {
-    return ((length_ >= x.length_) &&
-            (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
-  }
-
-  size_type copy(char* buf, size_type n, size_type pos = 0) const {
-    return internal::copy(*this, buf, n, pos);
-  }
-
-  size_type find(const BasicStringPiece& s, size_type pos = 0) const {
-    return internal::find(*this, s, pos);
-  }
-
-  size_type find(char c, size_type pos = 0) const {
-    return internal::find(*this, c, pos);
-  }
-
-  size_type rfind(const BasicStringPiece& s, size_type pos = npos) const {
-    return internal::rfind(*this, s, pos);
-  }
-
-  size_type rfind(char c, size_type pos = npos) const {
-    return internal::rfind(*this, c, pos);
-  }
-
-  size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const {
-    return internal::find_first_of(*this, s, pos);
-  }
-
-  size_type find_first_of(char c, size_type pos = 0) const {
-    return find(c, pos);
-  }
-
-  size_type find_first_not_of(const BasicStringPiece& s,
-                              size_type pos = 0) const {
-    return internal::find_first_not_of(*this, s, pos);
-  }
-
-  size_type find_first_not_of(char c, size_type pos = 0) const {
-    return internal::find_first_not_of(*this, c, pos);
-  }
-
-  size_type find_last_of(const BasicStringPiece& s,
-                         size_type pos = npos) const {
-    return internal::find_last_of(*this, s, pos);
-  }
-
-  size_type find_last_of(char c, size_type pos = npos) const {
-    return rfind(c, pos);
-  }
-
-  size_type find_last_not_of(const BasicStringPiece& s,
-                             size_type pos = npos) const {
-    return internal::find_last_not_of(*this, s, pos);
-  }
-
-  size_type find_last_not_of(char c, size_type pos = npos) const {
-    return internal::find_last_not_of(*this, c, pos);
-  }
-
-  BasicStringPiece substr(size_type pos, size_type n = npos) const {
-    return internal::substr(*this, pos, n);
-  }
-};
-
-// MSVC doesn't like complex extern templates and DLLs.
-#if !defined(COMPILER_MSVC)
-// We can't explicitly declare the std::string instantiation here because it was
-// already instantiated when specialized, above. Not only is it a no-op, but
-// currently it also crashes Clang (see http://crbug.com/107412).
+extern template class BASE_EXPORT BasicStringPiece<std::string>;
 extern template class BASE_EXPORT BasicStringPiece<string16>;
 #endif
 
+// StingPiece operators --------------------------------------------------------
+
 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);
 
 inline bool operator!=(const StringPiece& x, const StringPiece& y) {
@@ -372,6 +382,8 @@
   return !(x < y);
 }
 
+// StringPiece16 operators -----------------------------------------------------
+
 inline bool operator==(const StringPiece16& x, const StringPiece16& y) {
   if (x.size() != y.size())
     return false;
@@ -406,6 +418,8 @@
 
 }  // namespace base
 
+// Hashing ---------------------------------------------------------------------
+
 // We provide appropriate hash functions so StringPiece and StringPiece16 can
 // be used as keys in hash sets and maps.
 
diff --git a/base/strings/string_piece_unittest.cc b/base/strings/string_piece_unittest.cc
index 84ed9ef..d45fd92 100644
--- a/base/strings/string_piece_unittest.cc
+++ b/base/strings/string_piece_unittest.cc
@@ -192,20 +192,27 @@
   ASSERT_GE(a.capacity(), a.size());
 }
 
-// STL stuff only supported by the std::string version
-TEST(StringPieceTest, CheckSTL) {
-  StringPiece a("abcdefghijklmnopqrstuvwxyz");
-  StringPiece b("abc");
-  StringPiece c("xyz");
-  StringPiece d("foobar");
-  d.clear();
-  StringPiece e;
-  std::string temp("123");
-  temp += '\0';
-  temp += "456";
-  StringPiece f(temp);
+TYPED_TEST(CommonStringPieceTest, CheckFind) {
+  typedef BasicStringPiece<TypeParam> Piece;
 
-  char buf[4] = { '%', '%', '%', '%' };
+  TypeParam alphabet(TestFixture::as_string("abcdefghijklmnopqrstuvwxyz"));
+  TypeParam abc(TestFixture::as_string("abc"));
+  TypeParam xyz(TestFixture::as_string("xyz"));
+  TypeParam foobar(TestFixture::as_string("foobar"));
+
+  BasicStringPiece<TypeParam> a(alphabet);
+  BasicStringPiece<TypeParam> b(abc);
+  BasicStringPiece<TypeParam> c(xyz);
+  BasicStringPiece<TypeParam> d(foobar);
+
+  d.clear();
+  Piece e;
+  TypeParam temp(TestFixture::as_string("123"));
+  temp.push_back('\0');
+  temp += TestFixture::as_string("456");
+  Piece f(temp);
+
+  typename TypeParam::value_type buf[4] = { '%', '%', '%', '%' };
   ASSERT_EQ(a.copy(buf, 4), 4U);
   ASSERT_EQ(buf[0], a[0]);
   ASSERT_EQ(buf[1], a[1]);
@@ -222,28 +229,29 @@
   ASSERT_EQ(buf[2], c[2]);
   ASSERT_EQ(buf[3], a[3]);
 
-  ASSERT_EQ(StringPiece::npos, std::string::npos);
+  ASSERT_EQ(Piece::npos, TypeParam::npos);
 
   ASSERT_EQ(a.find(b), 0U);
-  ASSERT_EQ(a.find(b, 1), StringPiece::npos);
+  ASSERT_EQ(a.find(b, 1), Piece::npos);
   ASSERT_EQ(a.find(c), 23U);
   ASSERT_EQ(a.find(c, 9), 23U);
-  ASSERT_EQ(a.find(c, StringPiece::npos), StringPiece::npos);
-  ASSERT_EQ(b.find(c), StringPiece::npos);
-  ASSERT_EQ(b.find(c, StringPiece::npos), StringPiece::npos);
+  ASSERT_EQ(a.find(c, Piece::npos), Piece::npos);
+  ASSERT_EQ(b.find(c), Piece::npos);
+  ASSERT_EQ(b.find(c, Piece::npos), Piece::npos);
   ASSERT_EQ(a.find(d), 0U);
   ASSERT_EQ(a.find(e), 0U);
   ASSERT_EQ(a.find(d, 12), 12U);
   ASSERT_EQ(a.find(e, 17), 17U);
-  StringPiece g("xx not found bb");
-  ASSERT_EQ(a.find(g), StringPiece::npos);
+  TypeParam not_found(TestFixture::as_string("xx not found bb"));
+  Piece g(not_found);
+  ASSERT_EQ(a.find(g), Piece::npos);
   // empty string nonsense
-  ASSERT_EQ(d.find(b), StringPiece::npos);
-  ASSERT_EQ(e.find(b), StringPiece::npos);
-  ASSERT_EQ(d.find(b, 4), StringPiece::npos);
-  ASSERT_EQ(e.find(b, 7), StringPiece::npos);
+  ASSERT_EQ(d.find(b), Piece::npos);
+  ASSERT_EQ(e.find(b), Piece::npos);
+  ASSERT_EQ(d.find(b, 4), Piece::npos);
+  ASSERT_EQ(e.find(b, 7), Piece::npos);
 
-  size_t empty_search_pos = std::string().find(std::string());
+  size_t empty_search_pos = TypeParam().find(TypeParam());
   ASSERT_EQ(d.find(d), empty_search_pos);
   ASSERT_EQ(d.find(e), empty_search_pos);
   ASSERT_EQ(e.find(d), empty_search_pos);
@@ -256,42 +264,42 @@
   ASSERT_EQ(a.find('a'), 0U);
   ASSERT_EQ(a.find('c'), 2U);
   ASSERT_EQ(a.find('z'), 25U);
-  ASSERT_EQ(a.find('$'), StringPiece::npos);
-  ASSERT_EQ(a.find('\0'), StringPiece::npos);
+  ASSERT_EQ(a.find('$'), Piece::npos);
+  ASSERT_EQ(a.find('\0'), Piece::npos);
   ASSERT_EQ(f.find('\0'), 3U);
   ASSERT_EQ(f.find('3'), 2U);
   ASSERT_EQ(f.find('5'), 5U);
   ASSERT_EQ(g.find('o'), 4U);
   ASSERT_EQ(g.find('o', 4), 4U);
   ASSERT_EQ(g.find('o', 5), 8U);
-  ASSERT_EQ(a.find('b', 5), StringPiece::npos);
+  ASSERT_EQ(a.find('b', 5), Piece::npos);
   // empty string nonsense
-  ASSERT_EQ(d.find('\0'), StringPiece::npos);
-  ASSERT_EQ(e.find('\0'), StringPiece::npos);
-  ASSERT_EQ(d.find('\0', 4), StringPiece::npos);
-  ASSERT_EQ(e.find('\0', 7), StringPiece::npos);
-  ASSERT_EQ(d.find('x'), StringPiece::npos);
-  ASSERT_EQ(e.find('x'), StringPiece::npos);
-  ASSERT_EQ(d.find('x', 4), StringPiece::npos);
-  ASSERT_EQ(e.find('x', 7), StringPiece::npos);
+  ASSERT_EQ(d.find('\0'), Piece::npos);
+  ASSERT_EQ(e.find('\0'), Piece::npos);
+  ASSERT_EQ(d.find('\0', 4), Piece::npos);
+  ASSERT_EQ(e.find('\0', 7), Piece::npos);
+  ASSERT_EQ(d.find('x'), Piece::npos);
+  ASSERT_EQ(e.find('x'), Piece::npos);
+  ASSERT_EQ(d.find('x', 4), Piece::npos);
+  ASSERT_EQ(e.find('x', 7), Piece::npos);
 
   ASSERT_EQ(a.rfind(b), 0U);
   ASSERT_EQ(a.rfind(b, 1), 0U);
   ASSERT_EQ(a.rfind(c), 23U);
-  ASSERT_EQ(a.rfind(c, 22U), StringPiece::npos);
-  ASSERT_EQ(a.rfind(c, 1U), StringPiece::npos);
-  ASSERT_EQ(a.rfind(c, 0U), StringPiece::npos);
-  ASSERT_EQ(b.rfind(c), StringPiece::npos);
-  ASSERT_EQ(b.rfind(c, 0U), StringPiece::npos);
-  ASSERT_EQ(a.rfind(d), (size_t) a.as_string().rfind(std::string()));
-  ASSERT_EQ(a.rfind(e), a.as_string().rfind(std::string()));
+  ASSERT_EQ(a.rfind(c, 22U), Piece::npos);
+  ASSERT_EQ(a.rfind(c, 1U), Piece::npos);
+  ASSERT_EQ(a.rfind(c, 0U), Piece::npos);
+  ASSERT_EQ(b.rfind(c), Piece::npos);
+  ASSERT_EQ(b.rfind(c, 0U), Piece::npos);
+  ASSERT_EQ(a.rfind(d), static_cast<size_t>(a.as_string().rfind(TypeParam())));
+  ASSERT_EQ(a.rfind(e), a.as_string().rfind(TypeParam()));
   ASSERT_EQ(a.rfind(d, 12), 12U);
   ASSERT_EQ(a.rfind(e, 17), 17U);
-  ASSERT_EQ(a.rfind(g), StringPiece::npos);
-  ASSERT_EQ(d.rfind(b), StringPiece::npos);
-  ASSERT_EQ(e.rfind(b), StringPiece::npos);
-  ASSERT_EQ(d.rfind(b, 4), StringPiece::npos);
-  ASSERT_EQ(e.rfind(b, 7), StringPiece::npos);
+  ASSERT_EQ(a.rfind(g), Piece::npos);
+  ASSERT_EQ(d.rfind(b), Piece::npos);
+  ASSERT_EQ(e.rfind(b), Piece::npos);
+  ASSERT_EQ(d.rfind(b, 4), Piece::npos);
+  ASSERT_EQ(e.rfind(b, 7), Piece::npos);
   // empty string nonsense
   ASSERT_EQ(d.rfind(d, 4), std::string().rfind(std::string()));
   ASSERT_EQ(e.rfind(d, 7), std::string().rfind(std::string()));
@@ -303,80 +311,82 @@
   ASSERT_EQ(e.rfind(e), std::string().rfind(std::string()));
 
   ASSERT_EQ(g.rfind('o'), 8U);
-  ASSERT_EQ(g.rfind('q'), StringPiece::npos);
+  ASSERT_EQ(g.rfind('q'), Piece::npos);
   ASSERT_EQ(g.rfind('o', 8), 8U);
   ASSERT_EQ(g.rfind('o', 7), 4U);
-  ASSERT_EQ(g.rfind('o', 3), StringPiece::npos);
+  ASSERT_EQ(g.rfind('o', 3), Piece::npos);
   ASSERT_EQ(f.rfind('\0'), 3U);
   ASSERT_EQ(f.rfind('\0', 12), 3U);
   ASSERT_EQ(f.rfind('3'), 2U);
   ASSERT_EQ(f.rfind('5'), 5U);
   // empty string nonsense
-  ASSERT_EQ(d.rfind('o'), StringPiece::npos);
-  ASSERT_EQ(e.rfind('o'), StringPiece::npos);
-  ASSERT_EQ(d.rfind('o', 4), StringPiece::npos);
-  ASSERT_EQ(e.rfind('o', 7), StringPiece::npos);
+  ASSERT_EQ(d.rfind('o'), Piece::npos);
+  ASSERT_EQ(e.rfind('o'), Piece::npos);
+  ASSERT_EQ(d.rfind('o', 4), Piece::npos);
+  ASSERT_EQ(e.rfind('o', 7), Piece::npos);
 
-  ASSERT_EQ(
-      StringPiece("one,two:three;four").find_first_of(StringPiece(",:"), 1),
-      3U);
+  TypeParam one_two_three_four(TestFixture::as_string("one,two:three;four"));
+  TypeParam comma_colon(TestFixture::as_string(",:"));
+  ASSERT_EQ(3U, Piece(one_two_three_four).find_first_of(comma_colon));
   ASSERT_EQ(a.find_first_of(b), 0U);
   ASSERT_EQ(a.find_first_of(b, 0), 0U);
   ASSERT_EQ(a.find_first_of(b, 1), 1U);
   ASSERT_EQ(a.find_first_of(b, 2), 2U);
-  ASSERT_EQ(a.find_first_of(b, 3), StringPiece::npos);
+  ASSERT_EQ(a.find_first_of(b, 3), Piece::npos);
   ASSERT_EQ(a.find_first_of(c), 23U);
   ASSERT_EQ(a.find_first_of(c, 23), 23U);
   ASSERT_EQ(a.find_first_of(c, 24), 24U);
   ASSERT_EQ(a.find_first_of(c, 25), 25U);
-  ASSERT_EQ(a.find_first_of(c, 26), StringPiece::npos);
+  ASSERT_EQ(a.find_first_of(c, 26), Piece::npos);
   ASSERT_EQ(g.find_first_of(b), 13U);
   ASSERT_EQ(g.find_first_of(c), 0U);
-  ASSERT_EQ(a.find_first_of(f), StringPiece::npos);
-  ASSERT_EQ(f.find_first_of(a), StringPiece::npos);
+  ASSERT_EQ(a.find_first_of(f), Piece::npos);
+  ASSERT_EQ(f.find_first_of(a), Piece::npos);
   // empty string nonsense
-  ASSERT_EQ(a.find_first_of(d), StringPiece::npos);
-  ASSERT_EQ(a.find_first_of(e), StringPiece::npos);
-  ASSERT_EQ(d.find_first_of(b), StringPiece::npos);
-  ASSERT_EQ(e.find_first_of(b), StringPiece::npos);
-  ASSERT_EQ(d.find_first_of(d), StringPiece::npos);
-  ASSERT_EQ(e.find_first_of(d), StringPiece::npos);
-  ASSERT_EQ(d.find_first_of(e), StringPiece::npos);
-  ASSERT_EQ(e.find_first_of(e), StringPiece::npos);
+  ASSERT_EQ(a.find_first_of(d), Piece::npos);
+  ASSERT_EQ(a.find_first_of(e), Piece::npos);
+  ASSERT_EQ(d.find_first_of(b), Piece::npos);
+  ASSERT_EQ(e.find_first_of(b), Piece::npos);
+  ASSERT_EQ(d.find_first_of(d), Piece::npos);
+  ASSERT_EQ(e.find_first_of(d), Piece::npos);
+  ASSERT_EQ(d.find_first_of(e), Piece::npos);
+  ASSERT_EQ(e.find_first_of(e), Piece::npos);
 
   ASSERT_EQ(a.find_first_not_of(b), 3U);
   ASSERT_EQ(a.find_first_not_of(c), 0U);
-  ASSERT_EQ(b.find_first_not_of(a), StringPiece::npos);
-  ASSERT_EQ(c.find_first_not_of(a), StringPiece::npos);
+  ASSERT_EQ(b.find_first_not_of(a), Piece::npos);
+  ASSERT_EQ(c.find_first_not_of(a), Piece::npos);
   ASSERT_EQ(f.find_first_not_of(a), 0U);
   ASSERT_EQ(a.find_first_not_of(f), 0U);
   ASSERT_EQ(a.find_first_not_of(d), 0U);
   ASSERT_EQ(a.find_first_not_of(e), 0U);
   // empty string nonsense
-  ASSERT_EQ(d.find_first_not_of(a), StringPiece::npos);
-  ASSERT_EQ(e.find_first_not_of(a), StringPiece::npos);
-  ASSERT_EQ(d.find_first_not_of(d), StringPiece::npos);
-  ASSERT_EQ(e.find_first_not_of(d), StringPiece::npos);
-  ASSERT_EQ(d.find_first_not_of(e), StringPiece::npos);
-  ASSERT_EQ(e.find_first_not_of(e), StringPiece::npos);
+  ASSERT_EQ(d.find_first_not_of(a), Piece::npos);
+  ASSERT_EQ(e.find_first_not_of(a), Piece::npos);
+  ASSERT_EQ(d.find_first_not_of(d), Piece::npos);
+  ASSERT_EQ(e.find_first_not_of(d), Piece::npos);
+  ASSERT_EQ(d.find_first_not_of(e), Piece::npos);
+  ASSERT_EQ(e.find_first_not_of(e), Piece::npos);
 
-  StringPiece h("====");
-  ASSERT_EQ(h.find_first_not_of('='), StringPiece::npos);
-  ASSERT_EQ(h.find_first_not_of('=', 3), StringPiece::npos);
+  TypeParam equals(TestFixture::as_string("===="));
+  Piece h(equals);
+  ASSERT_EQ(h.find_first_not_of('='), Piece::npos);
+  ASSERT_EQ(h.find_first_not_of('=', 3), Piece::npos);
   ASSERT_EQ(h.find_first_not_of('\0'), 0U);
   ASSERT_EQ(g.find_first_not_of('x'), 2U);
   ASSERT_EQ(f.find_first_not_of('\0'), 0U);
   ASSERT_EQ(f.find_first_not_of('\0', 3), 4U);
   ASSERT_EQ(f.find_first_not_of('\0', 2), 2U);
   // empty string nonsense
-  ASSERT_EQ(d.find_first_not_of('x'), StringPiece::npos);
-  ASSERT_EQ(e.find_first_not_of('x'), StringPiece::npos);
-  ASSERT_EQ(d.find_first_not_of('\0'), StringPiece::npos);
-  ASSERT_EQ(e.find_first_not_of('\0'), StringPiece::npos);
+  ASSERT_EQ(d.find_first_not_of('x'), Piece::npos);
+  ASSERT_EQ(e.find_first_not_of('x'), Piece::npos);
+  ASSERT_EQ(d.find_first_not_of('\0'), Piece::npos);
+  ASSERT_EQ(e.find_first_not_of('\0'), Piece::npos);
 
-  //  StringPiece g("xx not found bb");
-  StringPiece i("56");
-  ASSERT_EQ(h.find_last_of(a), StringPiece::npos);
+  //  Piece g("xx not found bb");
+  TypeParam fifty_six(TestFixture::as_string("56"));
+  Piece i(fifty_six);
+  ASSERT_EQ(h.find_last_of(a), Piece::npos);
   ASSERT_EQ(g.find_last_of(a), g.size()-1);
   ASSERT_EQ(a.find_last_of(b), 2U);
   ASSERT_EQ(a.find_last_of(c), a.size()-1);
@@ -386,74 +396,74 @@
   ASSERT_EQ(a.find_last_of('z'), 25U);
   ASSERT_EQ(a.find_last_of('a', 5), 0U);
   ASSERT_EQ(a.find_last_of('b', 5), 1U);
-  ASSERT_EQ(a.find_last_of('b', 0), StringPiece::npos);
+  ASSERT_EQ(a.find_last_of('b', 0), Piece::npos);
   ASSERT_EQ(a.find_last_of('z', 25), 25U);
-  ASSERT_EQ(a.find_last_of('z', 24), StringPiece::npos);
+  ASSERT_EQ(a.find_last_of('z', 24), Piece::npos);
   ASSERT_EQ(f.find_last_of(i, 5), 5U);
   ASSERT_EQ(f.find_last_of(i, 6), 6U);
-  ASSERT_EQ(f.find_last_of(a, 4), StringPiece::npos);
+  ASSERT_EQ(f.find_last_of(a, 4), Piece::npos);
   // empty string nonsense
-  ASSERT_EQ(f.find_last_of(d), StringPiece::npos);
-  ASSERT_EQ(f.find_last_of(e), StringPiece::npos);
-  ASSERT_EQ(f.find_last_of(d, 4), StringPiece::npos);
-  ASSERT_EQ(f.find_last_of(e, 4), StringPiece::npos);
-  ASSERT_EQ(d.find_last_of(d), StringPiece::npos);
-  ASSERT_EQ(d.find_last_of(e), StringPiece::npos);
-  ASSERT_EQ(e.find_last_of(d), StringPiece::npos);
-  ASSERT_EQ(e.find_last_of(e), StringPiece::npos);
-  ASSERT_EQ(d.find_last_of(f), StringPiece::npos);
-  ASSERT_EQ(e.find_last_of(f), StringPiece::npos);
-  ASSERT_EQ(d.find_last_of(d, 4), StringPiece::npos);
-  ASSERT_EQ(d.find_last_of(e, 4), StringPiece::npos);
-  ASSERT_EQ(e.find_last_of(d, 4), StringPiece::npos);
-  ASSERT_EQ(e.find_last_of(e, 4), StringPiece::npos);
-  ASSERT_EQ(d.find_last_of(f, 4), StringPiece::npos);
-  ASSERT_EQ(e.find_last_of(f, 4), StringPiece::npos);
+  ASSERT_EQ(f.find_last_of(d), Piece::npos);
+  ASSERT_EQ(f.find_last_of(e), Piece::npos);
+  ASSERT_EQ(f.find_last_of(d, 4), Piece::npos);
+  ASSERT_EQ(f.find_last_of(e, 4), Piece::npos);
+  ASSERT_EQ(d.find_last_of(d), Piece::npos);
+  ASSERT_EQ(d.find_last_of(e), Piece::npos);
+  ASSERT_EQ(e.find_last_of(d), Piece::npos);
+  ASSERT_EQ(e.find_last_of(e), Piece::npos);
+  ASSERT_EQ(d.find_last_of(f), Piece::npos);
+  ASSERT_EQ(e.find_last_of(f), Piece::npos);
+  ASSERT_EQ(d.find_last_of(d, 4), Piece::npos);
+  ASSERT_EQ(d.find_last_of(e, 4), Piece::npos);
+  ASSERT_EQ(e.find_last_of(d, 4), Piece::npos);
+  ASSERT_EQ(e.find_last_of(e, 4), Piece::npos);
+  ASSERT_EQ(d.find_last_of(f, 4), Piece::npos);
+  ASSERT_EQ(e.find_last_of(f, 4), Piece::npos);
 
   ASSERT_EQ(a.find_last_not_of(b), a.size()-1);
   ASSERT_EQ(a.find_last_not_of(c), 22U);
-  ASSERT_EQ(b.find_last_not_of(a), StringPiece::npos);
-  ASSERT_EQ(b.find_last_not_of(b), StringPiece::npos);
+  ASSERT_EQ(b.find_last_not_of(a), Piece::npos);
+  ASSERT_EQ(b.find_last_not_of(b), Piece::npos);
   ASSERT_EQ(f.find_last_not_of(i), 4U);
   ASSERT_EQ(a.find_last_not_of(c, 24), 22U);
   ASSERT_EQ(a.find_last_not_of(b, 3), 3U);
-  ASSERT_EQ(a.find_last_not_of(b, 2), StringPiece::npos);
+  ASSERT_EQ(a.find_last_not_of(b, 2), Piece::npos);
   // empty string nonsense
   ASSERT_EQ(f.find_last_not_of(d), f.size()-1);
   ASSERT_EQ(f.find_last_not_of(e), f.size()-1);
   ASSERT_EQ(f.find_last_not_of(d, 4), 4U);
   ASSERT_EQ(f.find_last_not_of(e, 4), 4U);
-  ASSERT_EQ(d.find_last_not_of(d), StringPiece::npos);
-  ASSERT_EQ(d.find_last_not_of(e), StringPiece::npos);
-  ASSERT_EQ(e.find_last_not_of(d), StringPiece::npos);
-  ASSERT_EQ(e.find_last_not_of(e), StringPiece::npos);
-  ASSERT_EQ(d.find_last_not_of(f), StringPiece::npos);
-  ASSERT_EQ(e.find_last_not_of(f), StringPiece::npos);
-  ASSERT_EQ(d.find_last_not_of(d, 4), StringPiece::npos);
-  ASSERT_EQ(d.find_last_not_of(e, 4), StringPiece::npos);
-  ASSERT_EQ(e.find_last_not_of(d, 4), StringPiece::npos);
-  ASSERT_EQ(e.find_last_not_of(e, 4), StringPiece::npos);
-  ASSERT_EQ(d.find_last_not_of(f, 4), StringPiece::npos);
-  ASSERT_EQ(e.find_last_not_of(f, 4), StringPiece::npos);
+  ASSERT_EQ(d.find_last_not_of(d), Piece::npos);
+  ASSERT_EQ(d.find_last_not_of(e), Piece::npos);
+  ASSERT_EQ(e.find_last_not_of(d), Piece::npos);
+  ASSERT_EQ(e.find_last_not_of(e), Piece::npos);
+  ASSERT_EQ(d.find_last_not_of(f), Piece::npos);
+  ASSERT_EQ(e.find_last_not_of(f), Piece::npos);
+  ASSERT_EQ(d.find_last_not_of(d, 4), Piece::npos);
+  ASSERT_EQ(d.find_last_not_of(e, 4), Piece::npos);
+  ASSERT_EQ(e.find_last_not_of(d, 4), Piece::npos);
+  ASSERT_EQ(e.find_last_not_of(e, 4), Piece::npos);
+  ASSERT_EQ(d.find_last_not_of(f, 4), Piece::npos);
+  ASSERT_EQ(e.find_last_not_of(f, 4), Piece::npos);
 
   ASSERT_EQ(h.find_last_not_of('x'), h.size() - 1);
-  ASSERT_EQ(h.find_last_not_of('='), StringPiece::npos);
+  ASSERT_EQ(h.find_last_not_of('='), Piece::npos);
   ASSERT_EQ(b.find_last_not_of('c'), 1U);
   ASSERT_EQ(h.find_last_not_of('x', 2), 2U);
-  ASSERT_EQ(h.find_last_not_of('=', 2), StringPiece::npos);
+  ASSERT_EQ(h.find_last_not_of('=', 2), Piece::npos);
   ASSERT_EQ(b.find_last_not_of('b', 1), 0U);
   // empty string nonsense
-  ASSERT_EQ(d.find_last_not_of('x'), StringPiece::npos);
-  ASSERT_EQ(e.find_last_not_of('x'), StringPiece::npos);
-  ASSERT_EQ(d.find_last_not_of('\0'), StringPiece::npos);
-  ASSERT_EQ(e.find_last_not_of('\0'), StringPiece::npos);
+  ASSERT_EQ(d.find_last_not_of('x'), Piece::npos);
+  ASSERT_EQ(e.find_last_not_of('x'), Piece::npos);
+  ASSERT_EQ(d.find_last_not_of('\0'), Piece::npos);
+  ASSERT_EQ(e.find_last_not_of('\0'), Piece::npos);
 
   ASSERT_EQ(a.substr(0, 3), b);
   ASSERT_EQ(a.substr(23), c);
   ASSERT_EQ(a.substr(23, 3), c);
   ASSERT_EQ(a.substr(23, 99), c);
   ASSERT_EQ(a.substr(0), a);
-  ASSERT_EQ(a.substr(3, 2), "de");
+  ASSERT_EQ(a.substr(3, 2), TestFixture::as_string("de"));
   // empty string nonsense
   ASSERT_EQ(a.substr(99, 2), e);
   ASSERT_EQ(d.substr(99), e);
@@ -561,11 +571,11 @@
   ASSERT_TRUE(!e.ends_with(a));
 
   StringPiece c;
-  c.set(static_cast<const void*>("foobar"), 6);
+  c.set("foobar", 6);
   ASSERT_EQ(c, a);
-  c.set(static_cast<const void*>("foobar"), 0);
+  c.set("foobar", 0);
   ASSERT_EQ(c, e);
-  c.set(static_cast<const void*>("foobar"), 7);
+  c.set("foobar", 7);
   ASSERT_NE(c, a);
 }
 
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc
index 85dad8c..d4ed6f8 100644
--- a/net/websockets/websocket_basic_handshake_stream.cc
+++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -225,7 +225,7 @@
 
 bool DeflateError(std::string* message, const base::StringPiece& piece) {
   *message = "Error in permessage-deflate: ";
-  AppendToString(piece, message);
+  piece.AppendToString(message);
   return false;
 }
 
diff --git a/ui/base/resource/data_pack.cc b/ui/base/resource/data_pack.cc
index 934b14b..ac5ff4f 100644
--- a/ui/base/resource/data_pack.cc
+++ b/ui/base/resource/data_pack.cc
@@ -190,7 +190,8 @@
   const DataPackEntry* next_entry = target + 1;
   size_t length = next_entry->file_offset - target->file_offset;
 
-  data->set(mmap_->data() + target->file_offset, length);
+  data->set(reinterpret_cast<const char*>(mmap_->data() + target->file_offset),
+            length);
   return true;
 }