5#ifndef V8_ZONE_ZONE_CONTAINERS_H_
6#define V8_ZONE_ZONE_CONTAINERS_H_
10#include <initializer_list>
17#include <unordered_map>
18#include <unordered_set>
20#include "absl/container/btree_map.h"
21#include "absl/container/flat_hash_map.h"
22#include "absl/container/flat_hash_set.h"
86 size_t size = list.size();
99 typename =
typename std::iterator_traits<It>::iterator_category>
101 if constexpr (std::is_base_of_v<
102 std::random_access_iterator_tag,
103 typename std::iterator_traits<It>::iterator_category>) {
104 size_t size = last - first;
109 while (first != last)
push_back(*first++);
121 for (T* p =
data_; p <
end_; p++) p->~T();
130 T* src = other.data_;
133 if constexpr (std::is_trivially_copyable_v<T>) {
134 size_t size = other.size();
135 if (size) memcpy(dst, src, size *
sizeof(T));
137 }
else if constexpr (std::is_copy_assignable_v<T>) {
138 while (dst <
end_ && src < other.end_) *dst++ = *src++;
139 while (src < other.end_)
emplace(dst++, *src++);
142 for (T* p =
end_; p < old_end; p++) p->~T();
144 for (T* p =
data_; p <
end_; p++) p->~T();
145 while (src < other.end_)
emplace(dst++, *src++);
149 for (T* p =
data_; p <
end_; p++) p->~T();
151 size_t new_cap = other.capacity();
170 if (
zone_ ==
nullptr) {
175 for (T* p =
data_; p <
end_; p++) p->~T();
181 other.data_ = other.end_ = other.capacity_ =
nullptr;
195 std::swap(
data_, other.data_);
196 std::swap(
end_, other.end_);
202 T* new_end =
data_ + new_size;
204 for (T* p = new_end; p <
end_; p++) p->~T();
208 void resize(
size_t new_size,
const T& value) {
210 T* new_end =
data_ + new_size;
211 for (T* p =
end_; p < new_end; p++)
emplace(p, value);
212 for (T* p = new_end; p <
end_; p++) p->~T();
216 void assign(
size_t new_size,
const T& value) {
218 T* new_end =
data_ + new_size;
219 T* assignable =
data_ + std::min(
size(), new_size);
222 for (T* p = new_end; p <
end_; p++) p->~T();
227 T* new_end =
data_ + new_size;
234 for (T* p =
data_; p <
end_; p++) p->~T();
285 return std::make_reverse_iterator(
end());
288 return std::make_reverse_iterator(
end());
291 return std::make_reverse_iterator(
cend());
294 return std::make_reverse_iterator(
begin());
297 return std::make_reverse_iterator(
begin());
300 return std::make_reverse_iterator(
cbegin());
314 template <
typename... Args>
318 new (ptr)
T(std::forward<Args>(
args)...);
323 typename =
typename std::iterator_traits<It>::iterator_category>
326 if constexpr (std::is_base_of_v<
327 std::random_access_iterator_tag,
328 typename std::iterator_traits<It>::iterator_category>) {
330 size_t count = last - first;
333 if constexpr (std::is_trivially_copyable_v<T>) {
339 }
else if (
pos ==
end()) {
341 while (first != last) {
361 T* stop = dst + assignable;
366 while (dst < stop)
emplace(dst++, value);
372 if (
pos ==
end())
return const_cast<T*
>(
pos);
375 T*
erase(
const T* first,
const T* last) {
377 if (first == last)
return const_cast<T*
>(first);
378 return erase(first, last - first);
390 return new_capacity < minimum ? minimum : new_capacity;
406 if constexpr (std::is_move_constructible_v<T>) {
414 if constexpr (std::is_copy_assignable_v<T>) {
423 if constexpr (std::is_move_assignable_v<T>) {
424 *dst = std::move(*src);
430#define EMIT_TRIVIAL_CASE(memcpy_function) \
431 DCHECK_LE(src, src_end); \
432 if constexpr (std::is_trivially_copyable_v<T>) { \
433 size_t count = src_end - src; \
435 V8_ASSUME(src != nullptr); \
436 memcpy_function(dst, src, count * sizeof(T)); \
442 for (; src < src_end; dst++, src++) {
449 for (; src < src_end; dst++, src++) {
457 for (; src < src_end; dst++, src++) {
464 for (; src < src_end; dst++, src++) {
469#undef EMIT_TRIVIAL_CASE
474 size_t old_size =
size();
489 size_t to_shift =
end() -
pos;
495 size_t old_size =
size();
529 size_t assignable_slots = std::min(to_shift,
count);
530 *assignable = assignable_slots;
531 if constexpr (std::is_trivially_copyable_v<T>) {
535 memmove(
const_cast<T*
>(
pos +
count),
pos, to_shift *
sizeof(T));
544 for (T* stop = dst - assignable_slots; dst > stop;) {
562 T*
position =
const_cast<T*
>(first);
566 for (T* p =
end_; p < old_end; p++) p->~T();
570 template <
typename... Args>
588 return !(lhs == rhs);
593 return std::lexicographical_compare(lhs.
begin(), lhs.
end(), rhs.
begin(),
597template <
class T,
class GetIntrusiveSetIndex>
605using base::IntrusiveSetIndex;
610class ZoneDeque :
public std::deque<T, RecyclingZoneAllocator<T>> {
642template <
typename T,
typename Compare = std::less<T>>
644 :
public std::priority_queue<T, ZoneVector<T>, Compare> {
674template <
typename K,
typename Compare = std::less<K>>
675class ZoneSet :
public std::set<K, Compare, ZoneAllocator<K>> {
685template <
typename K,
typename Compare = std::less<K>>
686class ZoneMultiset :
public std::multiset<K, Compare, ZoneAllocator<K>> {
696template <
typename K,
typename V,
typename Compare = std::less<K>>
698 :
public std::map<K, V, Compare, ZoneAllocator<std::pair<const K, V>>> {
708template <
typename K,
typename V,
typename Hash = base::hash<K>,
709 typename KeyEqual = std::equal_to<K>>
711 :
public std::unordered_map<K, V, Hash, KeyEqual,
712 ZoneAllocator<std::pair<const K, V>>> {
716 :
std::unordered_map<
K,
V,
Hash, KeyEqual,
718 bucket_count,
Hash(), KeyEqual(),
724template <
typename K,
typename Hash = base::hash<K>,
725 typename KeyEqual = std::equal_to<K>>
727 :
public std::unordered_set<K, Hash, KeyEqual, ZoneAllocator<K>> {
737template <
typename K,
typename V,
typename Compare = std::less<K>>
739 :
public std::multimap<K, V, Compare,
740 ZoneAllocator<std::pair<const K, V>>> {
750template <
typename T,
size_t kSize>
764template <
typename ZoneMap>
777template <
typename K,
typename V,
size_t kArraySize,
778 typename Compare = std::less<K>,
typename KeyEqual = std::equal_to<K>>
780 :
public base::SmallMap<ZoneMap<K, V, Compare>, kArraySize, KeyEqual,
781 ZoneMapInit<ZoneMap<K, V, Compare>>> {
793template <
typename K,
typename V,
794 typename Hash =
typename absl::flat_hash_map<K, V>::hasher,
796 typename absl::flat_hash_map<K, V, Hash>::key_equal>
798 :
public absl::flat_hash_map<K, V, Hash, KeyEqual,
799 ZoneAllocator<std::pair<const K, V>>> {
803 : absl::flat_hash_map<
K,
V,
Hash, KeyEqual,
805 bucket_count,
Hash(), KeyEqual(),
813template <typename K, typename Hash = typename absl::flat_hash_set<K>::hasher,
814 typename KeyEqual =
typename absl::flat_hash_set<K, Hash>::key_equal>
816 :
public absl::flat_hash_set<K, Hash, KeyEqual, ZoneAllocator<K>> {
828template <
typename K,
typename V,
typename Compare = std::less<K>>
830 :
public absl::btree_map<K, V, Compare,
831 ZoneAllocator<std::pair<const K, V>>> {
IntrusiveSet(ZoneVector< T > container, GetIntrusiveSetIndex index_functor={})
SmallZoneVector(size_t size, Zone *zone)
SmallZoneVector(Zone *zone)
ZoneAbslBTreeMap(Zone *zone)
ZoneAbslFlatHashMap(Zone *zone, size_t bucket_count=0)
ZoneAbslFlatHashSet(Zone *zone, size_t bucket_count=0)
ZoneForwardList(Zone *zone)
ZoneIntrusiveSet(Zone *zone, GetIntrusiveSetIndex index_functor={})
ZoneLinkedList(Zone *zone)
void operator()(ZoneMap *map) const
ZonePriorityQueue(Zone *zone)
ZoneUnorderedMap(Zone *zone, size_t bucket_count=0)
ZoneUnorderedSet(Zone *zone, size_t bucket_count=0)
void emplace(T *target, Args &&... args)
reverse_iterator rbegin() V8_NOEXCEPT
V8_INLINE void MoveToNewStorage(T *dst, T *src)
T * insert(const T *pos, size_t count, const T &value)
void reserve(size_t new_cap)
V8_INLINE void CopyingOverwrite(T *dst, const T *src)
V8_INLINE void EnsureOneMoreCapacity()
V8_INLINE void MovingOverwrite(T *dst, T *src, const T *src_end)
ZoneVector & operator=(std::initializer_list< T > ilist)
void swap(ZoneVector< T > &other) noexcept
static constexpr size_t kMinCapacity
std::reverse_iterator< const T * > const_reverse_iterator
void resize(size_t new_size)
V8_NOINLINE V8_PRESERVE_MOST void Grow(size_t minimum)
V8_INLINE void CopyToNewStorage(T *dst, const T *src, const T *src_end)
V8_INLINE void EnsureCapacity(size_t minimum)
const T & const_reference
const_reverse_iterator rbegin() const V8_NOEXCEPT
const T * cbegin() const V8_NOEXCEPT
T * erase(const T *first, const T *last)
void assign(size_t new_size, const T &value)
T * PrepareForInsertion(const T *pos, size_t count, size_t *assignable)
std::reverse_iterator< T * > reverse_iterator
V8_INLINE void MoveToNewStorage(T *dst, T *src, const T *src_end)
T * insert(const T *pos, It first, It last)
ZoneVector & operator=(const ZoneVector &other) V8_NOEXCEPT
const T & operator[](size_t pos) const
const T * end() const V8_NOEXCEPT
V8_INLINE void CopyingOverwrite(T *dst, const T *src, const T *src_end)
T & operator[](size_t pos)
V8_INLINE void MovingOverwrite(T *dst, T *src)
reverse_iterator rend() V8_NOEXCEPT
ZoneVector(size_t size, T def, Zone *zone)
ZoneVector(ZoneVector &&other) V8_NOEXCEPT
const_reverse_iterator crbegin() const V8_NOEXCEPT
const T * cend() const V8_NOEXCEPT
ZoneVector(std::initializer_list< T > list, Zone *zone)
const_reverse_iterator rend() const V8_NOEXCEPT
const_reverse_iterator crend() const V8_NOEXCEPT
const T & at(size_t pos) const
void resize(size_t new_size, const T &value)
V8_INLINE void CopyToNewStorage(T *dst, const T *src)
size_t NewCapacity(size_t minimum)
T * erase(const T *first, size_t count)
const T * begin() const V8_NOEXCEPT
ZoneVector(const ZoneVector &other) V8_NOEXCEPT
T & emplace_back(Args &&... args)
ZoneVector & operator=(ZoneVector &&other) V8_NOEXCEPT
ZoneVector(It first, It last, Zone *zone)
void push_back(const T &value)
void push_back(T &&value)
ZoneVector(size_t size, Zone *zone)
T * AllocateArray(size_t length)
void DeleteArray(T *pointer, size_t length)
base::Vector< const DirectHandle< Object > > args
bool operator!=(ExternalReference lhs, ExternalReference rhs)
static const uint32_t K[64]
V8_INLINE constexpr bool operator<(Builtin a, Builtin b)
static uint32_t Hash(RegisteredExtension *extension)
bool operator==(ExternalReference lhs, ExternalReference rhs)
int Compare(const T &a, const T &b)
#define DCHECK_LE(v1, v2)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define V8_LIKELY(condition)
#define EMIT_TRIVIAL_CASE(memcpy_function)