Replace OutputFile with StringAtom under the hood

The purpose of this is to allow OutputFile to be cheaply copied.

Bug: 491925153
Change-Id: I4d42b77f31a0608f978712143d0c6e746a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/23921
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Commit-Queue: Matt Stark <msta@google.com>
diff --git a/src/gn/output_file.cc b/src/gn/output_file.cc
index 6028ad1..6a159ea 100644
--- a/src/gn/output_file.cc
+++ b/src/gn/output_file.cc
@@ -9,12 +9,9 @@
 
 OutputFile::OutputFile(const BuildSettings* build_settings,
                        const SourceFile& source_file) {
-  std::string rebased =
-      RebasePath(source_file.value(), build_settings->build_dir(),
-                 build_settings->root_path_utf8());
-  if (!rebased.empty()) {
-    value_.assign(rebased.begin(), rebased.end());
-  }
+  value_ =
+      StringAtom(RebasePath(source_file.value(), build_settings->build_dir(),
+                            build_settings->root_path_utf8()));
 }
 
 SourceFile OutputFile::AsSourceFile(const BuildSettings* build_settings) const {
diff --git a/src/gn/output_file.h b/src/gn/output_file.h
index 9ae8cdf..30d3a12 100644
--- a/src/gn/output_file.h
+++ b/src/gn/output_file.h
@@ -8,32 +8,25 @@
 #include <stddef.h>
 
 #include <string_view>
-#include <vector>
+
+#include "gn/string_atom.h"
 
 class BuildSettings;
 class SourceDir;
 class SourceFile;
 
-// A simple wrapper around a vector of chars that indicates the path
+// A simple wrapper around StringAtom that indicates the path
 // relative to the output directory.
 class OutputFile {
  public:
   OutputFile() = default;
 
-  explicit OutputFile(std::string_view v) { value_.assign(v.begin(), v.end()); }
+  explicit OutputFile(std::string_view v) : value_(v) {}
 
   OutputFile(const BuildSettings* build_settings,
              const SourceFile& source_file);
 
-  std::string_view value() const {
-    return std::string_view(value_.data(), value_.size());
-  }
-
-  void resize(std::size_t n) { value_.resize(n); }
-
-  void append(std::string_view v) {
-    value_.insert(value_.end(), v.begin(), v.end());
-  }
+  std::string_view value() const { return value_; }
 
   // Converts to a SourceFile by prepending the build directory to the file.
   // The *Dir version requires that the current OutputFile ends in a slash, and
@@ -42,18 +35,10 @@
   SourceDir AsSourceDir(const BuildSettings* build_settings) const;
 
   bool operator==(const OutputFile& other) const = default;
-  bool operator!=(const OutputFile& other) const = default;
-  bool operator<(const OutputFile& other) const = default;
   std::strong_ordering operator<=>(const OutputFile& other) const = default;
 
  private:
-  // Storing this as a vector<char> instead of a std::string has some tradeoffs.
-  // * When OutputFile is moved (eg. vector<OutputFile>.push_back), string_views
-  //   pointing to OutputFile stay valid
-  // * We now lose small string optimization. This is probably fine, and may in
-  //   fact even be an improvement, as OutputFiles are almost universally very
-  //   long and thus this may help with branch prediction.
-  std::vector<char> value_;
+  StringAtom value_;
 };
 
 namespace std {