#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_VECTOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_VECTOR_H_
#include <string.h>
#include <algorithm>
#include <concepts>
#include <functional>
#include <initializer_list>
#include <iterator>
#include <ranges>
#include <type_traits>
#include <utility>
#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/containers/checked_iterators.h"
#include "base/containers/span.h"
#include "base/dcheck_is_on.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/atomic_operations.h"
#include "third_party/blink/renderer/platform/wtf/construct_traits.h"
#include "third_party/blink/renderer/platform/wtf/container_annotations.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
#include "third_party/blink/renderer/platform/wtf/vector_traits.h"
#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
#define INLINE_CAPACITY …
#else
#define INLINE_CAPACITY …
#endif
namespace WTF {
#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
static const wtf_size_t kInitialVectorSize = 1;
#else
static const wtf_size_t kInitialVectorSize = …;
#endif
template <typename T, wtf_size_t inlineBuffer, typename Allocator>
class Deque;
#if defined(ADDRESS_SANITIZER)
#define MARKING_AWARE_ANNOTATE_CHANGE_SIZE …
#define MARKING_AWARE_ANNOTATE_NEW_BUFFER …
#else
#define MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, buffer, capacity, \
old_size, new_size) …
#define MARKING_AWARE_ANNOTATE_NEW_BUFFER(Allocator, buffer, capacity, size) …
#endif
template <typename T>
struct VectorElementComparer { … };
VectorElementComparer<std::unique_ptr<T>>;
enum class VectorOperationOrigin { … };
template <typename T, typename Allocator>
struct VectorTypeOperations { … };
template <typename T, typename Allocator>
class VectorBufferBase { … };
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator = PartitionAllocator>
class VectorBuffer;
VectorBuffer<T, 0, Allocator>;
template <typename T, wtf_size_t InlineCapacity, typename Allocator>
class VectorBuffer : protected VectorBufferBase<T, Allocator> { … };
template <typename T>
class UncheckedIterator { … };
template <typename T, bool checked_iter>
struct IteratorSelector;
IteratorSelector<T, true>;
IteratorSelector<T, false>;
kVectorNeedsDestructor;
kVectorNeedsDestructor;
kVectorNeedsDestructor;
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> { … };
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline Vector<T, InlineCapacity, Allocator, checked_iter>::Vector() { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline Vector<T, InlineCapacity, Allocator, checked_iter>::Vector(
wtf_size_t size)
: … { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline Vector<T, InlineCapacity, Allocator, checked_iter>::Vector(
wtf_size_t size,
const T& val)
: … { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
Vector<T, InlineCapacity, Allocator, checked_iter>::Vector(const Vector& other)
: … { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename Proj, typename>
Vector<T, InlineCapacity, Allocator, checked_iter>::Vector(const Vector& other,
Proj proj)
: Base(other.capacity()) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <wtf_size_t otherCapacity>
Vector<T, InlineCapacity, Allocator, checked_iter>::Vector(
const Vector<T, otherCapacity, Allocator, checked_iter>& other)
: Base(other.capacity()) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U, wtf_size_t otherCapacity, typename Proj, typename>
Vector<T, InlineCapacity, Allocator, checked_iter>::Vector(
const Vector<U, otherCapacity, Allocator>& other,
Proj proj)
: Base(other.capacity()) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
Vector<T, InlineCapacity, Allocator, checked_iter>&
Vector<T, InlineCapacity, Allocator, checked_iter>::operator=(
const Vector& other) { … }
inline bool TypelessPointersAreEqual(const void* a, const void* b) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <wtf_size_t otherCapacity>
Vector<T, InlineCapacity, Allocator, checked_iter>&
Vector<T, InlineCapacity, Allocator, checked_iter>::operator=(
const Vector<T, otherCapacity, Allocator, checked_iter>& other) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename Range>
requires std::ranges::input_range<Range> && std::ranges::sized_range<Range>
void Vector<T, InlineCapacity, Allocator, checked_iter>::assign(
const Range& range) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
Vector<T, InlineCapacity, Allocator, checked_iter>::Vector(Vector&& other) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
Vector<T, InlineCapacity, Allocator, checked_iter>&
Vector<T, InlineCapacity, Allocator, checked_iter>::operator=(Vector&& other) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
Vector<T, InlineCapacity, Allocator, checked_iter>::Vector(
std::initializer_list<T> elements)
: … { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
Vector<T, InlineCapacity, Allocator, checked_iter>&
Vector<T, InlineCapacity, Allocator, checked_iter>::operator=(
std::initializer_list<T> elements) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
bool Vector<T, InlineCapacity, Allocator, checked_iter>::Contains(
const U& value) const { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
wtf_size_t Vector<T, InlineCapacity, Allocator, checked_iter>::Find(
const U& value) const { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
wtf_size_t Vector<T, InlineCapacity, Allocator, checked_iter>::ReverseFind(
const U& value) const { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
void Vector<T, InlineCapacity, Allocator, checked_iter>::Fill(
const T& val,
wtf_size_t new_size)
requires(!Allocator::kIsGarbageCollected)
{ … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
void Vector<T, InlineCapacity, Allocator, checked_iter>::ExpandCapacity(
wtf_size_t new_min_capacity) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
T* Vector<T, InlineCapacity, Allocator, checked_iter>::ExpandCapacity(
wtf_size_t new_min_capacity,
T* ptr) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
inline U* Vector<T, InlineCapacity, Allocator, checked_iter>::ExpandCapacity(
wtf_size_t new_min_capacity,
U* ptr) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::resize(
wtf_size_t size) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
void Vector<T, InlineCapacity, Allocator, checked_iter>::Shrink(
wtf_size_t size) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
void Vector<T, InlineCapacity, Allocator, checked_iter>::Grow(wtf_size_t size) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
void Vector<T, InlineCapacity, Allocator, checked_iter>::reserve(
wtf_size_t new_capacity) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline void
Vector<T, InlineCapacity, Allocator, checked_iter>::ReserveInitialCapacity(
wtf_size_t initial_capacity) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
void Vector<T, InlineCapacity, Allocator, checked_iter>::ShrinkCapacity(
wtf_size_t new_capacity) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
ALWAYS_INLINE void
Vector<T, InlineCapacity, Allocator, checked_iter>::push_back(U&& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename... Args>
ALWAYS_INLINE T&
Vector<T, InlineCapacity, Allocator, checked_iter>::emplace_back(
Args&&... args) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
void Vector<T, InlineCapacity, Allocator, checked_iter>::Append(
const U* data,
wtf_size_t data_size) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
NOINLINE PRESERVE_MOST void
Vector<T, InlineCapacity, Allocator, checked_iter>::AppendSlowCase(U&& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U, wtf_size_t otherCapacity, typename OtherAllocator, bool f>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::AppendVector(
const Vector<U, otherCapacity, OtherAllocator, f>& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename Iterator>
void Vector<T, InlineCapacity, Allocator, checked_iter>::AppendRange(
Iterator begin,
Iterator end) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U, size_t N>
void Vector<T, InlineCapacity, Allocator, checked_iter>::AppendSpan(
base::span<U, N> data) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
ALWAYS_INLINE void
Vector<T, InlineCapacity, Allocator, checked_iter>::UncheckedAppend(U&& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::insert(
wtf_size_t position,
U&& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
void Vector<T, InlineCapacity, Allocator, checked_iter>::insert(
wtf_size_t position,
const U* data,
wtf_size_t data_size) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
void Vector<T, InlineCapacity, Allocator, checked_iter>::InsertAt(
Vector::iterator position,
U&& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
void Vector<T, InlineCapacity, Allocator, checked_iter>::InsertAt(
Vector::iterator position,
const U* data,
wtf_size_t data_size) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U, wtf_size_t otherCapacity, typename OtherAllocator, bool f>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::InsertVector(
wtf_size_t position,
const Vector<U, otherCapacity, OtherAllocator, f>& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::push_front(
U&& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U>
void Vector<T, InlineCapacity, Allocator, checked_iter>::push_front(
const U* data,
wtf_size_t data_size) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
template <typename U, wtf_size_t otherCapacity, typename OtherAllocator, bool f>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::PrependVector(
const Vector<U, otherCapacity, OtherAllocator, f>& val) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::EraseAt(
wtf_size_t position) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline auto Vector<T, InlineCapacity, Allocator, checked_iter>::erase(
iterator position) -> iterator { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline auto Vector<T, InlineCapacity, Allocator, checked_iter>::erase(
iterator first,
iterator last) -> iterator { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::EraseAt(
wtf_size_t position,
wtf_size_t length) { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline void Vector<T, InlineCapacity, Allocator, checked_iter>::Reverse() { … }
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
inline void swap(Vector<T, InlineCapacity, Allocator, checked_iter>& a,
Vector<T, InlineCapacity, Allocator, checked_iter>& b) { … }
template <typename T,
wtf_size_t InlineCapacityA,
wtf_size_t InlineCapacityB,
typename Allocator,
bool checked_iter>
bool operator==(const Vector<T, InlineCapacityA, Allocator, checked_iter>& a,
const Vector<T, InlineCapacityB, Allocator, checked_iter>& b) { … }
template <typename T,
wtf_size_t InlineCapacityA,
wtf_size_t InlineCapacityB,
typename Allocator,
bool checked_iter>
inline bool operator!=(
const Vector<T, InlineCapacityA, Allocator, checked_iter>& a,
const Vector<T, InlineCapacityB, Allocator, checked_iter>& b) { … }
namespace internal {
template <typename Allocator, typename VisitorDispatcher, typename T>
void TraceInlinedBuffer(VisitorDispatcher visitor,
const T* buffer_begin,
size_t capacity) { … }
template <typename Allocator,
typename VisitorDispatcher,
typename T,
wtf_size_t InlineCapacity>
void DeferredTraceImpl(VisitorDispatcher visitor, const void* object) { … }
}
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
void Vector<T, InlineCapacity, Allocator, checked_iter>::Trace(
auto visitor) const
requires Allocator::kIsGarbageCollected
{
static_assert(Allocator::kIsGarbageCollected,
"Garbage collector must be enabled.");
const T* buffer = BufferSafe();
if (!buffer) {
Allocator::TraceVectorBacking(visitor, static_cast<T*>(nullptr),
Base::BufferSlot());
return;
}
if (Base::IsOutOfLineBuffer(buffer)) {
Allocator::TraceVectorBacking(visitor, buffer, Base::BufferSlot());
} else {
Allocator::TraceVectorBacking(visitor, static_cast<T*>(nullptr),
Base::BufferSlot());
if (!VectorTraits<T>::kCanTraceConcurrently) {
if (Allocator::DeferTraceToMutatorThreadIfConcurrent(
visitor, buffer,
internal::DeferredTraceImpl<Allocator, decltype(visitor), T,
InlineCapacity>,
InlineCapacity * sizeof(T))) {
return;
}
}
internal::TraceInlinedBuffer<Allocator>(visitor, buffer, InlineCapacity);
}
}
template <typename T,
wtf_size_t InlineCapacity,
typename Allocator,
bool checked_iter>
void Vector<T, InlineCapacity, Allocator, checked_iter>::ReallocateBuffer(
wtf_size_t new_capacity) { … }
template <typename T,
wtf_size_t inline_capacity,
typename Allocator,
bool checked_iter,
typename U>
wtf_size_t Erase(Vector<T, inline_capacity, Allocator, checked_iter>& v,
const U& value) { … }
template <typename T,
wtf_size_t inline_capacity,
typename Allocator,
bool checked_iter,
typename Pred>
wtf_size_t EraseIf(Vector<T, inline_capacity, Allocator, checked_iter>& v,
Pred pred) { … }
}
Vector;
#endif