Define StringPiece in terms of std::string_view

This is possible now that we have C++17 support. The typedef is left as
a temporary transition artifact and will be removed in a later pass.

Most changes are to remove calls to as_string and related differences.

Change-Id: I83c2c1f84802a5d08f825e6b14a4640c3e22fb75
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/6021
Commit-Queue: Brett Wilson <brettw@chromium.org>
Reviewed-by: Scott Graham <scottmg@chromium.org>
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index f0e1acb..3ecb009 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -171,7 +171,7 @@
 FilePath::FilePath(FilePath&& that) noexcept = default;
 
 FilePath::FilePath(StringPieceType path) {
-  path.CopyToString(&path_);
+  path_.assign(path);
   StringType::size_type nul_pos = path_.find(kStringTerminator);
   if (nul_pos != StringType::npos)
     path_.erase(nul_pos, StringType::npos);
@@ -401,7 +401,7 @@
 
   StringType ext = Extension();
   StringType ret = RemoveExtension().value();
-  suffix.AppendToString(&ret);
+  ret.append(suffix);
   ret.append(ext);
   return FilePath(ret);
 }
@@ -429,7 +429,7 @@
       *(str.end() - 1) != kExtensionSeparator) {
     str.append(1, kExtensionSeparator);
   }
-  extension.AppendToString(&str);
+  str.append(extension);
   return FilePath(str);
 }
 
@@ -446,7 +446,7 @@
   StringType str = no_ext.value();
   if (extension[0] != kExtensionSeparator)
     str.append(1, kExtensionSeparator);
-  extension.AppendToString(&str);
+  str.append(extension);
   return FilePath(str);
 }
 
@@ -456,7 +456,7 @@
 
   StringType::size_type nul_pos = component.find(kStringTerminator);
   if (nul_pos != StringPieceType::npos) {
-    component.substr(0, nul_pos).CopyToString(&without_nuls);
+    without_nuls.assign(component.substr(0, nul_pos));
     appended = StringPieceType(without_nuls);
   }
 
@@ -490,7 +490,7 @@
     }
   }
 
-  appended.AppendToString(&new_path.path_);
+  new_path.path_.append(appended);
   return new_path;
 }
 
diff --git a/base/files/file_path.h b/base/files/file_path.h
index a85c1aa..a8322c4 100644
--- a/base/files/file_path.h
+++ b/base/files/file_path.h
@@ -152,8 +152,8 @@
   typedef std::string StringType;
 #endif  // OS_WIN
 
-  typedef BasicStringPiece<StringType> StringPieceType;
-  typedef StringType::value_type CharType;
+  using CharType = StringType::value_type;
+  using StringPieceType = std::basic_string_view<CharType>;
 
   // Null-terminated array of separators used to separate components in
   // hierarchical paths.  Each character in this array is a valid separator,
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc
index 966abc0..0749ac9 100644
--- a/base/files/file_util_posix.cc
+++ b/base/files/file_util_posix.cc
@@ -184,7 +184,7 @@
 // https://www.gnu.org/software/libc/manual/html_node/Opening-Streams.html for
 // details.
 std::string AppendModeCharacter(StringPiece mode, char mode_char) {
-  std::string result(mode.as_string());
+  std::string result(mode);
   size_t comma_pos = result.find(',');
   result.insert(comma_pos == std::string::npos ? result.length() : comma_pos, 1,
                 mode_char);
diff --git a/base/logging.h b/base/logging.h
index 95c96ed..cba1c55 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -17,7 +17,7 @@
 #include "base/callback_forward.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/template_util.h"
 #include "util/build_config.h"
 
diff --git a/base/md5.cc b/base/md5.cc
index c66f7b2..0b50e56 100644
--- a/base/md5.cc
+++ b/base/md5.cc
@@ -24,6 +24,7 @@
 #include "base/md5.h"
 
 #include <stddef.h>
+#include <string.h>
 
 namespace {
 
diff --git a/base/md5.h b/base/md5.h
index 16a0a6f..802645c 100644
--- a/base/md5.h
+++ b/base/md5.h
@@ -8,6 +8,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <string>
+
 #include "base/strings/string_piece.h"
 
 namespace base {
diff --git a/base/strings/string_number_conversions.cc b/base/strings/string_number_conversions.cc
index 01375f5..5f94a56 100644
--- a/base/strings/string_number_conversions.cc
+++ b/base/strings/string_number_conversions.cc
@@ -112,9 +112,9 @@
 };
 
 template <>
-class WhitespaceHelper<char16> {
+class WhitespaceHelper<char16_t> {
  public:
-  static bool Invoke(char16 c) { return 0 != iswspace(c); }
+  static bool Invoke(char16_t c) { return 0 != iswspace(c); }
 };
 
 template <typename CHAR>
diff --git a/base/strings/string_piece.cc b/base/strings/string_piece.cc
deleted file mode 100644
index 612298a..0000000
--- a/base/strings/string_piece.cc
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-// Copied from strings/stringpiece.cc with modifications
-
-#include "base/strings/string_piece.h"
-
-#include <limits.h>
-
-#include <algorithm>
-#include <ostream>
-
-#include "base/logging.h"
-
-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)
-template class BasicStringPiece<std::string>;
-template class BasicStringPiece<string16>;
-#endif
-
-bool operator==(const StringPiece& x, const StringPiece& y) {
-  if (x.size() != y.size())
-    return false;
-
-  return CharTraits<StringPiece::value_type>::compare(x.data(), y.data(),
-                                                      x.size()) == 0;
-}
-
-std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
-  o.write(piece.data(), static_cast<std::streamsize>(piece.size()));
-  return o;
-}
-
-namespace internal {
-
-template <typename STR>
-void CopyToStringT(const BasicStringPiece<STR>& self, STR* target) {
-  if (self.empty())
-    target->clear();
-  else
-    target->assign(self.data(), self.size());
-}
-
-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());
-}
-
-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;
-}
-
-size_t copy(const StringPiece& self, char* buf, size_t n, size_t pos) {
-  return copyT(self, buf, n, pos);
-}
-
-size_t copy(const StringPiece16& self, char16* buf, size_t n, size_t pos) {
-  return copyT(self, buf, n, pos);
-}
-
-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())
-                              : BasicStringPiece<STR>::npos;
-}
-
-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 BasicStringPiece<STR>::npos;
-
-  if (s.empty())
-    return std::min(self.size(), pos);
-
-  typename BasicStringPiece<STR>::const_iterator last =
-      self.begin() + std::min(self.size() - s.size(), pos) + s.size();
-  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())
-                        : BasicStringPiece<STR>::npos;
-}
-
-size_t rfind(const StringPiece& self, const StringPiece& s, size_t pos) {
-  return rfindT(self, s, pos);
-}
-
-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 BasicStringPiece<STR>::npos;
-}
-
-size_t rfind(const StringPiece& self, char c, size_t pos) {
-  return rfindT(self, c, 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;
-
-  // Avoid the cost of BuildLookupTable() for a single-character search.
-  if (s.size() == 1)
-    return find(self, s.data()[0], pos);
-
-  bool lookup[UCHAR_MAX + 1] = {false};
-  BuildLookupTable(s, lookup);
-  for (size_t i = pos; i < self.size(); ++i) {
-    if (lookup[static_cast<unsigned char>(self.data()[i])]) {
-      return i;
-    }
-  }
-  return StringPiece::npos;
-}
-
-// 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;
-
-  if (s.size() == 0)
-    return 0;
-
-  // Avoid the cost of BuildLookupTable() for a single-character search.
-  if (s.size() == 1)
-    return find_first_not_of(self, s.data()[0], pos);
-
-  bool lookup[UCHAR_MAX + 1] = {false};
-  BuildLookupTable(s, lookup);
-  for (size_t i = pos; i < self.size(); ++i) {
-    if (!lookup[static_cast<unsigned char>(self.data()[i])]) {
-      return i;
-    }
-  }
-  return StringPiece::npos;
-}
-
-// 16-bit brute-force version.
-size_t find_first_not_of(const StringPiece16& self,
-                         const StringPiece16& s,
-                         size_t pos) {
-  if (self.size() == 0)
-    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 BasicStringPiece<STR>::npos;
-}
-
-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;
-
-  // Avoid the cost of BuildLookupTable() for a single-character search.
-  if (s.size() == 1)
-    return rfind(self, s.data()[0], pos);
-
-  bool lookup[UCHAR_MAX + 1] = {false};
-  BuildLookupTable(s, lookup);
-  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)
-      break;
-  }
-  return StringPiece::npos;
-}
-
-// 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;
-
-  size_t i = std::min(pos, self.size() - 1);
-  if (s.size() == 0)
-    return i;
-
-  // Avoid the cost of BuildLookupTable() for a single-character search.
-  if (s.size() == 1)
-    return find_last_not_of(self, s.data()[0], pos);
-
-  bool lookup[UCHAR_MAX + 1] = {false};
-  BuildLookupTable(s, lookup);
-  for (;; --i) {
-    if (!lookup[static_cast<unsigned char>(self.data()[i])])
-      return i;
-    if (i == 0)
-      break;
-  }
-  return StringPiece::npos;
-}
-
-// 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 (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 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, 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);
-}
-
-#if DCHECK_IS_ON()
-void AssertIteratorsInOrder(std::string::const_iterator begin,
-                            std::string::const_iterator end) {
-  DCHECK(begin <= end) << "StringPiece iterators swapped or invalid.";
-}
-void AssertIteratorsInOrder(string16::const_iterator begin,
-                            string16::const_iterator end) {
-  DCHECK(begin <= end) << "StringPiece iterators swapped or invalid.";
-}
-#endif
-
-}  // namespace internal
-}  // namespace base
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index 0722269..fa215ef 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -22,412 +22,15 @@
 #ifndef BASE_STRINGS_STRING_PIECE_H_
 #define BASE_STRINGS_STRING_PIECE_H_
 
