Remove backward-compatibility-1500-revert-remove-base-stackvector.patch

BUG=b:295505917
TEST=emerge-hatch libchrome

Cq-Depend: chromium:4782568
Change-Id: Ida2b7cad36fbff5842c1bada1ded38757b91029f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/libchrome/+/4780691
Tested-by: Ryo Hashimoto <hashimoto@chromium.org>
Commit-Queue: Grace Cham <hscham@chromium.org>
Reviewed-by: Grace Cham <hscham@chromium.org>
diff --git a/libchrome_tools/patches/backward-compatibility-1500-revert-remove-base-stackvector.patch b/libchrome_tools/patches/backward-compatibility-1500-revert-remove-base-stackvector.patch
deleted file mode 100644
index 5f44647..0000000
--- a/libchrome_tools/patches/backward-compatibility-1500-revert-remove-base-stackvector.patch
+++ /dev/null
@@ -1,519 +0,0 @@
-From 67b1b0352f38a531781bb0311441b77f092a6845 Mon Sep 17 00:00:00 2001
-From: Brett Brotherton <bbrotherton@google.com>
-Date: Fri, 11 Aug 2023 07:21:32 -0600
-Subject: [PATCH] Revert "Remove base::StackVector"
-
-This reverts commit 70f8b27d8e7b42cd461e388af427a361ca509808.
----
- base/containers/stack_container.h           | 277 ++++++++++++++++++++
- base/containers/stack_container_unittest.cc | 214 +++++++++++++++
- 2 files changed, 491 insertions(+)
- create mode 100644 base/containers/stack_container.h
- create mode 100644 base/containers/stack_container_unittest.cc
-
-diff --git a/base/containers/stack_container.h b/base/containers/stack_container.h
-new file mode 100644
-index 0000000000..ba3842a28d
---- /dev/null
-+++ b/base/containers/stack_container.h
-@@ -0,0 +1,277 @@
-+// Copyright 2012 The Chromium Authors
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef BASE_CONTAINERS_STACK_CONTAINER_H_
-+#define BASE_CONTAINERS_STACK_CONTAINER_H_
-+
-+// ================== DEPRECATION NOTICE ==================
-+// These classes are deprecated and will be removed soon. Use
-+// absl::InlinedVector instead. If absl::InlinedVector doesn't fit your use
-+// case, please email cxx@chromium.org with details.
-+
-+#include <stddef.h>
-+#include <memory>
-+#include <vector>
-+
-+#include "base/compiler_specific.h"
-+#include "base/memory/raw_ptr_exclusion.h"
-+#include "build/build_config.h"
-+
-+namespace base {
-+
-+// This allocator can be used with STL containers to provide a stack buffer
-+// from which to allocate memory and overflows onto the heap. This stack buffer
-+// would be allocated on the stack and allows us to avoid heap operations in
-+// some situations.
-+//
-+// STL likes to make copies of allocators, so the allocator itself can't hold
-+// the data. Instead, we make the creator responsible for creating a
-+// StackAllocator::Source which contains the data. Copying the allocator
-+// merely copies the pointer to this shared source, so all allocators created
-+// based on our allocator will share the same stack buffer.
-+//
-+// This stack buffer implementation is very simple. The first allocation that
-+// fits in the stack buffer will use the stack buffer. Any subsequent
-+// allocations will not use the stack buffer, even if there is unused room.
-+// This makes it appropriate for array-like containers, but the caller should
-+// be sure to reserve() in the container up to the stack buffer size. Otherwise
-+// the container will allocate a small array which will "use up" the stack
-+// buffer.
-+template <typename T, size_t stack_capacity, typename FallbackAllocator>
-+class StackAllocator : public FallbackAllocator {
-+ public:
-+  using pointer = typename std::allocator_traits<FallbackAllocator>::pointer;
-+  using size_type =
-+      typename std::allocator_traits<FallbackAllocator>::size_type;
-+
-+  // Backing store for the allocator. The container owner is responsible for
-+  // maintaining this for as long as any containers using this allocator are
-+  // live.
-+  struct Source {
-+    Source() : used_stack_buffer_(false) {
-+    }
-+
-+    // Casts the buffer in its right type.
-+    NO_SANITIZE("cfi-unrelated-cast")
-+    T* stack_buffer() { return reinterpret_cast<T*>(stack_buffer_); }
-+    NO_SANITIZE("cfi-unrelated-cast")
-+    const T* stack_buffer() const {
-+      return reinterpret_cast<const T*>(&stack_buffer_);
-+    }
-+
-+    // The buffer itself. It is not of type T because we don't want the
-+    // constructors and destructors to be automatically called. Define a POD
-+    // buffer of the right size instead.
-+    alignas(T) char stack_buffer_[sizeof(T[stack_capacity])];
-+#if defined(__GNUC__) && !defined(ARCH_CPU_X86_FAMILY)
-+    static_assert(alignof(T) <= 16, "http://crbug.com/115612");
-+#endif
-+
-+    // Set when the stack buffer is used for an allocation. We do not track
-+    // how much of the buffer is used, only that somebody is using it.
-+    bool used_stack_buffer_;
-+  };
-+
-+  // Used by containers when they want to refer to an allocator of type U.
-+  template<typename U>
-+  struct rebind {
-+    typedef StackAllocator<U, stack_capacity, FallbackAllocator> other;
-+  };
-+
-+  // For the straight up copy c-tor, we can share storage.
-+  StackAllocator(
-+      const StackAllocator<T, stack_capacity, FallbackAllocator>& rhs)
-+      : source_(rhs.source_) {}
-+
-+  // ISO C++ requires the following constructor to be defined,
-+  // and std::vector in VC++2008SP1 Release fails with an error
-+  // in the class _Container_base_aux_alloc_real (from <xutility>)
-+  // if the constructor does not exist.
-+  // For this constructor, we cannot share storage; there's
-+  // no guarantee that the Source buffer of Ts is large enough
-+  // for Us.
-+  // TODO: If we were fancy pants, perhaps we could share storage
-+  // iff sizeof(T) == sizeof(U).
-+  template <typename U, size_t other_capacity, typename FA>
-+  StackAllocator(const StackAllocator<U, other_capacity, FA>& other)
-+      : source_(nullptr) {}
-+
-+  // This constructor must exist. It creates a default allocator that doesn't
-+  // actually have a stack buffer. glibc's std::string() will compare the
-+  // current allocator against the default-constructed allocator, so this
-+  // should be fast.
-+  StackAllocator() : source_(nullptr) {}
-+
-+  explicit StackAllocator(Source* source) : source_(source) {
-+  }
-+
-+  // Actually do the allocation. Use the stack buffer if nobody has used it yet
-+  // and the size requested fits. Otherwise, fall through to the standard
-+  // allocator.
-+  pointer allocate(size_type n) {
-+    if (source_ && !source_->used_stack_buffer_ && n <= stack_capacity) {
-+      source_->used_stack_buffer_ = true;
-+      return source_->stack_buffer();
-+    } else {
-+      return std::allocator_traits<FallbackAllocator>::allocate(*this, n);
-+    }
-+  }
-+
-+  // Free: when trying to free the stack buffer, just mark it as free. For
-+  // non-stack-buffer pointers, just fall though to the standard allocator.
-+  void deallocate(pointer p, size_type n) {
-+    if (source_ && p == source_->stack_buffer())
-+      source_->used_stack_buffer_ = false;
-+    else
-+      std::allocator_traits<FallbackAllocator>::deallocate(*this, p, n);
-+  }
-+
-+ private:
-+  // `source_` is not a raw_ptr<T> for performance reasons: on-stack pointee.
-+  RAW_PTR_EXCLUSION Source* source_;
-+};
-+
-+// A wrapper around STL containers that maintains a stack-sized buffer that the
-+// initial capacity of the vector is based on. Growing the container beyond the
-+// stack capacity will transparently overflow onto the heap. The container must
-+// support reserve().
-+//
-+// This will not work with std::string since some implementations allocate
-+// more bytes than requested in calls to reserve(), forcing the allocation onto
-+// the heap.  http://crbug.com/709273
-+//
-+// WATCH OUT: the ContainerType MUST use the proper StackAllocator for this
-+// type. This object is really intended to be used only internally. You'll want
-+// to use the wrappers below for different types.
-+template <typename TContainerType, int stack_capacity>
-+class StackContainer {
-+ public:
-+  using ContainerType = TContainerType;
-+  using ContainedType = typename ContainerType::value_type;
-+  using Allocator = typename ContainerType::allocator_type;
-+
-+  // Allocator must be constructed before the container!
-+  StackContainer() : allocator_(&stack_data_), container_(allocator_) {
-+    // Make the container use the stack allocation by reserving our buffer size
-+    // before doing anything else.
-+    container_.reserve(stack_capacity);
-+  }
-+  StackContainer(const StackContainer&) = delete;
-+  StackContainer& operator=(const StackContainer&) = delete;
-+
-+  // Getters for the actual container.
-+  //
-+  // Danger: any copies of this made using the copy constructor must have
-+  // shorter lifetimes than the source. The copy will share the same allocator
-+  // and therefore the same stack buffer as the original. Use std::copy to
-+  // copy into a "real" container for longer-lived objects.
-+  ContainerType& container() { return container_; }
-+  const ContainerType& container() const { return container_; }
-+
-+  // Support operator-> to get to the container. This allows nicer syntax like:
-+  //   StackContainer<...> foo;
-+  //   std::sort(foo->begin(), foo->end());
-+  ContainerType* operator->() { return &container_; }
-+  const ContainerType* operator->() const { return &container_; }
-+
-+#ifdef UNIT_TEST
-+  // Retrieves the stack source so that that unit tests can verify that the
-+  // buffer is being used properly.
-+  const typename Allocator::Source& stack_data() const {
-+    return stack_data_;
-+  }
-+#endif
-+
-+ protected:
-+  typename Allocator::Source stack_data_;
-+  NO_UNIQUE_ADDRESS Allocator allocator_;
-+  ContainerType container_;
-+};
-+
-+// Range-based iteration support for StackContainer.
-+template <typename TContainerType, int stack_capacity>
-+auto begin(
-+    const StackContainer<TContainerType, stack_capacity>& stack_container)
-+    -> decltype(begin(stack_container.container())) {
-+  return begin(stack_container.container());
-+}
-+
-+template <typename TContainerType, int stack_capacity>
-+auto begin(StackContainer<TContainerType, stack_capacity>& stack_container)
-+    -> decltype(begin(stack_container.container())) {
-+  return begin(stack_container.container());
-+}
-+
-+template <typename TContainerType, int stack_capacity>
-+auto end(StackContainer<TContainerType, stack_capacity>& stack_container)
-+    -> decltype(end(stack_container.container())) {
-+  return end(stack_container.container());
-+}
-+
-+template <typename TContainerType, int stack_capacity>
-+auto end(const StackContainer<TContainerType, stack_capacity>& stack_container)
-+    -> decltype(end(stack_container.container())) {
-+  return end(stack_container.container());
-+}
-+
-+// StackVector -----------------------------------------------------------------
-+
-+// THIS CLASS IS DEPRECATED. Use absl::InlinedVector instead.
-+
-+// Example:
-+//   StackVector<int, 16> foo;
-+//   foo->push_back(22);  // we have overloaded operator->
-+//   foo[0] = 10;         // as well as operator[]
-+template <typename T,
-+          size_t stack_capacity,
-+          typename FallbackAllocator = std::allocator<T>>
-+class StackVector
-+    : public StackContainer<
-+          std::vector<T, StackAllocator<T, stack_capacity, FallbackAllocator>>,
-+          stack_capacity> {
-+ public:
-+  StackVector()
-+      : StackContainer<
-+            std::vector<T,
-+                        StackAllocator<T, stack_capacity, FallbackAllocator>>,
-+            stack_capacity>() {}
-+
-+  // We need to put this in STL containers sometimes, which requires a copy
-+  // constructor. We can't call the regular copy constructor because that will
-+  // take the stack buffer from the original. Here, we create an empty object
-+  // and make a stack buffer of its own.
-+  StackVector(const StackVector<T, stack_capacity, FallbackAllocator>& other)
-+      : StackContainer<
-+            std::vector<T,
-+                        StackAllocator<T, stack_capacity, FallbackAllocator>>,
-+            stack_capacity>() {
-+    this->container().assign(other->begin(), other->end());
-+  }
-+
-+  StackVector<T, stack_capacity, FallbackAllocator>& operator=(
-+      const StackVector<T, stack_capacity, FallbackAllocator>& other) {
-+    this->container().assign(other->begin(), other->end());
-+    return *this;
-+  }
-+
-+  // Vectors are commonly indexed, which isn't very convenient even with
-+  // operator-> (using "->at()" does exception stuff we don't want).
-+  T& operator[](size_t i) { return this->container().operator[](i); }
-+  const T& operator[](size_t i) const {
-+    return this->container().operator[](i);
-+  }
-+};
-+
-+}  // namespace base
-+
-+// Opt out of libc++ container annotations for StackAllocator. It seems to slow
-+// down some tests enough to cause timeouts(?) crbug.com/1444659
-+#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
-+template <typename T, size_t stack_capacity, typename FallbackAllocator>
-+struct ::std::__asan_annotate_container_with_allocator<
-+    base::StackAllocator<T, stack_capacity, FallbackAllocator>>
-+    : ::std::false_type {};
-+#endif  // _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
-+
-+#endif  // BASE_CONTAINERS_STACK_CONTAINER_H_
-diff --git a/base/containers/stack_container_unittest.cc b/base/containers/stack_container_unittest.cc
-new file mode 100644
-index 0000000000..68c6321824
---- /dev/null
-+++ b/base/containers/stack_container_unittest.cc
-@@ -0,0 +1,214 @@
-+// Copyright 2012 The Chromium Authors
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "base/containers/stack_container.h"
-+
-+#include <stddef.h>
-+
-+#include "base/memory/aligned_memory.h"
-+#include "base/memory/raw_ptr.h"
-+#include "base/memory/ref_counted.h"
-+#include "base/ranges/algorithm.h"
-+#include "build/build_config.h"
-+#include "testing/gtest/include/gtest/gtest.h"
-+
-+namespace base {
-+
-+namespace {
-+
-+class Dummy : public RefCounted<Dummy> {
-+ public:
-+  explicit Dummy(int* alive) : alive_(alive) {
-+    ++*alive_;
-+  }
-+
-+ private:
-+  friend class RefCounted<Dummy>;
-+
-+  ~Dummy() {
-+    --*alive_;
-+  }
-+
-+  const raw_ptr<int> alive_;
-+};
-+
-+}  // namespace
-+
-+TEST(StackContainer, Vector) {
-+  const int stack_size = 3;
-+  StackVector<int, stack_size> vect;
-+  const int* stack_buffer = &vect.stack_data().stack_buffer()[0];
-+
-+  // The initial |stack_size| elements should appear in the stack buffer.
-+  EXPECT_EQ(static_cast<size_t>(stack_size), vect.container().capacity());
-+  for (int i = 0; i < stack_size; i++) {
-+    vect.container().push_back(i);
-+    EXPECT_EQ(stack_buffer, &vect.container()[0]);
-+    EXPECT_TRUE(vect.stack_data().used_stack_buffer_);
-+  }
-+
-+  // Adding more elements should push the array onto the heap.
-+  for (int i = 0; i < stack_size; i++) {
-+    vect.container().push_back(i + stack_size);
-+    EXPECT_NE(stack_buffer, &vect.container()[0]);
-+    EXPECT_FALSE(vect.stack_data().used_stack_buffer_);
-+  }
-+
-+  // The array should still be in order.
-+  for (int i = 0; i < stack_size * 2; i++)
-+    EXPECT_EQ(i, vect.container()[i]);
-+
-+  // Resize to smaller. Our STL implementation won't reallocate in this case,
-+  // otherwise it might use our stack buffer. We reserve right after the resize
-+  // to guarantee it isn't using the stack buffer, even though it doesn't have
-+  // much data.
-+  vect.container().resize(stack_size);
-+  vect.container().reserve(stack_size * 2);
-+  EXPECT_FALSE(vect.stack_data().used_stack_buffer_);
-+
-+  // Copying the small vector to another should use the same allocator and use
-+  // the now-unused stack buffer. GENERALLY CALLERS SHOULD NOT DO THIS since
-+  // they have to get the template types just right and it can cause errors.
-+  std::vector<int, StackAllocator<int, stack_size, std::allocator<int>>> other(
-+      vect.container());
-+  EXPECT_EQ(stack_buffer, &other.front());
-+  EXPECT_TRUE(vect.stack_data().used_stack_buffer_);
-+  for (int i = 0; i < stack_size; i++)
-+    EXPECT_EQ(i, other[i]);
-+}
-+
-+TEST(StackContainer, VectorDoubleDelete) {
-+  // Regression testing for double-delete.
-+  typedef StackVector<scoped_refptr<Dummy>, 2> Vector;
-+  Vector vect;
-+
-+  int alive = 0;
-+  scoped_refptr<Dummy> dummy(new Dummy(&alive));
-+  EXPECT_EQ(alive, 1);
-+
-+  vect->push_back(dummy);
-+  EXPECT_EQ(alive, 1);
-+
-+  Dummy* dummy_unref = dummy.get();
-+  dummy = nullptr;
-+  EXPECT_EQ(alive, 1);
-+
-+  auto itr = ranges::find(vect, dummy_unref);
-+  EXPECT_EQ(itr->get(), dummy_unref);
-+  vect->erase(itr);
-+  EXPECT_EQ(alive, 0);
-+
-+  // Shouldn't crash at exit.
-+}
-+
-+namespace {
-+
-+template <size_t alignment>
-+class AlignedData {
-+ public:
-+  AlignedData() { memset(data_, 0, alignment); }
-+  ~AlignedData() = default;
-+  alignas(alignment) char data_[alignment];
-+};
-+
-+}  // namespace
-+
-+TEST(StackContainer, BufferAlignment) {
-+  StackVector<wchar_t, 16> text;
-+  text->push_back(L'A');
-+  EXPECT_TRUE(IsAligned(&text[0], alignof(wchar_t)));
-+
-+  StackVector<double, 1> doubles;
-+  doubles->push_back(0.0);
-+  EXPECT_TRUE(IsAligned(&doubles[0], alignof(double)));
-+
-+  StackVector<AlignedData<16>, 1> aligned16;
-+  aligned16->push_back(AlignedData<16>());
-+  EXPECT_TRUE(IsAligned(&aligned16[0], 16));
-+
-+#if !defined(__GNUC__) || defined(ARCH_CPU_X86_FAMILY)
-+  // It seems that non-X86 gcc doesn't respect greater than 16 byte alignment.
-+  // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33721 for details.
-+  // TODO(sbc): Re-enable this if GCC starts respecting higher alignments.
-+  StackVector<AlignedData<256>, 1> aligned256;
-+  aligned256->push_back(AlignedData<256>());
-+  EXPECT_TRUE(IsAligned(&aligned256[0], 256));
-+#endif
-+}
-+
-+template class StackVector<int, 2>;
-+template class StackVector<scoped_refptr<Dummy>, 2>;
-+
-+template <typename T, size_t size>
-+void CheckStackVectorElements(const StackVector<T, size>& vec,
-+                              std::initializer_list<T> expected) {
-+  auto expected_it = expected.begin();
-+  EXPECT_EQ(vec->size(), expected.size());
-+  for (T t : vec) {
-+    EXPECT_NE(expected.end(), expected_it);
-+    EXPECT_EQ(*expected_it, t);
-+    ++expected_it;
-+  }
-+  EXPECT_EQ(expected.end(), expected_it);
-+}
-+
-+TEST(StackContainer, Iteration) {
-+  StackVector<int, 3> vect;
-+  vect->push_back(7);
-+  vect->push_back(11);
-+
-+  CheckStackVectorElements(vect, {7, 11});
-+  for (int& i : vect) {
-+    ++i;
-+  }
-+  CheckStackVectorElements(vect, {8, 12});
-+  vect->push_back(13);
-+  CheckStackVectorElements(vect, {8, 12, 13});
-+  vect->resize(5);
-+  CheckStackVectorElements(vect, {8, 12, 13, 0, 0});
-+  vect->resize(1);
-+  CheckStackVectorElements(vect, {8});
-+}
-+
-+namespace {
-+struct Allocator : std::allocator<int> {
-+  using Base = std::allocator<int>;
-+
-+  int* allocate(size_t n) {
-+    ++allocated;
-+    return Base::allocate(n);
-+  }
-+  void deallocate(int* p, size_t n) {
-+    ++deallocated;
-+    Base::deallocate(p, n);
-+  }
-+
-+  static int allocated;
-+  static int deallocated;
-+};
-+
-+int Allocator::allocated = 0;
-+int Allocator::deallocated = 0;
-+}  // namespace
-+
-+TEST(StackContainer, CustomAllocator) {
-+  StackVector<int, 2, Allocator> v;
-+
-+  EXPECT_EQ(0, Allocator::allocated);
-+  EXPECT_EQ(0, Allocator::deallocated);
-+
-+  v->push_back(1);
-+  v->push_back(1);
-+  EXPECT_EQ(0, Allocator::allocated);
-+  v->push_back(1);
-+  EXPECT_EQ(1, Allocator::allocated);
-+
-+  EXPECT_EQ(0, Allocator::deallocated);
-+  v->clear();
-+  // shrink_to_fit() makes sure to destroy empty backing store.
-+  v->shrink_to_fit();
-+  EXPECT_EQ(1, Allocator::deallocated);
-+}
-+
-+}  // namespace base
--- 
-2.41.0.640.ga95def55d0-goog
-