-#include <stddef.h>
-
-#include <iosfwd>
-#include <string>
-
-#include "base/logging.h"
-#include "base/strings/char_traits.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_piece_forward.h"
+#include <string_view>
 
 namespace base {
 
-// 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 {
-
-void CopyToString(const StringPiece& self, std::string* target);
-void CopyToString(const StringPiece16& self, string16* target);
-
-void AppendToString(const StringPiece& self, std::string* target);
-void AppendToString(const StringPiece16& self, string16* target);
-
-size_t copy(const StringPiece& self, char* buf, size_t n, size_t pos);
-size_t copy(const StringPiece16& self, char16* buf, size_t n, size_t pos);
-
-size_t find(const StringPiece& self, const StringPiece& s, size_t pos);
-size_t find(const StringPiece16& self, const StringPiece16& s, size_t pos);
-size_t find(const StringPiece& self, char c, size_t pos);
-size_t find(const StringPiece16& self, char16 c, size_t pos);
-
-size_t rfind(const StringPiece& self, const StringPiece& s, size_t pos);
-size_t rfind(const StringPiece16& self, const StringPiece16& s, size_t pos);
-size_t rfind(const StringPiece& self, char c, size_t pos);
-size_t rfind(const StringPiece16& self, char16 c, size_t pos);
-
-size_t find_first_of(const StringPiece& self, const StringPiece& s, size_t pos);
-size_t find_first_of(const StringPiece16& self,
-                     const StringPiece16& s,
-                     size_t pos);
-
-size_t find_first_not_of(const StringPiece& self,
-                         const StringPiece& s,
-                         size_t pos);
-size_t find_first_not_of(const StringPiece16& self,
-                         const StringPiece16& s,
-                         size_t pos);
-size_t find_first_not_of(const StringPiece& self, char c, size_t pos);
-size_t find_first_not_of(const StringPiece16& self, char16 c, size_t pos);
-
-size_t find_last_of(const StringPiece& self, const StringPiece& s, size_t pos);
-size_t find_last_of(const StringPiece16& self,
-                    const StringPiece16& s,
-                    size_t pos);
-size_t find_last_of(const StringPiece& self, char c, size_t pos);
-size_t find_last_of(const StringPiece16& self, char16 c, size_t pos);
-
-size_t find_last_not_of(const StringPiece& self,
-                        const StringPiece& s,
-                        size_t pos);
-size_t find_last_not_of(const StringPiece16& self,
-                        const StringPiece16& s,
-                        size_t pos);
-size_t find_last_not_of(const StringPiece16& self, char16 c, size_t pos);
-size_t find_last_not_of(const StringPiece& self, char c, size_t pos);
-
-StringPiece substr(const StringPiece& self, size_t pos, size_t n);
-StringPiece16 substr(const StringPiece16& self, size_t pos, size_t n);
-
-#if DCHECK_IS_ON()
-// Asserts that begin <= end to catch some errors with iterator usage.
-void AssertIteratorsInOrder(std::string::const_iterator begin,
-                            std::string::const_iterator end);
-void AssertIteratorsInOrder(string16::const_iterator begin,
-                            string16::const_iterator end);
-#endif
-
-}  // 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.
-//
-// 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.
-  typedef size_t size_type;
-  typedef typename STRING_TYPE::value_type value_type;
-  typedef const value_type* pointer;
-  typedef const value_type& reference;
-  typedef const value_type& const_reference;
-  typedef ptrdiff_t difference_type;
-  typedef const value_type* const_iterator;
-  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-  static const size_type npos;
-
- public:
-  // 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).
-  constexpr BasicStringPiece() : ptr_(NULL), length_(0) {}
-  // TODO(dcheng): Construction from nullptr is not allowed for
-  // std::basic_string_view, so remove the special handling for it.
-  // Note: This doesn't just use STRING_TYPE::traits_type::length(), since that
-  // isn't constexpr until C++17.
-  constexpr BasicStringPiece(const value_type* str)
-      : ptr_(str), length_(!str ? 0 : CharTraits<value_type>::length(str)) {}
-  BasicStringPiece(const STRING_TYPE& str)
-      : ptr_(str.data()), length_(str.size()) {}
-  constexpr BasicStringPiece(const value_type* offset, size_type len)
-      : ptr_(offset), length_(len) {}
-  BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
-                   const typename STRING_TYPE::const_iterator& end) {
-#if DCHECK_IS_ON()
-    // This assertion is done out-of-line to avoid bringing in logging.h and
-    // instantiating logging macros for every instantiation.
-    internal::AssertIteratorsInOrder(begin, end);
-#endif
-    length_ = static_cast<size_t>(std::distance(begin, end));
-
-    // The length test before assignment is to avoid dereferencing an iterator
-    // that may point to the end() of a string.
-    ptr_ = length_ > 0 ? &*begin : nullptr;
-  }
-
-  // data() may return a pointer to a buffer with embedded NULs, and the
-  // returned buffer may or may not be null terminated.  Therefore it is
-  // typically a mistake to pass data() to a routine that expects a NUL
-  // terminated string.
-  constexpr const value_type* data() const { return ptr_; }
-  constexpr size_type size() const { return length_; }
-  constexpr size_type length() const { return length_; }
-  bool empty() const { return length_ == 0; }
-
-  void clear() {
-    ptr_ = NULL;
-    length_ = 0;
-  }
-  void set(const value_type* data, size_type len) {
-    ptr_ = data;
-    length_ = len;
-  }
-  void set(const value_type* str) {
-    ptr_ = str;
-    length_ = str ? STRING_TYPE::traits_type::length(str) : 0;
-  }
-
-  constexpr value_type operator[](size_type i) const {
-    CHECK(i < length_);
-    return ptr_[i];
-  }
-
-  value_type front() const {
-    CHECK_NE(0UL, length_);
-    return ptr_[0];
-  }
-
-  value_type back() const {
-    CHECK_NE(0UL, length_);
-    return ptr_[length_ - 1];
-  }
-
-  constexpr void remove_prefix(size_type n) {
-    CHECK(n <= length_);
-    ptr_ += n;
-    length_ -= n;
-  }
-
-  constexpr void remove_suffix(size_type n) {
-    CHECK(n <= length_);
-    length_ -= n;
-  }
-
-  constexpr int compare(BasicStringPiece x) const noexcept {
-    int r = CharTraits<value_type>::compare(
-        ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
-    if (r == 0) {
-      if (length_ < x.length_)
-        r = -1;
-      else if (length_ > x.length_)
-        r = +1;
-    }
-    return r;
-  }
-
-  // This is the style of conversion preferred by std::string_view in C++17.
-  explicit operator STRING_TYPE() const { return as_string(); }
-
-  STRING_TYPE as_string() const {
-    // std::string doesn't like to take a NULL pointer even with a 0 size.
-    return empty() ? STRING_TYPE() : STRING_TYPE(data(), size());
-  }
-
-  const_iterator begin() const { return ptr_; }
-  const_iterator end() const { return ptr_ + length_; }
-  const_reverse_iterator rbegin() const {
-    return const_reverse_iterator(ptr_ + length_);
-  }
-  const_reverse_iterator rend() const { return const_reverse_iterator(ptr_); }
-
-  size_type max_size() const { return length_; }
-  size_type capacity() const { return length_; }
-
-  // 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"
-  constexpr bool starts_with(BasicStringPiece x) const noexcept {
-    return (
-        (this->length_ >= x.length_) &&
-        (CharTraits<value_type>::compare(this->ptr_, x.ptr_, x.length_) == 0));
-  }
-
-  // Does "this" end with "x"
-  constexpr bool ends_with(BasicStringPiece x) const noexcept {
-    return ((this->length_ >= x.length_) &&
-            (CharTraits<value_type>::compare(
-                 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 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 BasicStringPiece<std::string>;
-extern template class BasicStringPiece<string16>;
-#endif
-
-// StingPiece operators --------------------------------------------------------
-
-bool operator==(const StringPiece& x, const StringPiece& y);
-
-inline bool operator!=(const StringPiece& x, const StringPiece& y) {
-  return !(x == y);
-}
-
-inline bool operator<(const StringPiece& x, const StringPiece& y) {
-  const int r = CharTraits<StringPiece::value_type>::compare(
-      x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
-  return ((r < 0) || ((r == 0) && (x.size() < y.size())));
-}
-
-inline bool operator>(const StringPiece& x, const StringPiece& y) {
-  return y < x;
-}
-
-inline bool operator<=(const StringPiece& x, const StringPiece& y) {
-  return !(x > y);
-}
-
-inline bool operator>=(const StringPiece& x, const StringPiece& y) {
-  return !(x < y);
-}
-
-// StringPiece16 operators -----------------------------------------------------
-
-inline bool operator==(const StringPiece16& x, const StringPiece16& y) {
-  if (x.size() != y.size())
-    return false;
-
-  return CharTraits<StringPiece16::value_type>::compare(x.data(), y.data(),
-                                                        x.size()) == 0;
-}
-
-inline bool operator!=(const StringPiece16& x, const StringPiece16& y) {
-  return !(x == y);
-}
-
-inline bool operator<(const StringPiece16& x, const StringPiece16& y) {
-  const int r = CharTraits<StringPiece16::value_type>::compare(
-      x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
-  return ((r < 0) || ((r == 0) && (x.size() < y.size())));
-}
-
-inline bool operator>(const StringPiece16& x, const StringPiece16& y) {
-  return y < x;
-}
-
-inline bool operator<=(const StringPiece16& x, const StringPiece16& y) {
-  return !(x > y);
-}
-
-inline bool operator>=(const StringPiece16& x, const StringPiece16& y) {
-  return !(x < y);
-}
-
-std::ostream& operator<<(std::ostream& o, const StringPiece& piece);
-
-// Hashing ---------------------------------------------------------------------
-
-// We provide appropriate hash functions so StringPiece and StringPiece16 can
-// be used as keys in hash sets and maps.
-
-// This hash function is copied from base/strings/string16.h. We don't use the
-// ones already defined for string and string16 directly because it would
-// require the string constructors to be called, which we don't want.
-#define HASH_STRING_PIECE(StringPieceType, string_piece)         \
-  std::size_t result = 0;                                        \
-  for (StringPieceType::const_iterator i = string_piece.begin(); \
-       i != string_piece.end(); ++i)                             \
-    result = (result * 131) + *i;                                \
-  return result;
-
-struct StringPieceHash {
-  std::size_t operator()(const StringPiece& sp) const {
-    HASH_STRING_PIECE(StringPiece, sp);
-  }
-};
-struct StringPiece16Hash {
-  std::size_t operator()(const StringPiece16& sp16) const {
-    HASH_STRING_PIECE(StringPiece16, sp16);
-  }
-};
+// Temporary definitions. These should be removed and code using the standard
+// ones.
+using StringPiece = std::string_view;
+using StringPiece16 = std::u16string_view;
+using WStringPiece = std::wstring_view;
 
 }  // namespace base
 
diff --git a/base/strings/string_piece_forward.h b/base/strings/string_piece_forward.h
deleted file mode 100644
index 86c1d5f..0000000
--- a/base/strings/string_piece_forward.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Forward declaration of StringPiece types from base/strings/string_piece.h
-
-#ifndef BASE_STRINGS_STRING_PIECE_FORWARD_H_
-#define BASE_STRINGS_STRING_PIECE_FORWARD_H_
-
-#include <string>
-
-#include "base/strings/string16.h"
-
-namespace base {
-
-template <typename STRING_TYPE>
-class BasicStringPiece;
-typedef BasicStringPiece<std::string> StringPiece;
-typedef BasicStringPiece<string16> StringPiece16;
-
-}  // namespace base
-
-#endif  // BASE_STRINGS_STRING_PIECE_FORWARD_H_
diff --git a/base/strings/string_split.cc b/base/strings/string_split.cc
index e9b5c96..a57d537 100644
--- a/base/strings/string_split.cc
+++ b/base/strings/string_split.cc
@@ -14,34 +14,15 @@
 
 namespace {
 
-// PieceToOutputType converts a StringPiece as needed to a given output type,
-// which is either the same type of StringPiece (a NOP) or the corresponding
-// non-piece string type.
-//
-// The default converter is a NOP, it works when the OutputType is the
-// correct StringPiece.
-template <typename Str, typename OutputType>
-OutputType PieceToOutputType(BasicStringPiece<Str> piece) {
-  return piece;
-}
-template <>  // Convert StringPiece to std::string
-std::string PieceToOutputType<std::string, std::string>(StringPiece piece) {
-  return piece.as_string();
-}
-template <>  // Convert StringPiece16 to string16.
-string16 PieceToOutputType<string16, string16>(StringPiece16 piece) {
-  return piece.as_string();
-}
-
 // Returns either the ASCII or UTF-16 whitespace.
-template <typename Str>
-BasicStringPiece<Str> WhitespaceForType();
+template <typename char_type>
+std::basic_string_view<char_type> WhitespaceForType();
 template <>
-StringPiece16 WhitespaceForType<string16>() {
+StringPiece16 WhitespaceForType<char16_t>() {
   return kWhitespaceUTF16;
 }
 template <>
-StringPiece WhitespaceForType<std::string>() {
+StringPiece WhitespaceForType<char>() {
   return kWhitespaceASCII;
 }
 
@@ -69,36 +50,39 @@
 // multiple-character delimiters.
 //
 // DelimiterType is either a character (Str::value_type) or a string piece of
-// multiple characters (BasicStringPiece<Str>). StringPiece has a version of
-// find for both of these cases, and the single-character version is the most
+// multiple characters (std::basic_string_view<char>). StringPiece has a version
+// of find for both of these cases, and the single-character version is the most
 // common and can be implemented faster, which is why this is a template.
-template <typename Str, typename OutputStringType, typename DelimiterType>
-static std::vector<OutputStringType> SplitStringT(BasicStringPiece<Str> str,
-                                                  DelimiterType delimiter,
-                                                  WhitespaceHandling whitespace,
-                                                  SplitResult result_type) {
+template <typename char_type, typename OutputStringType, typename DelimiterType>
+static std::vector<OutputStringType> SplitStringT(
+    std::basic_string_view<char_type> str,
+    DelimiterType delimiter,
+    WhitespaceHandling whitespace,
+    SplitResult result_type) {
   std::vector<OutputStringType> result;
   if (str.empty())
     return result;
 
+  using ViewType = std::basic_string_view<char_type>;
+
   size_t start = 0;
-  while (start != Str::npos) {
+  while (start != ViewType::npos) {
     size_t end = FindFirstOf(str, delimiter, start);
 
-    BasicStringPiece<Str> piece;
-    if (end == Str::npos) {
+    ViewType piece;
+    if (end == ViewType::npos) {
       piece = str.substr(start);
-      start = Str::npos;
+      start = ViewType::npos;
     } else {
       piece = str.substr(start, end - start);
       start = end + 1;
     }
 
     if (whitespace == TRIM_WHITESPACE)
-      piece = TrimString(piece, WhitespaceForType<Str>(), TRIM_ALL);
+      piece = TrimString(piece, WhitespaceForType<char_type>(), TRIM_ALL);
 
     if (result_type == SPLIT_WANT_ALL || !piece.empty())
-      result.push_back(PieceToOutputType<Str, OutputStringType>(piece));
+      result.emplace_back(piece);
   }
   return result;
 }
@@ -116,7 +100,7 @@
   if (end_key_pos == std::string::npos) {
     return false;  // No delimiter.
   }
-  input.substr(0, end_key_pos).CopyToString(&result_pair.first);
+  result_pair.first.assign(input.substr(0, end_key_pos));
 
   // Find the value string.
   StringPiece remains = input.substr(end_key_pos, input.size() - end_key_pos);
@@ -124,19 +108,19 @@
   if (begin_value_pos == StringPiece::npos) {
     return false;  // No value.
   }
-  remains.substr(begin_value_pos, remains.size() - begin_value_pos)
-      .CopyToString(&result_pair.second);
+  result_pair.second.assign(
+      remains.substr(begin_value_pos, remains.size() - begin_value_pos));
 
   return true;
 }
 
-template <typename Str, typename OutputStringType>
-void SplitStringUsingSubstrT(BasicStringPiece<Str> input,
-                             BasicStringPiece<Str> delimiter,
+template <typename char_type, typename OutputStringType>
+void SplitStringUsingSubstrT(std::basic_string_view<char_type> input,
+                             std::basic_string_view<char_type> delimiter,
                              WhitespaceHandling whitespace,
                              SplitResult result_type,
                              std::vector<OutputStringType>* result) {
-  using Piece = BasicStringPiece<Str>;
+  using Piece = std::basic_string_view<char_type>;
   using size_type = typename Piece::size_type;
 
   result->clear();
@@ -148,10 +132,10 @@
                      : input.substr(begin_index, end_index - begin_index);
 
     if (whitespace == TRIM_WHITESPACE)
-      term = TrimString(term, WhitespaceForType<Str>(), TRIM_ALL);
+      term = TrimString(term, WhitespaceForType<char_type>(), TRIM_ALL);
 
     if (result_type == SPLIT_WANT_ALL || !term.empty())
-      result->push_back(PieceToOutputType<Str, OutputStringType>(term));
+      result->emplace_back(term);
   }
 }
 
@@ -162,11 +146,11 @@
                                      WhitespaceHandling whitespace,
                                      SplitResult result_type) {
   if (separators.size() == 1) {
-    return SplitStringT<std::string, std::string, char>(
-        input, separators[0], whitespace, result_type);
+    return SplitStringT<char, std::string, char>(input, separators[0],
+                                                 whitespace, result_type);
   }
-  return SplitStringT<std::string, std::string, StringPiece>(
-      input, separators, whitespace, result_type);
+  return SplitStringT<char, std::string, StringPiece>(input, separators,
+                                                      whitespace, result_type);
 }
 
 std::vector<string16> SplitString(StringPiece16 input,
@@ -174,10 +158,10 @@
                                   WhitespaceHandling whitespace,
                                   SplitResult result_type) {
   if (separators.size() == 1) {
-    return SplitStringT<string16, string16, char16>(input, separators[0],
+    return SplitStringT<char16_t, string16, char16>(input, separators[0],
                                                     whitespace, result_type);
   }
-  return SplitStringT<string16, string16, StringPiece16>(
+  return SplitStringT<char16_t, string16, StringPiece16>(
       input, separators, whitespace, result_type);
 }
 
@@ -186,11 +170,11 @@
                                           WhitespaceHandling whitespace,
                                           SplitResult result_type) {
   if (separators.size() == 1) {
-    return SplitStringT<std::string, StringPiece, char>(
-        input, separators[0], whitespace, result_type);
+    return SplitStringT<char, StringPiece, char>(input, separators[0],
+                                                 whitespace, result_type);
   }
-  return SplitStringT<std::string, StringPiece, StringPiece>(
-      input, separators, whitespace, result_type);
+  return SplitStringT<char, StringPiece, StringPiece>(input, separators,
+                                                      whitespace, result_type);
 }
 
 std::vector<StringPiece16> SplitStringPiece(StringPiece16 input,
@@ -198,10 +182,10 @@
                                             WhitespaceHandling whitespace,
                                             SplitResult result_type) {
   if (separators.size() == 1) {
-    return SplitStringT<string16, StringPiece16, char16>(
+    return SplitStringT<char16_t, StringPiece16, char16>(
         input, separators[0], whitespace, result_type);
   }
-  return SplitStringT<string16, StringPiece16, StringPiece16>(
+  return SplitStringT<char16_t, StringPiece16, StringPiece16>(
       input, separators, whitespace, result_type);
 }
 
diff --git a/base/strings/string_tokenizer.h b/base/strings/string_tokenizer.h
index 9c3b5fa..50deb88 100644
--- a/base/strings/string_tokenizer.h
+++ b/base/strings/string_tokenizer.h
@@ -142,9 +142,9 @@
   const_iterator token_begin() const { return token_begin_; }
   const_iterator token_end() const { return token_end_; }
   str token() const { return str(token_begin_, token_end_); }
-  BasicStringPiece<str> token_piece() const {
-    return BasicStringPiece<str>(&*token_begin_,
-                                 std::distance(token_begin_, token_end_));
+  std::basic_string_view<typename str::value_type> token_piece() const {
+    return std::basic_string_view<typename str::value_type>(
+        &*token_begin_, std::distance(token_begin_, token_end_));
   }
 
  private:
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index f3e8257..f6ee491 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -49,21 +49,6 @@
   return elem1.parameter < elem2.parameter;
 }
 
-// Overloaded function to append one string onto the end of another. Having a
-// separate overload for |source| as both string and StringPiece allows for more
-// efficient usage from functions templated to work with either type (avoiding a
-// redundant call to the BasicStringPiece constructor in both cases).
-template <typename string_type>
-inline void AppendToString(string_type* target, const string_type& source) {
-  target->append(source);
-}
-
-template <typename string_type>
-inline void AppendToString(string_type* target,
-                           const BasicStringPiece<string_type>& source) {
-  source.AppendToString(target);
-}
-
 // Assuming that a pointer is the size of a "machine word", then
 // uintptr_t is an integer type that is also a machine word.
 typedef uintptr_t MachineWord;
@@ -103,7 +88,8 @@
 namespace {
 
 template <typename StringType>
-StringType ToLowerASCIIImpl(BasicStringPiece<StringType> str) {
+StringType ToLowerASCIIImpl(
+    std::basic_string_view<typename StringType::value_type> str) {
   StringType ret;
   ret.reserve(str.size());
   for (size_t i = 0; i < str.size(); i++)
@@ -112,7 +98,8 @@
 }
 
 template <typename StringType>
-StringType ToUpperASCIIImpl(BasicStringPiece<StringType> str) {
+StringType ToUpperASCIIImpl(
+    std::basic_string_view<typename StringType::value_type> str) {
   StringType ret;
   ret.reserve(str.size());
   for (size_t i = 0; i < str.size(); i++)
@@ -139,8 +126,9 @@
 }
 
 template <class StringType>
-int CompareCaseInsensitiveASCIIT(BasicStringPiece<StringType> a,
-                                 BasicStringPiece<StringType> b) {
+int CompareCaseInsensitiveASCIIT(
+    std::basic_string_view<typename StringType::value_type> a,
+    std::basic_string_view<typename StringType::value_type> b) {
   // Find the first characters that aren't equal and compare them.  If the end
   // of one of the strings is found before a nonequal character, the lengths
   // of the strings are compared.
@@ -186,10 +174,11 @@
 }
 
 template <class StringType>
-bool ReplaceCharsT(const StringType& input,
-                   BasicStringPiece<StringType> find_any_of_these,
-                   BasicStringPiece<StringType> replace_with,
-                   StringType* output);
+bool ReplaceCharsT(
+    const StringType& input,
+    std::basic_string_view<typename StringType::value_type> find_any_of_these,
+    std::basic_string_view<typename StringType::value_type> replace_with,
+    StringType* output);
 
 bool ReplaceChars(const string16& input,
                   StringPiece16 replace_chars,
@@ -219,15 +208,16 @@
 }
 
 template <typename Str>
-TrimPositions TrimStringT(const Str& input,
-                          BasicStringPiece<Str> trim_chars,
-                          TrimPositions positions,
-                          Str* output) {
+TrimPositions TrimStringT(
+    const Str& input,
+    std::basic_string_view<typename Str::value_type> trim_chars,
+    TrimPositions positions,
+    Str* output) {
   // Find the edges of leading/trailing whitespace as desired. Need to use
   // a StringPiece version of input to be able to call find* on it with the
   // StringPiece version of trim_chars (normally the trim_chars will be a
   // constant so avoid making a copy).
-  BasicStringPiece<Str> input_piece(input);
+  std::basic_string_view<typename Str::value_type> input_piece(input);
   const size_t last_char = input.length() - 1;
   const size_t first_good_char = (positions & TRIM_LEADING)
                                      ? input_piece.find_first_not_of(trim_chars)
@@ -267,12 +257,16 @@
   return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE;
 }
 
-template <typename Str>
-BasicStringPiece<Str> TrimStringPieceT(BasicStringPiece<Str> input,
-                                       BasicStringPiece<Str> trim_chars,
-                                       TrimPositions positions) {
+template <typename char_type>
+std::basic_string_view<char_type> TrimStringPieceT(
+    std::basic_string_view<char_type> input,
+    std::basic_string_view<char_type> trim_chars,
+    TrimPositions positions) {
   size_t begin =
       (positions & TRIM_LEADING) ? input.find_first_not_of(trim_chars) : 0;
+  if (begin == std::basic_string_view<char_type>::npos)
+    return std::basic_string_view<char_type>();  // All trimmed.
+
   size_t end = (positions & TRIM_TRAILING)
                    ? input.find_last_not_of(trim_chars) + 1
                    : input.size();
@@ -474,8 +468,9 @@
 // string piece gives additional flexibility for the caller (doesn't have to be
 // null terminated) so we choose the StringPiece route.
 template <typename Str>
-static inline bool DoLowerCaseEqualsASCII(BasicStringPiece<Str> str,
-                                          StringPiece lowercase_ascii) {
+static inline bool DoLowerCaseEqualsASCII(
+    std::basic_string_view<typename Str::value_type> str,
+    StringPiece lowercase_ascii) {
   if (str.size() != lowercase_ascii.size())
     return false;
   for (size_t i = 0; i < str.size(); i++) {
@@ -499,23 +494,22 @@
   return std::equal(ascii.begin(), ascii.end(), str.begin());
 }
 
-template <typename Str>
-bool StartsWithT(BasicStringPiece<Str> str,
-                 BasicStringPiece<Str> search_for,
+template <typename char_type>
+bool StartsWithT(std::basic_string_view<char_type> str,
+                 std::basic_string_view<char_type> search_for,
                  CompareCase case_sensitivity) {
   if (search_for.size() > str.size())
     return false;
 
-  BasicStringPiece<Str> source = str.substr(0, search_for.size());
+  std::basic_string_view<char_type> source = str.substr(0, search_for.size());
 
   switch (case_sensitivity) {
     case CompareCase::SENSITIVE:
       return source == search_for;
 
     case CompareCase::INSENSITIVE_ASCII:
-      return std::equal(
-          search_for.begin(), search_for.end(), source.begin(),
-          CaseInsensitiveCompareASCII<typename Str::value_type>());
+      return std::equal(search_for.begin(), search_for.end(), source.begin(),
+                        CaseInsensitiveCompareASCII<char_type>());
 
     default:
       NOTREACHED();
@@ -526,23 +520,23 @@
 bool StartsWith(StringPiece str,
                 StringPiece search_for,
                 CompareCase case_sensitivity) {
-  return StartsWithT<std::string>(str, search_for, case_sensitivity);
+  return StartsWithT(str, search_for, case_sensitivity);
 }
 
 bool StartsWith(StringPiece16 str,
                 StringPiece16 search_for,
                 CompareCase case_sensitivity) {
-  return StartsWithT<string16>(str, search_for, case_sensitivity);
+  return StartsWithT(str, search_for, case_sensitivity);
 }
 
 template <typename Str>
-bool EndsWithT(BasicStringPiece<Str> str,
-               BasicStringPiece<Str> search_for,
+bool EndsWithT(std::basic_string_view<typename Str::value_type> str,
+               std::basic_string_view<typename Str::value_type> search_for,
                CompareCase case_sensitivity) {
   if (search_for.size() > str.size())
     return false;
 
-  BasicStringPiece<Str> source =
+  std::basic_string_view<typename Str::value_type> source =
       str.substr(str.size() - search_for.size(), search_for.size());
 
   switch (case_sensitivity) {
@@ -620,7 +614,7 @@
 // A Matcher for DoReplaceMatchesAfterOffset() that matches substrings.
 template <class StringType>
 struct SubstringMatcher {
-  BasicStringPiece<StringType> find_this;
+  std::basic_string_view<typename StringType::value_type> find_this;
 
   size_t Find(const StringType& input, size_t pos) {
     return input.find(find_this.data(), pos, find_this.length());
@@ -631,7 +625,7 @@
 // A Matcher for DoReplaceMatchesAfterOffset() that matches single characters.
 template <class StringType>
 struct CharacterMatcher {
-  BasicStringPiece<StringType> find_any_of_these;
+  std::basic_string_view<typename StringType::value_type> find_any_of_these;
 
   size_t Find(const StringType& input, size_t pos) {
     return input.find_first_of(find_any_of_these.data(), pos,
@@ -648,11 +642,12 @@
 // This is parameterized on a |Matcher| traits type, so that it can be the
 // implementation for both ReplaceChars() and ReplaceSubstringsAfterOffset().
 template <class StringType, class Matcher>
-bool DoReplaceMatchesAfterOffset(StringType* str,
-                                 size_t initial_offset,
-                                 Matcher matcher,
-                                 BasicStringPiece<StringType> replace_with,
-                                 ReplaceType replace_type) {
+bool DoReplaceMatchesAfterOffset(
+    StringType* str,
+    size_t initial_offset,
+    Matcher matcher,
+    std::basic_string_view<typename StringType::value_type> replace_with,
+    ReplaceType replace_type) {
   using CharTraits = typename StringType::traits_type;
 
   const size_t find_length = matcher.MatchSize();
@@ -791,10 +786,11 @@
 }
 
 template <class StringType>
-bool ReplaceCharsT(const StringType& input,
-                   BasicStringPiece<StringType> find_any_of_these,
-                   BasicStringPiece<StringType> replace_with,
-                   StringType* output) {
+bool ReplaceCharsT(
+    const StringType& input,
+    std::basic_string_view<typename StringType::value_type> find_any_of_these,
+    std::basic_string_view<typename StringType::value_type> replace_with,
+    StringType* output) {
   // Commonly, this is called with output and input being the same string; in
   // that case, this assignment is inexpensive.
   *output = input;
@@ -863,34 +859,30 @@
 #endif
 
 // Generic version for all JoinString overloads. |list_type| must be a sequence
-// (std::vector or std::initializer_list) of strings/StringPieces (std::string,
-// string16, StringPiece or StringPiece16). |string_type| is either std::string
-// or string16.
-template <typename list_type, typename string_type>
-static string_type JoinStringT(const list_type& parts,
-                               BasicStringPiece<string_type> sep) {
+// (std::vector or std::initializer_list) of strings/string_views of any type.
+template <typename char_type, typename list_type>
+static std::basic_string<char_type> JoinStringT(
+    const list_type& parts,
+    std::basic_string_view<char_type> sep) {
   if (parts.size() == 0)
-    return string_type();
+    return std::basic_string<char_type>();
 
   // Pre-allocate the eventual size of the string. Start with the size of all of
   // the separators (note that this *assumes* parts.size() > 0).
   size_t total_size = (parts.size() - 1) * sep.size();
   for (const auto& part : parts)
     total_size += part.size();
-  string_type result;
+  std::basic_string<char_type> result;
   result.reserve(total_size);
 
   auto iter = parts.begin();
   DCHECK(iter != parts.end());
-  AppendToString(&result, *iter);
+  result.append(*iter);
   ++iter;
 
   for (; iter != parts.end(); ++iter) {
-    sep.AppendToString(&result);
-    // Using the overloaded AppendToString allows this template function to work
-    // on both strings and StringPieces without creating an intermediate
-    // StringPiece object.
-    AppendToString(&result, *iter);
+    result.append(sep);
+    result.append(*iter);
   }
 
   // Sanity-check that we pre-allocated correctly.
diff --git a/base/strings/utf_string_conversion_utils.cc b/base/strings/utf_string_conversion_utils.cc
index 4e5f890..838471c 100644
--- a/base/strings/utf_string_conversion_utils.cc
+++ b/base/strings/utf_string_conversion_utils.cc
@@ -30,7 +30,7 @@
   return IsValidCodepoint(code_point);
 }
 
-bool ReadUnicodeCharacter(const char16* src,
+bool ReadUnicodeCharacter(const char16_t* src,
                           int32_t src_len,
                           int32_t* char_index,
                           uint32_t* code_point) {
@@ -107,7 +107,7 @@
 }
 
 // Instantiate versions we know callers will need.
-template void PrepareForUTF8Output(const char16*, size_t, std::string*);
+template void PrepareForUTF8Output(const char16_t*, size_t, std::string*);
 
 template <typename STRING>
 void PrepareForUTF16Or32Output(const char* src,
diff --git a/base/strings/utf_string_conversion_utils.h b/base/strings/utf_string_conversion_utils.h
index 78cbde7..3f14808 100644
--- a/base/strings/utf_string_conversion_utils.h
+++ b/base/strings/utf_string_conversion_utils.h
@@ -47,7 +47,7 @@
                           uint32_t* code_point_out);
 
 // Reads a UTF-16 character. The usage is the same as the 8-bit version above.
-bool ReadUnicodeCharacter(const char16* src,
+bool ReadUnicodeCharacter(const char16_t* src,
                           int32_t src_len,
                           int32_t* char_index,
                           uint32_t* code_point);
diff --git a/build/gen.py b/build/gen.py
index 3d9406c..5011ea9 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -407,7 +407,6 @@
         'base/memory/weak_ptr.cc',
         'base/sha1.cc',
         'base/strings/string_number_conversions.cc',
-        'base/strings/string_piece.cc',
         'base/strings/string_split.cc',
         'base/strings/string_util.cc',
         'base/strings/string_util_constants.cc',
diff --git a/tools/gn/bundle_data.cc b/tools/gn/bundle_data.cc
index 4251c8f..9de0e8c 100644
--- a/tools/gn/bundle_data.cc
+++ b/tools/gn/bundle_data.cc
@@ -5,6 +5,7 @@
 #include "tools/gn/bundle_data.h"
 
 #include "base/logging.h"
+#include "base/strings/string_util.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/label_pattern.h"
 #include "tools/gn/output_file.h"
@@ -31,15 +32,20 @@
   //    .*\.xcassets/[^/]*\.launchimage/[^/]*
   bool is_file_from_asset_catalog = false;
   base::StringPiece dir = FindDirNoTrailingSeparator(source);
-  if (source.ends_with("/Contents.json") && dir.ends_with(".xcassets")) {
+  if (base::EndsWith(source, "/Contents.json", base::CompareCase::SENSITIVE) &&
+      base::EndsWith(dir, ".xcassets", base::CompareCase::SENSITIVE)) {
     is_file_from_asset_catalog = true;
-  } else if (dir.ends_with(".appiconset") || dir.ends_with(".imageset") ||
-             dir.ends_with(".launchimage") || dir.ends_with(".colorset")) {
+  } else if (base::EndsWith(dir, ".appiconset", base::CompareCase::SENSITIVE) ||
+             base::EndsWith(dir, ".imageset", base::CompareCase::SENSITIVE) ||
+             base::EndsWith(dir, ".launchimage",
+                            base::CompareCase::SENSITIVE) ||
+             base::EndsWith(dir, ".colorset", base::CompareCase::SENSITIVE)) {
     dir = FindDirNoTrailingSeparator(dir);
-    is_file_from_asset_catalog = dir.ends_with(".xcassets");
+    is_file_from_asset_catalog =
+        base::EndsWith(dir, ".xcassets", base::CompareCase::SENSITIVE);
   }
   if (is_file_from_asset_catalog && asset_catalog) {
-    std::string asset_catalog_path = dir.as_string();
+    std::string asset_catalog_path(dir);
     *asset_catalog = SourceFile(std::move(asset_catalog_path));
   }
   return is_file_from_asset_catalog;
diff --git a/tools/gn/c_include_iterator_unittest.cc b/tools/gn/c_include_iterator_unittest.cc
index a88537c..aa1f99a 100644
--- a/tools/gn/c_include_iterator_unittest.cc
+++ b/tools/gn/c_include_iterator_unittest.cc
@@ -132,7 +132,7 @@
   CIncludeIterator iter(&file);
   for (size_t group = 0; group < kGroupCount; group++) {
     EXPECT_TRUE(iter.GetNextIncludeString(&contents, &range));
-    EXPECT_EQ(include, contents.as_string());
+    EXPECT_EQ(include, std::string(contents));
   }
   EXPECT_FALSE(iter.GetNextIncludeString(&contents, &range));
 }
diff --git a/tools/gn/command_args.cc b/tools/gn/command_args.cc
index 096ba8f..26b8bd6 100644
--- a/tools/gn/command_args.cc
+++ b/tools/gn/command_args.cc
@@ -72,7 +72,7 @@
   // normal comment that has a space after the # will be indented 4 spaces
   // (which makes our formatting come out nicely). If the comment is indented
   // from there, we want to preserve that indenting.
-  std::string line_stripped = line.substr(line.find('#') + 1).as_string();
+  std::string line_stripped(line.substr(line.find('#') + 1));
   if (pad)
     return "   " + line_stripped;
 
@@ -131,7 +131,7 @@
     if (!comment.empty())
       OutputString("\n" + comment);
   } else {
-    OutputString("      (Internally set; try `gn help " + name.as_string() +
+    OutputString("      (Internally set; try `gn help " + std::string(name) +
                  "`.)\n");
   }
 }
@@ -139,7 +139,7 @@
 // Override value is null if there is no override.
 void PrintArgHelp(const base::StringPiece& name,
                   const Args::ValueWithOverride& val) {
-  OutputString(name.as_string(), DECORATION_YELLOW);
+  OutputString(std::string(name), DECORATION_YELLOW);
   OutputString("\n");
 
   if (val.has_override) {
@@ -259,7 +259,7 @@
     for (const auto& arg : args) {
       if (overrides_only && !arg.second.has_override)
         continue;
-      OutputString(arg.first.as_string());
+      OutputString(std::string(arg.first));
       OutputString(" = ");
       if (arg.second.has_override)
         OutputString(arg.second.override_value.ToString(true));
diff --git a/tools/gn/command_clean.cc b/tools/gn/command_clean.cc
index b354039..32aaf77 100644
--- a/tools/gn/command_clean.cc
+++ b/tools/gn/command_clean.cc
@@ -33,7 +33,7 @@
   std::string result;
   int num_blank_lines = 0;
   for (const auto& line : lines) {
-    line.AppendToString(&result);
+    result.append(line);
     result.push_back('\n');
     if (line.empty())
       ++num_blank_lines;
diff --git a/tools/gn/command_format.cc b/tools/gn/command_format.cc
index 4249c2f..a8604a5 100644
--- a/tools/gn/command_format.cc
+++ b/tools/gn/command_format.cc
@@ -265,7 +265,7 @@
 Printer::~Printer() = default;
 
 void Printer::Print(base::StringPiece str) {
-  str.AppendToString(&output_);
+  output_.append(str);
 }
 
 void Printer::PrintMargin() {
@@ -274,7 +274,7 @@
 
 void Printer::TrimAndPrintToken(const Token& token) {
   std::string trimmed;
-  TrimWhitespaceASCII(token.value().as_string(), base::TRIM_ALL, &trimmed);
+  TrimWhitespaceASCII(std::string(token.value()), base::TRIM_ALL, &trimmed);
   Print(trimmed);
 }
 
@@ -335,9 +335,8 @@
 void Printer::SortIfSourcesOrDeps(const BinaryOpNode* binop) {
   if (const Comments* comments = binop->comments()) {
     const std::vector<Token>& before = comments->before();
-    if (!before.empty() &&
-        (before.front().value().as_string() == "# NOSORT" ||
-         before.back().value().as_string() == "# NOSORT")) {
+    if (!before.empty() && (before.front().value() == "# NOSORT" ||
+                            before.back().value() == "# NOSORT")) {
       // Allow disabling of sort for specific actions that might be
       // order-sensitive.
       return;
@@ -645,7 +644,7 @@
     Printer sub_left;
     InitializeSub(&sub_left);
     sub_left.Expr(binop->left(), prec_left,
-                  std::string(" ") + binop->op().value().as_string());
+                  std::string(" ") + std::string(binop->op().value()));
     bool left_is_multiline = CountLines(sub_left.String()) > 1;
     // Avoid walking the whole left redundantly times (see timing of Format.046)
     // so pull the output and comments from subprinter.
@@ -1063,7 +1062,8 @@
   return false;
 }
 
-void DoFormat(const ParseNode* root, TreeDumpMode dump_tree,
+void DoFormat(const ParseNode* root,
+              TreeDumpMode dump_tree,
               std::string* output) {
   if (dump_tree == TreeDumpMode::kPlainText) {
     std::ostringstream os;
@@ -1071,8 +1071,8 @@
     fprintf(stderr, "%s", os.str().c_str());
   } else if (dump_tree == TreeDumpMode::kJSON) {
     std::string os;
-    base::JSONWriter::WriteWithOptions(root->GetJSONNode(),
-        base::JSONWriter::OPTIONS_PRETTY_PRINT, &os);
+    base::JSONWriter::WriteWithOptions(
+        root->GetJSONNode(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &os);
     fprintf(stderr, "%s", os.c_str());
   }
 
@@ -1146,17 +1146,19 @@
       base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDryRun);
   TreeDumpMode dump_tree = TreeDumpMode::kInactive;
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDumpTree)) {
-    std::string tree_type = base::CommandLine::ForCurrentProcess()->
-        GetSwitchValueASCII(kSwitchDumpTree);
+    std::string tree_type =
+        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+            kSwitchDumpTree);
     if (tree_type == kSwitchDumpTreeJSON) {
       dump_tree = TreeDumpMode::kJSON;
     } else if (tree_type.empty() || tree_type == kSwitchDumpTreeText) {
       dump_tree = TreeDumpMode::kPlainText;
     } else {
-      Err(Location(),
-          tree_type + " is an invalid value for --dump-tree. Specify "
-          "\"" + kSwitchDumpTreeText + "\" or \"" + kSwitchDumpTreeJSON +
-          "\".\n")
+      Err(Location(), tree_type +
+                          " is an invalid value for --dump-tree. Specify "
+                          "\"" +
+                          kSwitchDumpTreeText + "\" or \"" +
+                          kSwitchDumpTreeJSON + "\".\n")
           .PrintToStdout();
       return 1;
     }
@@ -1200,8 +1202,7 @@
   // parallel.
   for (const auto& arg : args) {
     Err err;
-    SourceFile file =
-        source_dir.ResolveRelativeFile(Value(nullptr, arg), &err);
+    SourceFile file = source_dir.ResolveRelativeFile(Value(nullptr, arg), &err);
     if (err.has_error()) {
       err.PrintToStdout();
       return 1;
diff --git a/tools/gn/command_help.cc b/tools/gn/command_help.cc
index 7145da4..987f506 100644
--- a/tools/gn/command_help.cc
+++ b/tools/gn/command_help.cc
@@ -366,7 +366,7 @@
     OutputString("Run `gn help` for a list of available topics.\n",
                  DECORATION_NONE);
   } else {
-    OutputString("Did you mean `gn help " + suggestion.as_string() + "`?\n",
+    OutputString("Did you mean `gn help " + std::string(suggestion) + "`?\n",
                  DECORATION_NONE);
   }
   return 1;
diff --git a/tools/gn/create_bundle_target_generator.cc b/tools/gn/create_bundle_target_generator.cc
index a54d171..2c5a3af 100644
--- a/tools/gn/create_bundle_target_generator.cc
+++ b/tools/gn/create_bundle_target_generator.cc
@@ -125,7 +125,7 @@
       return false;
 
     xcode_extra_attributes.insert(
-        std::make_pair(iter.first.as_string(), iter.second.string_value()));
+        std::make_pair(std::string(iter.first), iter.second.string_value()));
   }
 
   target_->bundle_data().xcode_extra_attributes() =
diff --git a/tools/gn/err.cc b/tools/gn/err.cc
index fe4db20..4f60964 100644
--- a/tools/gn/err.cc
+++ b/tools/gn/err.cc
@@ -22,7 +22,7 @@
   size_t end = line_off + 1;
   while (end < data.size() && !Tokenizer::IsNewline(data, end))
     end++;
-  return data.substr(line_off, end - line_off).as_string();
+  return std::string(data.substr(line_off, end - line_off));
 }
 
 void FillRangeOnLine(const LocationRange& range,
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc
index 727e2f3..ea4dfb8 100644
--- a/tools/gn/filesystem_utils.cc
+++ b/tools/gn/filesystem_utils.cc
@@ -226,7 +226,7 @@
 #if defined(OS_WIN)
   return base::FilePath(base::UTF8ToUTF16(sp));
 #else
-  return base::FilePath(sp.as_string());
+  return base::FilePath(sp);
 #endif
 }
 
@@ -572,7 +572,7 @@
                 // On Windows, if the source_root does not start with a slash,
                 // append one here for consistency.
                 if (!IsSlash(source_root[0])) {
-                  path->insert(0, "/" + source_root.as_string());
+                  path->insert(0, "/" + std::string(source_root));
                   source_root_len++;
                 } else {
                   path->insert(0, source_root.data(), source_root_len);
@@ -704,7 +704,8 @@
                        const SourceDir& dest_dir,
                        const base::StringPiece& source_root) {
   std::string ret;
-  DCHECK(source_root.empty() || !source_root.ends_with("/"));
+  DCHECK(source_root.empty() ||
+         !base::EndsWith(source_root, "/", base::CompareCase::SENSITIVE));
 
   bool input_is_source_path =
       (input.size() >= 2 && input[0] == '/' && input[1] == '/');
@@ -714,14 +715,14 @@
     std::string input_full;
     std::string dest_full;
     if (input_is_source_path) {
-      source_root.AppendToString(&input_full);
+      input_full.append(source_root);
       input_full.push_back('/');
       input_full.append(input, 2, std::string::npos);
     } else {
       input_full.append(input);
     }
     if (dest_dir.is_source_absolute()) {
-      source_root.AppendToString(&dest_full);
+      dest_full.append(source_root);
       dest_full.push_back('/');
       dest_full.append(dest_dir.value(), 2, std::string::npos);
     } else {
diff --git a/tools/gn/filesystem_utils_unittest.cc b/tools/gn/filesystem_utils_unittest.cc
index 32b30f6..2f8df44 100644
--- a/tools/gn/filesystem_utils_unittest.cc
+++ b/tools/gn/filesystem_utils_unittest.cc
@@ -26,17 +26,17 @@
 
 TEST(FilesystemUtils, FindExtension) {
   std::string input;
-  EXPECT_EQ("", FindExtension(&input).as_string());
+  EXPECT_EQ("", FindExtension(&input));
   input = "foo/bar/baz";
-  EXPECT_EQ("", FindExtension(&input).as_string());
+  EXPECT_EQ("", FindExtension(&input));
   input = "foo.";
-  EXPECT_EQ("", FindExtension(&input).as_string());
+  EXPECT_EQ("", FindExtension(&input));
   input = "f.o.bar";
-  EXPECT_EQ("bar", FindExtension(&input).as_string());
+  EXPECT_EQ("bar", FindExtension(&input));
   input = "foo.bar/";
-  EXPECT_EQ("", FindExtension(&input).as_string());
+  EXPECT_EQ("", FindExtension(&input));
   input = "foo.bar/baz";
-  EXPECT_EQ("", FindExtension(&input).as_string());
+  EXPECT_EQ("", FindExtension(&input));
 }
 
 TEST(FilesystemUtils, FindFilenameOffset) {
diff --git a/tools/gn/function_get_path_info.cc b/tools/gn/function_get_path_info.cc
index 08f7e8c..b392490 100644
--- a/tools/gn/function_get_path_info.cc
+++ b/tools/gn/function_get_path_info.cc
@@ -63,10 +63,10 @@
 
   switch (what) {
     case WHAT_FILE: {
-      return FindFilename(&input_string).as_string();
+      return std::string(FindFilename(&input_string));
     }
     case WHAT_NAME: {
-      std::string file = FindFilename(&input_string).as_string();
+      std::string file(FindFilename(&input_string));
       size_t extension_offset = FindExtensionOffset(file);
       if (extension_offset == std::string::npos)
         return file;
@@ -74,7 +74,7 @@
       return file.substr(0, extension_offset - 1);
     }
     case WHAT_EXTENSION: {
-      return FindExtension(&input_string).as_string();
+      return std::string(FindExtension(&input_string));
     }
     case WHAT_DIR: {
       base::StringPiece dir_incl_slash = FindDir(&input_string);
@@ -87,7 +87,7 @@
         return std::string("/.");
       if (dir_incl_slash == "//")
         return std::string("//.");
-      return dir_incl_slash.substr(0, dir_incl_slash.size() - 1).as_string();
+      return std::string(dir_incl_slash.substr(0, dir_incl_slash.size() - 1));
     }
     case WHAT_GEN_DIR: {
       return DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir(
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc
index 05033c8..c0a64ac 100644
--- a/tools/gn/functions.cc
+++ b/tools/gn/functions.cc
@@ -1175,7 +1175,7 @@
   int64_t n = 0;
   std::string val(str);
   size_t start_pos = 0;
-  while((start_pos = val.find(old, start_pos)) != std::string::npos) {
+  while ((start_pos = val.find(old, start_pos)) != std::string::npos) {
     val.replace(start_pos, old.length(), new_);
     start_pos += new_.length();
     if (++n >= max)
@@ -1315,7 +1315,7 @@
                   Err* err) {
   const Token& name = function->function();
 
-  std::string template_name = function->function().value().as_string();
+  std::string template_name(function->function().value());
   const Template* templ = scope->GetTemplate(template_name);
   if (templ) {
     Value args = args_list->Execute(scope, err);
diff --git a/tools/gn/generated_file_target_generator.cc b/tools/gn/generated_file_target_generator.cc
index 2971221..023e5d4 100644
--- a/tools/gn/generated_file_target_generator.cc
+++ b/tools/gn/generated_file_target_generator.cc
@@ -72,9 +72,9 @@
     const ParseNode* origin) {
   if (contents_defined_) {
     *err_ =
-        Err(origin, variable.as_string() + " won't be used.",
+        Err(origin, std::string(variable) + " won't be used.",
             "\"contents\" is defined on this target, and so setting " +
-                variable.as_string() +
+                std::string(variable) +
                 " will have no effect as no metdata collection will occur.");
     return false;
   }
diff --git a/tools/gn/header_checker.cc b/tools/gn/header_checker.cc
index dca7302..14784b7 100644
--- a/tools/gn/header_checker.cc
+++ b/tools/gn/header_checker.cc
@@ -120,8 +120,10 @@
 HeaderChecker::HeaderChecker(const BuildSettings* build_settings,
                              const std::vector<const Target*>& targets,
                              bool check_generated)
-    : build_settings_(build_settings), check_generated_(check_generated),
-      lock_(), task_count_cv_() {
+    : build_settings_(build_settings),
+      check_generated_(check_generated),
+      lock_(),
+      task_count_cv_() {
   for (auto* target : targets)
     AddTargetToFileMap(target, &file_map_);
 }
@@ -249,7 +251,7 @@
     Err* err) const {
   using base::FilePath;
 
-  Value relative_file_value(nullptr, relative_file_path.as_string());
+  Value relative_file_value(nullptr, std::string(relative_file_path));
   auto it = std::find_if(
       include_dirs.begin(), include_dirs.end(),
       [relative_file_value, err, this](const SourceDir& dir) -> bool {
diff --git a/tools/gn/label_pattern.cc b/tools/gn/label_pattern.cc
index f5e6b9c..bed4d86 100644
--- a/tools/gn/label_pattern.cc
+++ b/tools/gn/label_pattern.cc
@@ -55,9 +55,7 @@
                            const SourceDir& dir,
                            const base::StringPiece& name,
                            const Label& toolchain_label)
-    : toolchain_(toolchain_label), type_(type), dir_(dir) {
-  name.CopyToString(&name_);
-}
+    : toolchain_(toolchain_label), type_(type), dir_(dir), name_(name) {}
 
 LabelPattern::LabelPattern(const LabelPattern& other) = default;
 
@@ -103,8 +101,8 @@
       return LabelPattern();
     }
 
-    std::string toolchain_string =
-        str.substr(open_paren + 1, close_paren - open_paren - 1).as_string();
+    std::string toolchain_string(
+        str.substr(open_paren + 1, close_paren - open_paren - 1));
     if (toolchain_string.find('*') != std::string::npos) {
       *err = Err(value, "Can't have a wildcard in the toolchain.");
       return LabelPattern();
diff --git a/tools/gn/operators.cc b/tools/gn/operators.cc
index 40ea900..24b17c0 100644
--- a/tools/gn/operators.cc
+++ b/tools/gn/operators.cc
@@ -118,7 +118,7 @@
           "\n"
           "If you really wanted to do this, do:\n"
           "  " +
-              base_str.as_string() + " = " + base_str.as_string() +
+              std::string(base_str) + " = " + std::string(base_str) +
               "\n"
               "to copy it into the current scope before doing this operation.");
     } else {
@@ -246,7 +246,7 @@
                               const Value& right) {
   std::string msg = std::string("You can't do <") +
                     Value::DescribeType(left.type()) + "> " +
-                    op_node->op().value().as_string() + " <" +
+                    std::string(op_node->op().value()) + " <" +
                     Value::DescribeType(right.type()) + ">.";
   if (left.type() == Value::LIST) {
     // Append extra hint for list stuff.
diff --git a/tools/gn/output_conversion.cc b/tools/gn/output_conversion.cc
index 7f62896..77e9a4f 100644
--- a/tools/gn/output_conversion.cc
+++ b/tools/gn/output_conversion.cc
@@ -56,7 +56,7 @@
     if (!first)
       out << ",\n";
     Indent(indent, out);
-    out << "\"" << pair.first.as_string() << "\": ";
+    out << "\"" << pair.first << "\": ";
     if (pair.second.type() == Value::SCOPE)
       RenderScopeToJSON(pair.second, out, indent + 1);
     else if (pair.second.type() == Value::LIST)
@@ -103,8 +103,7 @@
   Scope::KeyValueMap scope_values;
   output.scope_value()->GetCurrentScopeValues(&scope_values);
   for (const auto& pair : scope_values) {
-    out << "  " << pair.first.as_string() << " = " << pair.second.ToString(true)
-        << "\n";
+    out << "  " << pair.first << " = " << pair.second.ToString(true) << "\n";
   }
 }
 
diff --git a/tools/gn/parse_tree.cc b/tools/gn/parse_tree.cc
index 821fb7e..337b3b2 100644
--- a/tools/gn/parse_tree.cc
+++ b/tools/gn/parse_tree.cc
@@ -13,6 +13,7 @@
 #include "base/json/string_escape.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "tools/gn/functions.h"
 #include "tools/gn/operators.h"
 #include "tools/gn/scope.h"
@@ -51,7 +52,8 @@
 std::tuple<base::StringPiece, base::StringPiece> SplitAtFirst(
     base::StringPiece str,
     char c) {
-  if (!str.starts_with("\"") || !str.ends_with("\""))
+  if (!base::StartsWith(str, "\"", base::CompareCase::SENSITIVE) ||
+      !base::EndsWith(str, "\"", base::CompareCase::SENSITIVE))
     return std::make_tuple(str, base::StringPiece());
 
   str = str.substr(1, str.length() - 2);
@@ -146,7 +148,7 @@
 }
 
 base::Value ParseNode::CreateJSONNode(const char* type,
-    const base::StringPiece& value) const {
+                                      const base::StringPiece& value) const {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetKey(kJsonNodeType, base::Value(type));
   dict.SetKey(kJsonNodeValue, base::Value(value));
@@ -305,7 +307,7 @@
   if (max_len == 0) {
     *err = Err(index_->GetRange(), "Array subscript out of range.",
                "You gave me " + base::Int64ToString(index_int) + " but the " +
-               "array has no elements.");
+                   "array has no elements.");
     return false;
   }
   size_t index_sizet = static_cast<size_t>(index_int);
@@ -806,7 +808,9 @@
       return Value(this, false);
     case Token::INTEGER: {
       base::StringPiece s = value_.value();
-      if ((s.starts_with("0") && s.size() > 1) || s.starts_with("-0")) {
+      if ((base::StartsWith(s, "0", base::CompareCase::SENSITIVE) &&
+           s.size() > 1) ||
+          base::StartsWith(s, "-0", base::CompareCase::SENSITIVE)) {
         if (s == "-0")
           *err = MakeErrorDescribing("Negative zero doesn't make sense");
         else
@@ -909,7 +913,7 @@
 
 base::Value BlockCommentNode::GetJSONNode() const {
   std::string escaped;
-  base::EscapeJSONString(comment_.value().as_string(), false, &escaped);
+  base::EscapeJSONString(std::string(comment_.value()), false, &escaped);
   return CreateJSONNode("BLOCK_COMMENT", escaped);
 }
 
diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc
index 0065afd..ea498a4 100644
--- a/tools/gn/parser.cc
+++ b/tools/gn/parser.cc
@@ -435,8 +435,7 @@
   PrefixFunc prefix = expressions_[token.type()].prefix;
 
   if (prefix == nullptr) {
-    *err_ = Err(token, std::string("Unexpected token '") +
-                           token.value().as_string() + std::string("'"));
+    *err_ = Err(token, "Unexpected token '" + std::string(token.value()) + "'");
     return std::unique_ptr<ParseNode>();
   }
 
@@ -449,9 +448,8 @@
     const Token& next_token = Consume();
     InfixFunc infix = expressions_[next_token.type()].infix;
     if (infix == nullptr) {
-      *err_ = Err(next_token, std::string("Unexpected token '") +
-                                  next_token.value().as_string() +
-                                  std::string("'"));
+      *err_ = Err(next_token,
+                  "Unexpected token '" + std::string(next_token.value()) + "'");
       return std::unique_ptr<ParseNode>();
     }
     left = (this->*infix)(std::move(left), next_token);
@@ -521,7 +519,7 @@
   if (!right) {
     if (!has_error()) {
       *err_ = Err(token, "Expected right-hand side for '" +
-                             token.value().as_string() + "'");
+                             std::string(token.value()) + "'");
     }
     return std::unique_ptr<ParseNode>();
   }
@@ -899,8 +897,9 @@
   return std::string(value, ' ');
 }
 
-void RenderToText(const base::Value& node, int indent_level,
-    std::ostringstream& os) {
+void RenderToText(const base::Value& node,
+                  int indent_level,
+                  std::ostringstream& os) {
   const base::Value* child = node.FindKey(std::string("child"));
   std::string node_type(node.FindKey("type")->GetString());
   if (node_type == "ACCESSOR") {
@@ -908,7 +907,7 @@
     // for the base.
     os << IndentFor(indent_level) << node_type << std::endl;
     os << IndentFor(indent_level + 1) << node.FindKey("value")->GetString()
-        << std::endl;
+       << std::endl;
   } else {
     os << IndentFor(indent_level) << node_type;
     if (node.FindKey("value")) {
@@ -918,20 +917,20 @@
   }
   if (node.FindKey(kJsonBeforeComment)) {
     for (auto& v : node.FindKey(kJsonBeforeComment)->GetList()) {
-      os << IndentFor(indent_level + 1) <<
-          "+BEFORE_COMMENT(\"" << v.GetString() << "\")\n";
+      os << IndentFor(indent_level + 1) << "+BEFORE_COMMENT(\"" << v.GetString()
+         << "\")\n";
     }
   }
   if (node.FindKey(kJsonSuffixComment)) {
     for (auto& v : node.FindKey(kJsonSuffixComment)->GetList()) {
-      os << IndentFor(indent_level + 1) <<
-          "+SUFFIX_COMMENT(\"" << v.GetString() << "\")\n";
+      os << IndentFor(indent_level + 1) << "+SUFFIX_COMMENT(\"" << v.GetString()
+         << "\")\n";
     }
   }
   if (node.FindKey(kJsonAfterComment)) {
     for (auto& v : node.FindKey(kJsonAfterComment)->GetList()) {
-      os << IndentFor(indent_level + 1) <<
-          "+AFTER_COMMENT(\"" << v.GetString() << "\")\n";
+      os << IndentFor(indent_level + 1) << "+AFTER_COMMENT(\"" << v.GetString()
+         << "\")\n";
     }
   }
   if (child) {
diff --git a/tools/gn/rust_values_generator.cc b/tools/gn/rust_values_generator.cc
index 910d5af..c29282e 100644
--- a/tools/gn/rust_values_generator.cc
+++ b/tools/gn/rust_values_generator.cc
@@ -199,7 +199,7 @@
 
     // Insert into the aliased_deps map.
     target_->rust_values().aliased_deps().emplace(std::move(dep_label),
-                                                  pair.first.as_string());
+                                                  pair.first);
   }
 
   return true;
diff --git a/tools/gn/scope.cc b/tools/gn/scope.cc
index dd1a576..40d4a86 100644
--- a/tools/gn/scope.cc
+++ b/tools/gn/scope.cc
@@ -220,7 +220,7 @@
 void Scope::MarkAllUsed(const std::set<std::string>& excluded_values) {
   for (auto& cur : values_) {
     if (!excluded_values.empty() &&
-        excluded_values.find(cur.first.as_string()) != excluded_values.end()) {
+        excluded_values.find(std::string(cur.first)) != excluded_values.end()) {
       continue;  // Skip this excluded value.
     }
     cur.second.used = true;
@@ -250,7 +250,7 @@
   for (const auto& pair : values_) {
     if (!pair.second.used) {
       std::string help =
-          "You set the variable \"" + pair.first.as_string() +
+          "You set the variable \"" + std::string(pair.first) +
           "\" here and it was unused before it went\nout of scope.";
 
       const BinaryOpNode* binary = pair.second.value.origin()->AsBinaryOp();
@@ -302,7 +302,7 @@
     if (options.skip_private_vars && IsPrivateVar(current_name))
       continue;  // Skip this private var.
     if (!options.excluded_values.empty() &&
-        options.excluded_values.find(current_name.as_string()) !=
+        options.excluded_values.find(std::string(current_name)) !=
             options.excluded_values.end()) {
       continue;  // Skip this excluded value.
     }
@@ -315,7 +315,7 @@
         std::string desc_string(desc_for_err);
         *err = Err(node_for_err, "Value collision.",
                    "This " + desc_string + " contains \"" +
-                       current_name.as_string() + "\"");
+                       std::string(current_name) + "\"");
         err->AppendSubErr(
             Err(pair.second.value, "defined here.",
                 "Which would clobber the one in your current scope"));
diff --git a/tools/gn/scope.h b/tools/gn/scope.h
index 6c26cdb..f7d70ca 100644
--- a/tools/gn/scope.h
+++ b/tools/gn/scope.h
@@ -338,8 +338,7 @@
     Value value;
   };
 
-  typedef std::unordered_map<base::StringPiece, Record, base::StringPieceHash>
-      RecordMap;
+  using RecordMap = std::unordered_map<base::StringPiece, Record>;
 
   void AddProvider(ProgrammaticProvider* p);
   void RemoveProvider(ProgrammaticProvider* p);
diff --git a/tools/gn/string_utils.h b/tools/gn/string_utils.h
index 744714a..c77daca 100644
--- a/tools/gn/string_utils.h
+++ b/tools/gn/string_utils.h
@@ -5,6 +5,7 @@
 #ifndef TOOLS_GN_STRING_UTILS_H_
 #define TOOLS_GN_STRING_UTILS_H_
 
+#include <string>
 #include <vector>
 
 #include "base/strings/string_piece.h"
diff --git a/tools/gn/substitution_writer.cc b/tools/gn/substitution_writer.cc
index 41be9b4..8b884c6 100644
--- a/tools/gn/substitution_writer.cc
+++ b/tools/gn/substitution_writer.cc
@@ -354,7 +354,7 @@
       return source.value();
     to_rebase = source.value();
   } else if (type == &SubstitutionSourceNamePart) {
-    return FindFilenameNoExtension(&source.value()).as_string();
+    return std::string(FindFilenameNoExtension(&source.value()));
   } else if (type == &SubstitutionSourceFilePart) {
     return source.GetName();
   } else if (type == &SubstitutionSourceDir) {
diff --git a/tools/gn/value.cc b/tools/gn/value.cc
index a54db03..c8cde58 100644
--- a/tools/gn/value.cc
+++ b/tools/gn/value.cc
@@ -37,29 +37,19 @@
 }
 
 Value::Value(const ParseNode* origin, bool bool_val)
-    : type_(BOOLEAN),
-      boolean_value_(bool_val),
-      origin_(origin) {}
+    : type_(BOOLEAN), boolean_value_(bool_val), origin_(origin) {}
 
 Value::Value(const ParseNode* origin, int64_t int_val)
-    : type_(INTEGER),
-      int_value_(int_val),
-      origin_(origin) {}
+    : type_(INTEGER), int_value_(int_val), origin_(origin) {}
 
 Value::Value(const ParseNode* origin, std::string str_val)
-    : type_(STRING),
-      string_value_(std::move(str_val)),
-      origin_(origin) {}
+    : type_(STRING), string_value_(std::move(str_val)), origin_(origin) {}
 
 Value::Value(const ParseNode* origin, const char* str_val)
-    : type_(STRING),
-      string_value_(str_val),
-      origin_(origin) {}
+    : type_(STRING), string_value_(str_val), origin_(origin) {}
 
 Value::Value(const ParseNode* origin, std::unique_ptr<Scope> scope)
-    : type_(SCOPE),
-      scope_value_(std::move(scope)),
-      origin_(origin) {}
+    : type_(SCOPE), scope_value_(std::move(scope)), origin_(origin) {}
 
 Value::Value(const Value& other) : type_(other.type_), origin_(other.origin_) {
   switch (type_) {
@@ -217,7 +207,7 @@
 
       std::string result = "{\n";
       for (const auto& pair : scope_values) {
-        result += "  " + pair.first.as_string() + " = " +
+        result += "  " + std::string(pair.first) + " = " +
                   pair.second.ToString(true) + "\n";
       }
       result += "}";
diff --git a/tools/gn/visual_studio_writer.cc b/tools/gn/visual_studio_writer.cc
index 9d9aa21..217075b 100644
--- a/tools/gn/visual_studio_writer.cc
+++ b/tools/gn/visual_studio_writer.cc
@@ -700,7 +700,7 @@
       base::StringPiece filter_path = FindParentDir(&target_relative_path);
 
       if (!filter_path.empty()) {
-        std::string filter_path_str = filter_path.as_string();
+        std::string filter_path_str(filter_path);
         while (processed_filters.find(filter_path_str) ==
                processed_filters.end()) {
           auto it = processed_filters.insert(filter_path_str).first;
@@ -708,7 +708,7 @@
               ->SubElement("Filter", XmlAttributes("Include", filter_path_str))
               ->SubElement("UniqueIdentifier")
               ->Text(MakeGuid(filter_path_str, kGuidSeedFilter));
-          filter_path_str = FindParentDir(&(*it)).as_string();
+          filter_path_str = std::string(FindParentDir(&(*it)));
           if (filter_path_str.empty())
             break;
         }
@@ -815,9 +815,10 @@
     if (it != processed_paths.end()) {
       project->parent_folder = it->second;
     } else {
-      std::string folder_path_str = folder_path.as_string();
+      std::string folder_path_str(folder_path);
       std::unique_ptr<SolutionEntry> folder = std::make_unique<SolutionEntry>(
-          FindLastDirComponent(SourceDir(std::string(folder_path))).as_string(),
+          std::string(
+              FindLastDirComponent(SourceDir(std::string(folder_path)))),
           folder_path_str, MakeGuid(folder_path_str, kGuidSeedFolder));
       project->parent_folder = folder.get();
       processed_paths[folder_path] = folder.get();
@@ -863,10 +864,10 @@
       } else {
         std::unique_ptr<SolutionEntry> new_folder =
             std::make_unique<SolutionEntry>(
-                FindLastDirComponent(SourceDir(std::string(parent_path)))
-                    .as_string(),
-                parent_path.as_string(),
-                MakeGuid(parent_path.as_string(), kGuidSeedFolder));
+                std::string(
+                    FindLastDirComponent(SourceDir(std::string(parent_path)))),
+                std::string(parent_path),
+                MakeGuid(std::string(parent_path), kGuidSeedFolder));
         processed_paths[parent_path] = new_folder.get();
         folder = new_folder.get();
         additional_folders.push_back(std::move(new_folder));
diff --git a/tools/gn/xcode_object.cc b/tools/gn/xcode_object.cc
index bd5c440..248661a 100644
--- a/tools/gn/xcode_object.cc
+++ b/tools/gn/xcode_object.cc
@@ -560,8 +560,8 @@
   }
 
   if (!group) {
-    children_.push_back(std::make_unique<PBXGroup>(component.as_string(),
-                                                   component.as_string()));
+    children_.push_back(std::make_unique<PBXGroup>(std::string(component),
+                                                   std::string(component)));
     group = static_cast<PBXGroup*>(children_.back().get());
   }
 
diff --git a/tools/gn/xml_element_writer.h b/tools/gn/xml_element_writer.h
index 4aa5f7e..1f68a7d 100644
--- a/tools/gn/xml_element_writer.h
+++ b/tools/gn/xml_element_writer.h
@@ -5,8 +5,8 @@
 #ifndef TOOLS_GN_XML_ELEMENT_WRITER_H_
 #define TOOLS_GN_XML_ELEMENT_WRITER_H_
 
-#include <iosfwd>
 #include <memory>
+#include <ostream>
 #include <string>
 #include <utility>
 #include <vector>