xref: /aosp_15_r20/external/angle/src/common/FastVector.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // FastVector.h:
7*8975f5c5SAndroid Build Coastguard Worker //   A vector class with a initial fixed size and variable growth.
8*8975f5c5SAndroid Build Coastguard Worker //   Based on FixedVector.
9*8975f5c5SAndroid Build Coastguard Worker //
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #ifndef COMMON_FASTVECTOR_H_
12*8975f5c5SAndroid Build Coastguard Worker #define COMMON_FASTVECTOR_H_
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker #include "bitset_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
18*8975f5c5SAndroid Build Coastguard Worker #include <array>
19*8975f5c5SAndroid Build Coastguard Worker #include <cstring>
20*8975f5c5SAndroid Build Coastguard Worker #include <initializer_list>
21*8975f5c5SAndroid Build Coastguard Worker #include <iterator>
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker namespace angle
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker 
26*8975f5c5SAndroid Build Coastguard Worker template <class Iter>
27*8975f5c5SAndroid Build Coastguard Worker class WrapIter
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker   public:
30*8975f5c5SAndroid Build Coastguard Worker     typedef Iter iterator_type;
31*8975f5c5SAndroid Build Coastguard Worker     typedef typename std::iterator_traits<iterator_type>::value_type value_type;
32*8975f5c5SAndroid Build Coastguard Worker     typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
33*8975f5c5SAndroid Build Coastguard Worker     typedef typename std::iterator_traits<iterator_type>::pointer pointer;
34*8975f5c5SAndroid Build Coastguard Worker     typedef typename std::iterator_traits<iterator_type>::reference reference;
35*8975f5c5SAndroid Build Coastguard Worker     typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
36*8975f5c5SAndroid Build Coastguard Worker 
WrapIter()37*8975f5c5SAndroid Build Coastguard Worker     WrapIter() : mIter() {}
38*8975f5c5SAndroid Build Coastguard Worker     WrapIter(const WrapIter &x)            = default;
39*8975f5c5SAndroid Build Coastguard Worker     WrapIter &operator=(const WrapIter &x) = default;
WrapIter(const Iter & iter)40*8975f5c5SAndroid Build Coastguard Worker     WrapIter(const Iter &iter) : mIter(iter) {}
41*8975f5c5SAndroid Build Coastguard Worker     ~WrapIter() = default;
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker     bool operator==(const WrapIter &x) const { return mIter == x.mIter; }
44*8975f5c5SAndroid Build Coastguard Worker     bool operator!=(const WrapIter &x) const { return mIter != x.mIter; }
45*8975f5c5SAndroid Build Coastguard Worker     bool operator<(const WrapIter &x) const { return mIter < x.mIter; }
46*8975f5c5SAndroid Build Coastguard Worker     bool operator<=(const WrapIter &x) const { return mIter <= x.mIter; }
47*8975f5c5SAndroid Build Coastguard Worker     bool operator>(const WrapIter &x) const { return mIter > x.mIter; }
48*8975f5c5SAndroid Build Coastguard Worker     bool operator>=(const WrapIter &x) const { return mIter >= x.mIter; }
49*8975f5c5SAndroid Build Coastguard Worker 
50*8975f5c5SAndroid Build Coastguard Worker     WrapIter &operator++()
51*8975f5c5SAndroid Build Coastguard Worker     {
52*8975f5c5SAndroid Build Coastguard Worker         mIter++;
53*8975f5c5SAndroid Build Coastguard Worker         return *this;
54*8975f5c5SAndroid Build Coastguard Worker     }
55*8975f5c5SAndroid Build Coastguard Worker 
56*8975f5c5SAndroid Build Coastguard Worker     WrapIter operator++(int)
57*8975f5c5SAndroid Build Coastguard Worker     {
58*8975f5c5SAndroid Build Coastguard Worker         WrapIter tmp(mIter);
59*8975f5c5SAndroid Build Coastguard Worker         mIter++;
60*8975f5c5SAndroid Build Coastguard Worker         return tmp;
61*8975f5c5SAndroid Build Coastguard Worker     }
62*8975f5c5SAndroid Build Coastguard Worker 
63*8975f5c5SAndroid Build Coastguard Worker     WrapIter operator+(difference_type n)
64*8975f5c5SAndroid Build Coastguard Worker     {
65*8975f5c5SAndroid Build Coastguard Worker         WrapIter tmp(mIter);
66*8975f5c5SAndroid Build Coastguard Worker         tmp.mIter += n;
67*8975f5c5SAndroid Build Coastguard Worker         return tmp;
68*8975f5c5SAndroid Build Coastguard Worker     }
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker     WrapIter operator-(difference_type n)
71*8975f5c5SAndroid Build Coastguard Worker     {
72*8975f5c5SAndroid Build Coastguard Worker         WrapIter tmp(mIter);
73*8975f5c5SAndroid Build Coastguard Worker         tmp.mIter -= n;
74*8975f5c5SAndroid Build Coastguard Worker         return tmp;
75*8975f5c5SAndroid Build Coastguard Worker     }
76*8975f5c5SAndroid Build Coastguard Worker 
77*8975f5c5SAndroid Build Coastguard Worker     difference_type operator-(const WrapIter &x) const { return mIter - x.mIter; }
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker     iterator_type operator->() const { return mIter; }
80*8975f5c5SAndroid Build Coastguard Worker 
81*8975f5c5SAndroid Build Coastguard Worker     reference operator*() const { return *mIter; }
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker   private:
84*8975f5c5SAndroid Build Coastguard Worker     iterator_type mIter;
85*8975f5c5SAndroid Build Coastguard Worker };
86*8975f5c5SAndroid Build Coastguard Worker 
87*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage = std::array<T, N>>
88*8975f5c5SAndroid Build Coastguard Worker class FastVector final
89*8975f5c5SAndroid Build Coastguard Worker {
90*8975f5c5SAndroid Build Coastguard Worker   public:
91*8975f5c5SAndroid Build Coastguard Worker     using value_type      = typename Storage::value_type;
92*8975f5c5SAndroid Build Coastguard Worker     using size_type       = typename Storage::size_type;
93*8975f5c5SAndroid Build Coastguard Worker     using reference       = typename Storage::reference;
94*8975f5c5SAndroid Build Coastguard Worker     using const_reference = typename Storage::const_reference;
95*8975f5c5SAndroid Build Coastguard Worker     using pointer         = typename Storage::pointer;
96*8975f5c5SAndroid Build Coastguard Worker     using const_pointer   = typename Storage::const_pointer;
97*8975f5c5SAndroid Build Coastguard Worker     using iterator        = WrapIter<T *>;
98*8975f5c5SAndroid Build Coastguard Worker     using const_iterator  = WrapIter<const T *>;
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker     // This class does not call destructors when resizing down (for performance reasons).
101*8975f5c5SAndroid Build Coastguard Worker     static_assert(std::is_trivially_destructible_v<value_type>);
102*8975f5c5SAndroid Build Coastguard Worker 
103*8975f5c5SAndroid Build Coastguard Worker     FastVector();
104*8975f5c5SAndroid Build Coastguard Worker     FastVector(size_type count, const value_type &value);
105*8975f5c5SAndroid Build Coastguard Worker     FastVector(size_type count);
106*8975f5c5SAndroid Build Coastguard Worker 
107*8975f5c5SAndroid Build Coastguard Worker     FastVector(const FastVector<T, N, Storage> &other);
108*8975f5c5SAndroid Build Coastguard Worker     FastVector(FastVector<T, N, Storage> &&other);
109*8975f5c5SAndroid Build Coastguard Worker     FastVector(std::initializer_list<value_type> init);
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker     template <class InputIt, std::enable_if_t<!std::is_integral<InputIt>::value, bool> = true>
112*8975f5c5SAndroid Build Coastguard Worker     FastVector(InputIt first, InputIt last);
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker     FastVector<T, N, Storage> &operator=(const FastVector<T, N, Storage> &other);
115*8975f5c5SAndroid Build Coastguard Worker     FastVector<T, N, Storage> &operator=(FastVector<T, N, Storage> &&other);
116*8975f5c5SAndroid Build Coastguard Worker     FastVector<T, N, Storage> &operator=(std::initializer_list<value_type> init);
117*8975f5c5SAndroid Build Coastguard Worker 
118*8975f5c5SAndroid Build Coastguard Worker     ~FastVector();
119*8975f5c5SAndroid Build Coastguard Worker 
120*8975f5c5SAndroid Build Coastguard Worker     reference at(size_type pos);
121*8975f5c5SAndroid Build Coastguard Worker     const_reference at(size_type pos) const;
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker     reference operator[](size_type pos);
124*8975f5c5SAndroid Build Coastguard Worker     const_reference operator[](size_type pos) const;
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker     pointer data();
127*8975f5c5SAndroid Build Coastguard Worker     const_pointer data() const;
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker     iterator begin();
130*8975f5c5SAndroid Build Coastguard Worker     const_iterator begin() const;
131*8975f5c5SAndroid Build Coastguard Worker 
132*8975f5c5SAndroid Build Coastguard Worker     iterator end();
133*8975f5c5SAndroid Build Coastguard Worker     const_iterator end() const;
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker     bool empty() const;
136*8975f5c5SAndroid Build Coastguard Worker     size_type size() const;
137*8975f5c5SAndroid Build Coastguard Worker 
138*8975f5c5SAndroid Build Coastguard Worker     void clear();
139*8975f5c5SAndroid Build Coastguard Worker 
140*8975f5c5SAndroid Build Coastguard Worker     void push_back(const value_type &value);
141*8975f5c5SAndroid Build Coastguard Worker     void push_back(value_type &&value);
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker     template <typename... Args>
144*8975f5c5SAndroid Build Coastguard Worker     void emplace_back(Args &&...args);
145*8975f5c5SAndroid Build Coastguard Worker 
146*8975f5c5SAndroid Build Coastguard Worker     void pop_back();
147*8975f5c5SAndroid Build Coastguard Worker 
148*8975f5c5SAndroid Build Coastguard Worker     reference front();
149*8975f5c5SAndroid Build Coastguard Worker     const_reference front() const;
150*8975f5c5SAndroid Build Coastguard Worker 
151*8975f5c5SAndroid Build Coastguard Worker     reference back();
152*8975f5c5SAndroid Build Coastguard Worker     const_reference back() const;
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker     void swap(FastVector<T, N, Storage> &other);
155*8975f5c5SAndroid Build Coastguard Worker     void resetWithRawData(size_type count, const uint8_t *data);
156*8975f5c5SAndroid Build Coastguard Worker 
157*8975f5c5SAndroid Build Coastguard Worker     void resize(size_type count);
158*8975f5c5SAndroid Build Coastguard Worker     void resize(size_type count, const value_type &value);
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker     // Only for use with non trivially constructible types.
161*8975f5c5SAndroid Build Coastguard Worker     // When increasing size, new elements may have previous values. Use with caution in cases when
162*8975f5c5SAndroid Build Coastguard Worker     // initialization of new elements is not required (will be explicitly initialized later), or
163*8975f5c5SAndroid Build Coastguard Worker     // is never resizing down (not possible to reuse previous values).
164*8975f5c5SAndroid Build Coastguard Worker     void resize_maybe_value_reuse(size_type count);
165*8975f5c5SAndroid Build Coastguard Worker     // Only for use with non trivially constructible types.
166*8975f5c5SAndroid Build Coastguard Worker     // No new elements added, so this function is safe to use. Generates ASSERT() if try resize up.
167*8975f5c5SAndroid Build Coastguard Worker     void resize_down(size_type count);
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker     void reserve(size_type count);
170*8975f5c5SAndroid Build Coastguard Worker 
171*8975f5c5SAndroid Build Coastguard Worker     // Specialty function that removes a known element and might shuffle the list.
172*8975f5c5SAndroid Build Coastguard Worker     void remove_and_permute(const value_type &element);
173*8975f5c5SAndroid Build Coastguard Worker     void remove_and_permute(iterator pos);
174*8975f5c5SAndroid Build Coastguard Worker 
175*8975f5c5SAndroid Build Coastguard Worker   private:
176*8975f5c5SAndroid Build Coastguard Worker     void assign_from_initializer_list(std::initializer_list<value_type> init);
177*8975f5c5SAndroid Build Coastguard Worker     void ensure_capacity(size_t capacity);
178*8975f5c5SAndroid Build Coastguard Worker     bool uses_fixed_storage() const;
179*8975f5c5SAndroid Build Coastguard Worker     void resize_impl(size_type count);
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker     Storage mFixedStorage;
182*8975f5c5SAndroid Build Coastguard Worker     pointer mData           = mFixedStorage.data();
183*8975f5c5SAndroid Build Coastguard Worker     size_type mSize         = 0;
184*8975f5c5SAndroid Build Coastguard Worker     size_type mReservedSize = N;
185*8975f5c5SAndroid Build Coastguard Worker };
186*8975f5c5SAndroid Build Coastguard Worker 
187*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class StorageN, size_t M, class StorageM>
188*8975f5c5SAndroid Build Coastguard Worker bool operator==(const FastVector<T, N, StorageN> &a, const FastVector<T, M, StorageM> &b)
189*8975f5c5SAndroid Build Coastguard Worker {
190*8975f5c5SAndroid Build Coastguard Worker     return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
191*8975f5c5SAndroid Build Coastguard Worker }
192*8975f5c5SAndroid Build Coastguard Worker 
193*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class StorageN, size_t M, class StorageM>
194*8975f5c5SAndroid Build Coastguard Worker bool operator!=(const FastVector<T, N, StorageN> &a, const FastVector<T, M, StorageM> &b)
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker     return !(a == b);
197*8975f5c5SAndroid Build Coastguard Worker }
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
uses_fixed_storage()200*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE bool FastVector<T, N, Storage>::uses_fixed_storage() const
201*8975f5c5SAndroid Build Coastguard Worker {
202*8975f5c5SAndroid Build Coastguard Worker     return mData == mFixedStorage.data();
203*8975f5c5SAndroid Build Coastguard Worker }
204*8975f5c5SAndroid Build Coastguard Worker 
205*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
FastVector()206*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::FastVector()
207*8975f5c5SAndroid Build Coastguard Worker {}
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
FastVector(size_type count,const value_type & value)210*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::FastVector(size_type count, const value_type &value)
211*8975f5c5SAndroid Build Coastguard Worker {
212*8975f5c5SAndroid Build Coastguard Worker     ensure_capacity(count);
213*8975f5c5SAndroid Build Coastguard Worker     mSize = count;
214*8975f5c5SAndroid Build Coastguard Worker     std::fill(begin(), end(), value);
215*8975f5c5SAndroid Build Coastguard Worker }
216*8975f5c5SAndroid Build Coastguard Worker 
217*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
FastVector(size_type count)218*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::FastVector(size_type count)
219*8975f5c5SAndroid Build Coastguard Worker {
220*8975f5c5SAndroid Build Coastguard Worker     ensure_capacity(count);
221*8975f5c5SAndroid Build Coastguard Worker     mSize = count;
222*8975f5c5SAndroid Build Coastguard Worker }
223*8975f5c5SAndroid Build Coastguard Worker 
224*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
FastVector(const FastVector<T,N,Storage> & other)225*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::FastVector(const FastVector<T, N, Storage> &other)
226*8975f5c5SAndroid Build Coastguard Worker     : FastVector(other.begin(), other.end())
227*8975f5c5SAndroid Build Coastguard Worker {}
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
FastVector(FastVector<T,N,Storage> && other)230*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::FastVector(FastVector<T, N, Storage> &&other) : FastVector()
231*8975f5c5SAndroid Build Coastguard Worker {
232*8975f5c5SAndroid Build Coastguard Worker     swap(other);
233*8975f5c5SAndroid Build Coastguard Worker }
234*8975f5c5SAndroid Build Coastguard Worker 
235*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
FastVector(std::initializer_list<value_type> init)236*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::FastVector(std::initializer_list<value_type> init)
237*8975f5c5SAndroid Build Coastguard Worker {
238*8975f5c5SAndroid Build Coastguard Worker     assign_from_initializer_list(init);
239*8975f5c5SAndroid Build Coastguard Worker }
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
242*8975f5c5SAndroid Build Coastguard Worker template <class InputIt, std::enable_if_t<!std::is_integral<InputIt>::value, bool>>
FastVector(InputIt first,InputIt last)243*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::FastVector(InputIt first, InputIt last)
244*8975f5c5SAndroid Build Coastguard Worker {
245*8975f5c5SAndroid Build Coastguard Worker     size_t newSize = last - first;
246*8975f5c5SAndroid Build Coastguard Worker     ensure_capacity(newSize);
247*8975f5c5SAndroid Build Coastguard Worker     mSize = newSize;
248*8975f5c5SAndroid Build Coastguard Worker     std::copy(first, last, begin());
249*8975f5c5SAndroid Build Coastguard Worker }
250*8975f5c5SAndroid Build Coastguard Worker 
251*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
252*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=(
253*8975f5c5SAndroid Build Coastguard Worker     const FastVector<T, N, Storage> &other)
254*8975f5c5SAndroid Build Coastguard Worker {
255*8975f5c5SAndroid Build Coastguard Worker     ensure_capacity(other.mSize);
256*8975f5c5SAndroid Build Coastguard Worker     mSize = other.mSize;
257*8975f5c5SAndroid Build Coastguard Worker     std::copy(other.begin(), other.end(), begin());
258*8975f5c5SAndroid Build Coastguard Worker     return *this;
259*8975f5c5SAndroid Build Coastguard Worker }
260*8975f5c5SAndroid Build Coastguard Worker 
261*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
262*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=(FastVector<T, N, Storage> &&other)
263*8975f5c5SAndroid Build Coastguard Worker {
264*8975f5c5SAndroid Build Coastguard Worker     swap(other);
265*8975f5c5SAndroid Build Coastguard Worker     return *this;
266*8975f5c5SAndroid Build Coastguard Worker }
267*8975f5c5SAndroid Build Coastguard Worker 
268*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
269*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=(
270*8975f5c5SAndroid Build Coastguard Worker     std::initializer_list<value_type> init)
271*8975f5c5SAndroid Build Coastguard Worker {
272*8975f5c5SAndroid Build Coastguard Worker     assign_from_initializer_list(init);
273*8975f5c5SAndroid Build Coastguard Worker     return *this;
274*8975f5c5SAndroid Build Coastguard Worker }
275*8975f5c5SAndroid Build Coastguard Worker 
276*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
~FastVector()277*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::~FastVector()
278*8975f5c5SAndroid Build Coastguard Worker {
279*8975f5c5SAndroid Build Coastguard Worker     clear();
280*8975f5c5SAndroid Build Coastguard Worker     if (!uses_fixed_storage())
281*8975f5c5SAndroid Build Coastguard Worker     {
282*8975f5c5SAndroid Build Coastguard Worker         delete[] mData;
283*8975f5c5SAndroid Build Coastguard Worker     }
284*8975f5c5SAndroid Build Coastguard Worker }
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
at(size_type pos)287*8975f5c5SAndroid Build Coastguard Worker typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::at(size_type pos)
288*8975f5c5SAndroid Build Coastguard Worker {
289*8975f5c5SAndroid Build Coastguard Worker     ASSERT(pos < mSize);
290*8975f5c5SAndroid Build Coastguard Worker     return mData[pos];
291*8975f5c5SAndroid Build Coastguard Worker }
292*8975f5c5SAndroid Build Coastguard Worker 
293*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
at(size_type pos)294*8975f5c5SAndroid Build Coastguard Worker typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::at(
295*8975f5c5SAndroid Build Coastguard Worker     size_type pos) const
296*8975f5c5SAndroid Build Coastguard Worker {
297*8975f5c5SAndroid Build Coastguard Worker     ASSERT(pos < mSize);
298*8975f5c5SAndroid Build Coastguard Worker     return mData[pos];
299*8975f5c5SAndroid Build Coastguard Worker }
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
302*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::operator[](
303*8975f5c5SAndroid Build Coastguard Worker     size_type pos)
304*8975f5c5SAndroid Build Coastguard Worker {
305*8975f5c5SAndroid Build Coastguard Worker     ASSERT(pos < mSize);
306*8975f5c5SAndroid Build Coastguard Worker     return mData[pos];
307*8975f5c5SAndroid Build Coastguard Worker }
308*8975f5c5SAndroid Build Coastguard Worker 
309*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
310*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference
311*8975f5c5SAndroid Build Coastguard Worker FastVector<T, N, Storage>::operator[](size_type pos) const
312*8975f5c5SAndroid Build Coastguard Worker {
313*8975f5c5SAndroid Build Coastguard Worker     ASSERT(pos < mSize);
314*8975f5c5SAndroid Build Coastguard Worker     return mData[pos];
315*8975f5c5SAndroid Build Coastguard Worker }
316*8975f5c5SAndroid Build Coastguard Worker 
317*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
318*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::const_pointer
data()319*8975f5c5SAndroid Build Coastguard Worker angle::FastVector<T, N, Storage>::data() const
320*8975f5c5SAndroid Build Coastguard Worker {
321*8975f5c5SAndroid Build Coastguard Worker     return mData;
322*8975f5c5SAndroid Build Coastguard Worker }
323*8975f5c5SAndroid Build Coastguard Worker 
324*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
data()325*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::pointer angle::FastVector<T, N, Storage>::data()
326*8975f5c5SAndroid Build Coastguard Worker {
327*8975f5c5SAndroid Build Coastguard Worker     return mData;
328*8975f5c5SAndroid Build Coastguard Worker }
329*8975f5c5SAndroid Build Coastguard Worker 
330*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
begin()331*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::iterator FastVector<T, N, Storage>::begin()
332*8975f5c5SAndroid Build Coastguard Worker {
333*8975f5c5SAndroid Build Coastguard Worker     return mData;
334*8975f5c5SAndroid Build Coastguard Worker }
335*8975f5c5SAndroid Build Coastguard Worker 
336*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
begin()337*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::const_iterator FastVector<T, N, Storage>::begin()
338*8975f5c5SAndroid Build Coastguard Worker     const
339*8975f5c5SAndroid Build Coastguard Worker {
340*8975f5c5SAndroid Build Coastguard Worker     return mData;
341*8975f5c5SAndroid Build Coastguard Worker }
342*8975f5c5SAndroid Build Coastguard Worker 
343*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
end()344*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::iterator FastVector<T, N, Storage>::end()
345*8975f5c5SAndroid Build Coastguard Worker {
346*8975f5c5SAndroid Build Coastguard Worker     return mData + mSize;
347*8975f5c5SAndroid Build Coastguard Worker }
348*8975f5c5SAndroid Build Coastguard Worker 
349*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
end()350*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::const_iterator FastVector<T, N, Storage>::end()
351*8975f5c5SAndroid Build Coastguard Worker     const
352*8975f5c5SAndroid Build Coastguard Worker {
353*8975f5c5SAndroid Build Coastguard Worker     return mData + mSize;
354*8975f5c5SAndroid Build Coastguard Worker }
355*8975f5c5SAndroid Build Coastguard Worker 
356*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
empty()357*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE bool FastVector<T, N, Storage>::empty() const
358*8975f5c5SAndroid Build Coastguard Worker {
359*8975f5c5SAndroid Build Coastguard Worker     return mSize == 0;
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
size()363*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::size_type FastVector<T, N, Storage>::size() const
364*8975f5c5SAndroid Build Coastguard Worker {
365*8975f5c5SAndroid Build Coastguard Worker     return mSize;
366*8975f5c5SAndroid Build Coastguard Worker }
367*8975f5c5SAndroid Build Coastguard Worker 
368*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
clear()369*8975f5c5SAndroid Build Coastguard Worker void FastVector<T, N, Storage>::clear()
370*8975f5c5SAndroid Build Coastguard Worker {
371*8975f5c5SAndroid Build Coastguard Worker     resize_impl(0);
372*8975f5c5SAndroid Build Coastguard Worker }
373*8975f5c5SAndroid Build Coastguard Worker 
374*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
push_back(const value_type & value)375*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::push_back(const value_type &value)
376*8975f5c5SAndroid Build Coastguard Worker {
377*8975f5c5SAndroid Build Coastguard Worker     if (mSize == mReservedSize)
378*8975f5c5SAndroid Build Coastguard Worker         ensure_capacity(mSize + 1);
379*8975f5c5SAndroid Build Coastguard Worker     mData[mSize++] = value;
380*8975f5c5SAndroid Build Coastguard Worker }
381*8975f5c5SAndroid Build Coastguard Worker 
382*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
push_back(value_type && value)383*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::push_back(value_type &&value)
384*8975f5c5SAndroid Build Coastguard Worker {
385*8975f5c5SAndroid Build Coastguard Worker     emplace_back(std::move(value));
386*8975f5c5SAndroid Build Coastguard Worker }
387*8975f5c5SAndroid Build Coastguard Worker 
388*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
389*8975f5c5SAndroid Build Coastguard Worker template <typename... Args>
emplace_back(Args &&...args)390*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::emplace_back(Args &&...args)
391*8975f5c5SAndroid Build Coastguard Worker {
392*8975f5c5SAndroid Build Coastguard Worker     if (mSize == mReservedSize)
393*8975f5c5SAndroid Build Coastguard Worker         ensure_capacity(mSize + 1);
394*8975f5c5SAndroid Build Coastguard Worker     mData[mSize++] = std::move(T(std::forward<Args>(args)...));
395*8975f5c5SAndroid Build Coastguard Worker }
396*8975f5c5SAndroid Build Coastguard Worker 
397*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
pop_back()398*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::pop_back()
399*8975f5c5SAndroid Build Coastguard Worker {
400*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mSize > 0);
401*8975f5c5SAndroid Build Coastguard Worker     mSize--;
402*8975f5c5SAndroid Build Coastguard Worker }
403*8975f5c5SAndroid Build Coastguard Worker 
404*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
front()405*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::front()
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mSize > 0);
408*8975f5c5SAndroid Build Coastguard Worker     return mData[0];
409*8975f5c5SAndroid Build Coastguard Worker }
410*8975f5c5SAndroid Build Coastguard Worker 
411*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
front()412*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::front()
413*8975f5c5SAndroid Build Coastguard Worker     const
414*8975f5c5SAndroid Build Coastguard Worker {
415*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mSize > 0);
416*8975f5c5SAndroid Build Coastguard Worker     return mData[0];
417*8975f5c5SAndroid Build Coastguard Worker }
418*8975f5c5SAndroid Build Coastguard Worker 
419*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
back()420*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::back()
421*8975f5c5SAndroid Build Coastguard Worker {
422*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mSize > 0);
423*8975f5c5SAndroid Build Coastguard Worker     return mData[mSize - 1];
424*8975f5c5SAndroid Build Coastguard Worker }
425*8975f5c5SAndroid Build Coastguard Worker 
426*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
back()427*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::back()
428*8975f5c5SAndroid Build Coastguard Worker     const
429*8975f5c5SAndroid Build Coastguard Worker {
430*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mSize > 0);
431*8975f5c5SAndroid Build Coastguard Worker     return mData[mSize - 1];
432*8975f5c5SAndroid Build Coastguard Worker }
433*8975f5c5SAndroid Build Coastguard Worker 
434*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
swap(FastVector<T,N,Storage> & other)435*8975f5c5SAndroid Build Coastguard Worker void FastVector<T, N, Storage>::swap(FastVector<T, N, Storage> &other)
436*8975f5c5SAndroid Build Coastguard Worker {
437*8975f5c5SAndroid Build Coastguard Worker     std::swap(mSize, other.mSize);
438*8975f5c5SAndroid Build Coastguard Worker 
439*8975f5c5SAndroid Build Coastguard Worker     pointer tempData = other.mData;
440*8975f5c5SAndroid Build Coastguard Worker     if (uses_fixed_storage())
441*8975f5c5SAndroid Build Coastguard Worker         other.mData = other.mFixedStorage.data();
442*8975f5c5SAndroid Build Coastguard Worker     else
443*8975f5c5SAndroid Build Coastguard Worker         other.mData = mData;
444*8975f5c5SAndroid Build Coastguard Worker     if (tempData == other.mFixedStorage.data())
445*8975f5c5SAndroid Build Coastguard Worker         mData = mFixedStorage.data();
446*8975f5c5SAndroid Build Coastguard Worker     else
447*8975f5c5SAndroid Build Coastguard Worker         mData = tempData;
448*8975f5c5SAndroid Build Coastguard Worker     std::swap(mReservedSize, other.mReservedSize);
449*8975f5c5SAndroid Build Coastguard Worker 
450*8975f5c5SAndroid Build Coastguard Worker     if (uses_fixed_storage() || other.uses_fixed_storage())
451*8975f5c5SAndroid Build Coastguard Worker         std::swap(mFixedStorage, other.mFixedStorage);
452*8975f5c5SAndroid Build Coastguard Worker }
453*8975f5c5SAndroid Build Coastguard Worker 
454*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
resetWithRawData(size_type count,const uint8_t * data)455*8975f5c5SAndroid Build Coastguard Worker void FastVector<T, N, Storage>::resetWithRawData(size_type count, const uint8_t *data)
456*8975f5c5SAndroid Build Coastguard Worker {
457*8975f5c5SAndroid Build Coastguard Worker     static_assert(std::is_trivially_copyable<value_type>(),
458*8975f5c5SAndroid Build Coastguard Worker                   "This is a special method for trivially copyable types.");
459*8975f5c5SAndroid Build Coastguard Worker     ASSERT(count > 0 && data != nullptr);
460*8975f5c5SAndroid Build Coastguard Worker     resize_impl(count);
461*8975f5c5SAndroid Build Coastguard Worker     std::memcpy(mData, data, count * sizeof(value_type));
462*8975f5c5SAndroid Build Coastguard Worker }
463*8975f5c5SAndroid Build Coastguard Worker 
464*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
resize(size_type count)465*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::resize(size_type count)
466*8975f5c5SAndroid Build Coastguard Worker {
467*8975f5c5SAndroid Build Coastguard Worker     // Trivially constructible types will have undefined values when created therefore reusing
468*8975f5c5SAndroid Build Coastguard Worker     // previous values after resize should not be a problem..
469*8975f5c5SAndroid Build Coastguard Worker     static_assert(std::is_trivially_constructible_v<value_type>,
470*8975f5c5SAndroid Build Coastguard Worker                   "For non trivially constructible types please use: resize(count, value), "
471*8975f5c5SAndroid Build Coastguard Worker                   "resize_maybe_value_reuse(count), or resize_down(count) methods.");
472*8975f5c5SAndroid Build Coastguard Worker     resize_impl(count);
473*8975f5c5SAndroid Build Coastguard Worker }
474*8975f5c5SAndroid Build Coastguard Worker 
475*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
resize_maybe_value_reuse(size_type count)476*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::resize_maybe_value_reuse(size_type count)
477*8975f5c5SAndroid Build Coastguard Worker {
478*8975f5c5SAndroid Build Coastguard Worker     static_assert(!std::is_trivially_constructible_v<value_type>,
479*8975f5c5SAndroid Build Coastguard Worker                   "This is a special method for non trivially constructible types. "
480*8975f5c5SAndroid Build Coastguard Worker                   "Please use regular resize(count) method.");
481*8975f5c5SAndroid Build Coastguard Worker     resize_impl(count);
482*8975f5c5SAndroid Build Coastguard Worker }
483*8975f5c5SAndroid Build Coastguard Worker 
484*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
resize_down(size_type count)485*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::resize_down(size_type count)
486*8975f5c5SAndroid Build Coastguard Worker {
487*8975f5c5SAndroid Build Coastguard Worker     static_assert(!std::is_trivially_constructible_v<value_type>,
488*8975f5c5SAndroid Build Coastguard Worker                   "This is a special method for non trivially constructible types. "
489*8975f5c5SAndroid Build Coastguard Worker                   "Please use regular resize(count) method.");
490*8975f5c5SAndroid Build Coastguard Worker     ASSERT(count <= mSize);
491*8975f5c5SAndroid Build Coastguard Worker     resize_impl(count);
492*8975f5c5SAndroid Build Coastguard Worker }
493*8975f5c5SAndroid Build Coastguard Worker 
494*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
resize_impl(size_type count)495*8975f5c5SAndroid Build Coastguard Worker void FastVector<T, N, Storage>::resize_impl(size_type count)
496*8975f5c5SAndroid Build Coastguard Worker {
497*8975f5c5SAndroid Build Coastguard Worker     if (count > mSize)
498*8975f5c5SAndroid Build Coastguard Worker     {
499*8975f5c5SAndroid Build Coastguard Worker         ensure_capacity(count);
500*8975f5c5SAndroid Build Coastguard Worker     }
501*8975f5c5SAndroid Build Coastguard Worker     mSize = count;
502*8975f5c5SAndroid Build Coastguard Worker }
503*8975f5c5SAndroid Build Coastguard Worker 
504*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
resize(size_type count,const value_type & value)505*8975f5c5SAndroid Build Coastguard Worker void FastVector<T, N, Storage>::resize(size_type count, const value_type &value)
506*8975f5c5SAndroid Build Coastguard Worker {
507*8975f5c5SAndroid Build Coastguard Worker     if (count > mSize)
508*8975f5c5SAndroid Build Coastguard Worker     {
509*8975f5c5SAndroid Build Coastguard Worker         ensure_capacity(count);
510*8975f5c5SAndroid Build Coastguard Worker         std::fill(mData + mSize, mData + count, value);
511*8975f5c5SAndroid Build Coastguard Worker     }
512*8975f5c5SAndroid Build Coastguard Worker     mSize = count;
513*8975f5c5SAndroid Build Coastguard Worker }
514*8975f5c5SAndroid Build Coastguard Worker 
515*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
reserve(size_type count)516*8975f5c5SAndroid Build Coastguard Worker void FastVector<T, N, Storage>::reserve(size_type count)
517*8975f5c5SAndroid Build Coastguard Worker {
518*8975f5c5SAndroid Build Coastguard Worker     ensure_capacity(count);
519*8975f5c5SAndroid Build Coastguard Worker }
520*8975f5c5SAndroid Build Coastguard Worker 
521*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
assign_from_initializer_list(std::initializer_list<value_type> init)522*8975f5c5SAndroid Build Coastguard Worker void FastVector<T, N, Storage>::assign_from_initializer_list(std::initializer_list<value_type> init)
523*8975f5c5SAndroid Build Coastguard Worker {
524*8975f5c5SAndroid Build Coastguard Worker     ensure_capacity(init.size());
525*8975f5c5SAndroid Build Coastguard Worker     mSize        = init.size();
526*8975f5c5SAndroid Build Coastguard Worker     size_t index = 0;
527*8975f5c5SAndroid Build Coastguard Worker     for (auto &value : init)
528*8975f5c5SAndroid Build Coastguard Worker     {
529*8975f5c5SAndroid Build Coastguard Worker         mData[index++] = value;
530*8975f5c5SAndroid Build Coastguard Worker     }
531*8975f5c5SAndroid Build Coastguard Worker }
532*8975f5c5SAndroid Build Coastguard Worker 
533*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
remove_and_permute(const value_type & element)534*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::remove_and_permute(const value_type &element)
535*8975f5c5SAndroid Build Coastguard Worker {
536*8975f5c5SAndroid Build Coastguard Worker     size_t len = mSize - 1;
537*8975f5c5SAndroid Build Coastguard Worker     for (size_t index = 0; index < len; ++index)
538*8975f5c5SAndroid Build Coastguard Worker     {
539*8975f5c5SAndroid Build Coastguard Worker         if (mData[index] == element)
540*8975f5c5SAndroid Build Coastguard Worker         {
541*8975f5c5SAndroid Build Coastguard Worker             mData[index] = std::move(mData[len]);
542*8975f5c5SAndroid Build Coastguard Worker             break;
543*8975f5c5SAndroid Build Coastguard Worker         }
544*8975f5c5SAndroid Build Coastguard Worker     }
545*8975f5c5SAndroid Build Coastguard Worker     pop_back();
546*8975f5c5SAndroid Build Coastguard Worker }
547*8975f5c5SAndroid Build Coastguard Worker 
548*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
remove_and_permute(iterator pos)549*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void FastVector<T, N, Storage>::remove_and_permute(iterator pos)
550*8975f5c5SAndroid Build Coastguard Worker {
551*8975f5c5SAndroid Build Coastguard Worker     ASSERT(pos >= begin());
552*8975f5c5SAndroid Build Coastguard Worker     ASSERT(pos < end());
553*8975f5c5SAndroid Build Coastguard Worker     size_t len = mSize - 1;
554*8975f5c5SAndroid Build Coastguard Worker     *pos       = std::move(mData[len]);
555*8975f5c5SAndroid Build Coastguard Worker     pop_back();
556*8975f5c5SAndroid Build Coastguard Worker }
557*8975f5c5SAndroid Build Coastguard Worker 
558*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N, class Storage>
ensure_capacity(size_t capacity)559*8975f5c5SAndroid Build Coastguard Worker void FastVector<T, N, Storage>::ensure_capacity(size_t capacity)
560*8975f5c5SAndroid Build Coastguard Worker {
561*8975f5c5SAndroid Build Coastguard Worker     // We have a minimum capacity of N.
562*8975f5c5SAndroid Build Coastguard Worker     if (mReservedSize < capacity)
563*8975f5c5SAndroid Build Coastguard Worker     {
564*8975f5c5SAndroid Build Coastguard Worker         ASSERT(capacity > N);
565*8975f5c5SAndroid Build Coastguard Worker         size_type newSize = std::max(mReservedSize, N);
566*8975f5c5SAndroid Build Coastguard Worker         while (newSize < capacity)
567*8975f5c5SAndroid Build Coastguard Worker         {
568*8975f5c5SAndroid Build Coastguard Worker             newSize *= 2;
569*8975f5c5SAndroid Build Coastguard Worker         }
570*8975f5c5SAndroid Build Coastguard Worker 
571*8975f5c5SAndroid Build Coastguard Worker         pointer newData = new value_type[newSize];
572*8975f5c5SAndroid Build Coastguard Worker 
573*8975f5c5SAndroid Build Coastguard Worker         if (mSize > 0)
574*8975f5c5SAndroid Build Coastguard Worker         {
575*8975f5c5SAndroid Build Coastguard Worker             std::move(begin(), end(), newData);
576*8975f5c5SAndroid Build Coastguard Worker         }
577*8975f5c5SAndroid Build Coastguard Worker 
578*8975f5c5SAndroid Build Coastguard Worker         if (!uses_fixed_storage())
579*8975f5c5SAndroid Build Coastguard Worker         {
580*8975f5c5SAndroid Build Coastguard Worker             delete[] mData;
581*8975f5c5SAndroid Build Coastguard Worker         }
582*8975f5c5SAndroid Build Coastguard Worker 
583*8975f5c5SAndroid Build Coastguard Worker         mData         = newData;
584*8975f5c5SAndroid Build Coastguard Worker         mReservedSize = newSize;
585*8975f5c5SAndroid Build Coastguard Worker     }
586*8975f5c5SAndroid Build Coastguard Worker }
587*8975f5c5SAndroid Build Coastguard Worker 
588*8975f5c5SAndroid Build Coastguard Worker template <class Value, size_t N, class Storage = FastVector<Value, N>>
589*8975f5c5SAndroid Build Coastguard Worker class FastMap final
590*8975f5c5SAndroid Build Coastguard Worker {
591*8975f5c5SAndroid Build Coastguard Worker   public:
592*8975f5c5SAndroid Build Coastguard Worker     using value_type      = typename Storage::value_type;
593*8975f5c5SAndroid Build Coastguard Worker     using size_type       = typename Storage::size_type;
594*8975f5c5SAndroid Build Coastguard Worker     using reference       = typename Storage::reference;
595*8975f5c5SAndroid Build Coastguard Worker     using const_reference = typename Storage::const_reference;
596*8975f5c5SAndroid Build Coastguard Worker     using pointer         = typename Storage::pointer;
597*8975f5c5SAndroid Build Coastguard Worker     using const_pointer   = typename Storage::const_pointer;
598*8975f5c5SAndroid Build Coastguard Worker     using iterator        = typename Storage::iterator;
599*8975f5c5SAndroid Build Coastguard Worker     using const_iterator  = typename Storage::const_iterator;
600*8975f5c5SAndroid Build Coastguard Worker 
FastMap()601*8975f5c5SAndroid Build Coastguard Worker     FastMap() {}
~FastMap()602*8975f5c5SAndroid Build Coastguard Worker     ~FastMap() {}
603*8975f5c5SAndroid Build Coastguard Worker 
604*8975f5c5SAndroid Build Coastguard Worker     Value &operator[](uint32_t key)
605*8975f5c5SAndroid Build Coastguard Worker     {
606*8975f5c5SAndroid Build Coastguard Worker         if (mData.size() <= key)
607*8975f5c5SAndroid Build Coastguard Worker         {
608*8975f5c5SAndroid Build Coastguard Worker             mData.resize(key + 1, {});
609*8975f5c5SAndroid Build Coastguard Worker         }
610*8975f5c5SAndroid Build Coastguard Worker         return at(key);
611*8975f5c5SAndroid Build Coastguard Worker     }
612*8975f5c5SAndroid Build Coastguard Worker 
613*8975f5c5SAndroid Build Coastguard Worker     const Value &operator[](uint32_t key) const { return at(key); }
614*8975f5c5SAndroid Build Coastguard Worker 
at(uint32_t key)615*8975f5c5SAndroid Build Coastguard Worker     Value &at(uint32_t key)
616*8975f5c5SAndroid Build Coastguard Worker     {
617*8975f5c5SAndroid Build Coastguard Worker         ASSERT(key < mData.size());
618*8975f5c5SAndroid Build Coastguard Worker         return mData[key];
619*8975f5c5SAndroid Build Coastguard Worker     }
620*8975f5c5SAndroid Build Coastguard Worker 
at(uint32_t key)621*8975f5c5SAndroid Build Coastguard Worker     const Value &at(uint32_t key) const
622*8975f5c5SAndroid Build Coastguard Worker     {
623*8975f5c5SAndroid Build Coastguard Worker         ASSERT(key < mData.size());
624*8975f5c5SAndroid Build Coastguard Worker         return mData[key];
625*8975f5c5SAndroid Build Coastguard Worker     }
626*8975f5c5SAndroid Build Coastguard Worker 
clear()627*8975f5c5SAndroid Build Coastguard Worker     void clear() { mData.clear(); }
628*8975f5c5SAndroid Build Coastguard Worker 
resetWithRawData(size_type count,const uint8_t * data)629*8975f5c5SAndroid Build Coastguard Worker     void resetWithRawData(size_type count, const uint8_t *data)
630*8975f5c5SAndroid Build Coastguard Worker     {
631*8975f5c5SAndroid Build Coastguard Worker         mData.resetWithRawData(count, data);
632*8975f5c5SAndroid Build Coastguard Worker     }
633*8975f5c5SAndroid Build Coastguard Worker 
empty()634*8975f5c5SAndroid Build Coastguard Worker     bool empty() const { return mData.empty(); }
size()635*8975f5c5SAndroid Build Coastguard Worker     size_t size() const { return mData.size(); }
636*8975f5c5SAndroid Build Coastguard Worker 
data()637*8975f5c5SAndroid Build Coastguard Worker     const Value *data() const { return mData.data(); }
638*8975f5c5SAndroid Build Coastguard Worker 
639*8975f5c5SAndroid Build Coastguard Worker     bool operator==(const FastMap<Value, N> &other) const
640*8975f5c5SAndroid Build Coastguard Worker     {
641*8975f5c5SAndroid Build Coastguard Worker         return (size() == other.size()) &&
642*8975f5c5SAndroid Build Coastguard Worker                (memcmp(data(), other.data(), size() * sizeof(Value)) == 0);
643*8975f5c5SAndroid Build Coastguard Worker     }
644*8975f5c5SAndroid Build Coastguard Worker 
begin()645*8975f5c5SAndroid Build Coastguard Worker     iterator begin() { return mData.begin(); }
begin()646*8975f5c5SAndroid Build Coastguard Worker     const_iterator begin() const { return mData.begin(); }
647*8975f5c5SAndroid Build Coastguard Worker 
end()648*8975f5c5SAndroid Build Coastguard Worker     iterator end() { return mData.end(); }
end()649*8975f5c5SAndroid Build Coastguard Worker     const_iterator end() const { return mData.end(); }
650*8975f5c5SAndroid Build Coastguard Worker 
651*8975f5c5SAndroid Build Coastguard Worker   private:
652*8975f5c5SAndroid Build Coastguard Worker     FastVector<Value, N> mData;
653*8975f5c5SAndroid Build Coastguard Worker };
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker template <class Key, class Value, size_t N>
656*8975f5c5SAndroid Build Coastguard Worker class FlatUnorderedMap final
657*8975f5c5SAndroid Build Coastguard Worker {
658*8975f5c5SAndroid Build Coastguard Worker   public:
659*8975f5c5SAndroid Build Coastguard Worker     using Pair           = std::pair<Key, Value>;
660*8975f5c5SAndroid Build Coastguard Worker     using Storage        = FastVector<Pair, N>;
661*8975f5c5SAndroid Build Coastguard Worker     using iterator       = typename Storage::iterator;
662*8975f5c5SAndroid Build Coastguard Worker     using const_iterator = typename Storage::const_iterator;
663*8975f5c5SAndroid Build Coastguard Worker 
664*8975f5c5SAndroid Build Coastguard Worker     FlatUnorderedMap()  = default;
665*8975f5c5SAndroid Build Coastguard Worker     ~FlatUnorderedMap() = default;
666*8975f5c5SAndroid Build Coastguard Worker 
begin()667*8975f5c5SAndroid Build Coastguard Worker     iterator begin() { return mData.begin(); }
begin()668*8975f5c5SAndroid Build Coastguard Worker     const_iterator begin() const { return mData.begin(); }
end()669*8975f5c5SAndroid Build Coastguard Worker     iterator end() { return mData.end(); }
end()670*8975f5c5SAndroid Build Coastguard Worker     const_iterator end() const { return mData.end(); }
671*8975f5c5SAndroid Build Coastguard Worker 
find(const Key & key)672*8975f5c5SAndroid Build Coastguard Worker     iterator find(const Key &key)
673*8975f5c5SAndroid Build Coastguard Worker     {
674*8975f5c5SAndroid Build Coastguard Worker         for (auto it = mData.begin(); it != mData.end(); ++it)
675*8975f5c5SAndroid Build Coastguard Worker         {
676*8975f5c5SAndroid Build Coastguard Worker             if (it->first == key)
677*8975f5c5SAndroid Build Coastguard Worker             {
678*8975f5c5SAndroid Build Coastguard Worker                 return it;
679*8975f5c5SAndroid Build Coastguard Worker             }
680*8975f5c5SAndroid Build Coastguard Worker         }
681*8975f5c5SAndroid Build Coastguard Worker         return mData.end();
682*8975f5c5SAndroid Build Coastguard Worker     }
683*8975f5c5SAndroid Build Coastguard Worker 
find(const Key & key)684*8975f5c5SAndroid Build Coastguard Worker     const_iterator find(const Key &key) const
685*8975f5c5SAndroid Build Coastguard Worker     {
686*8975f5c5SAndroid Build Coastguard Worker         for (auto it = mData.begin(); it != mData.end(); ++it)
687*8975f5c5SAndroid Build Coastguard Worker         {
688*8975f5c5SAndroid Build Coastguard Worker             if (it->first == key)
689*8975f5c5SAndroid Build Coastguard Worker             {
690*8975f5c5SAndroid Build Coastguard Worker                 return it;
691*8975f5c5SAndroid Build Coastguard Worker             }
692*8975f5c5SAndroid Build Coastguard Worker         }
693*8975f5c5SAndroid Build Coastguard Worker         return mData.end();
694*8975f5c5SAndroid Build Coastguard Worker     }
695*8975f5c5SAndroid Build Coastguard Worker 
696*8975f5c5SAndroid Build Coastguard Worker     Value &operator[](const Key &key)
697*8975f5c5SAndroid Build Coastguard Worker     {
698*8975f5c5SAndroid Build Coastguard Worker         iterator it = find(key);
699*8975f5c5SAndroid Build Coastguard Worker         if (it != end())
700*8975f5c5SAndroid Build Coastguard Worker         {
701*8975f5c5SAndroid Build Coastguard Worker             return it->second;
702*8975f5c5SAndroid Build Coastguard Worker         }
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker         mData.push_back(Pair(key, {}));
705*8975f5c5SAndroid Build Coastguard Worker         return mData.back().second;
706*8975f5c5SAndroid Build Coastguard Worker     }
707*8975f5c5SAndroid Build Coastguard Worker 
insert(Pair pair)708*8975f5c5SAndroid Build Coastguard Worker     void insert(Pair pair)
709*8975f5c5SAndroid Build Coastguard Worker     {
710*8975f5c5SAndroid Build Coastguard Worker         ASSERT(!contains(pair.first));
711*8975f5c5SAndroid Build Coastguard Worker         mData.push_back(std::move(pair));
712*8975f5c5SAndroid Build Coastguard Worker     }
713*8975f5c5SAndroid Build Coastguard Worker 
insert(const Key & key,Value value)714*8975f5c5SAndroid Build Coastguard Worker     void insert(const Key &key, Value value) { insert(Pair(key, value)); }
715*8975f5c5SAndroid Build Coastguard Worker 
erase(iterator pos)716*8975f5c5SAndroid Build Coastguard Worker     void erase(iterator pos) { mData.remove_and_permute(pos); }
717*8975f5c5SAndroid Build Coastguard Worker 
contains(const Key & key)718*8975f5c5SAndroid Build Coastguard Worker     bool contains(const Key &key) const { return find(key) != end(); }
719*8975f5c5SAndroid Build Coastguard Worker 
clear()720*8975f5c5SAndroid Build Coastguard Worker     void clear() { mData.clear(); }
721*8975f5c5SAndroid Build Coastguard Worker 
get(const Key & key,Value * value)722*8975f5c5SAndroid Build Coastguard Worker     bool get(const Key &key, Value *value) const
723*8975f5c5SAndroid Build Coastguard Worker     {
724*8975f5c5SAndroid Build Coastguard Worker         auto it = find(key);
725*8975f5c5SAndroid Build Coastguard Worker         if (it != end())
726*8975f5c5SAndroid Build Coastguard Worker         {
727*8975f5c5SAndroid Build Coastguard Worker             *value = it->second;
728*8975f5c5SAndroid Build Coastguard Worker             return true;
729*8975f5c5SAndroid Build Coastguard Worker         }
730*8975f5c5SAndroid Build Coastguard Worker         return false;
731*8975f5c5SAndroid Build Coastguard Worker     }
732*8975f5c5SAndroid Build Coastguard Worker 
empty()733*8975f5c5SAndroid Build Coastguard Worker     bool empty() const { return mData.empty(); }
size()734*8975f5c5SAndroid Build Coastguard Worker     size_t size() const { return mData.size(); }
735*8975f5c5SAndroid Build Coastguard Worker 
736*8975f5c5SAndroid Build Coastguard Worker   private:
737*8975f5c5SAndroid Build Coastguard Worker     FastVector<Pair, N> mData;
738*8975f5c5SAndroid Build Coastguard Worker };
739*8975f5c5SAndroid Build Coastguard Worker 
740*8975f5c5SAndroid Build Coastguard Worker template <class T, size_t N>
741*8975f5c5SAndroid Build Coastguard Worker class FlatUnorderedSet final
742*8975f5c5SAndroid Build Coastguard Worker {
743*8975f5c5SAndroid Build Coastguard Worker   public:
744*8975f5c5SAndroid Build Coastguard Worker     using Storage        = FastVector<T, N>;
745*8975f5c5SAndroid Build Coastguard Worker     using iterator       = typename Storage::iterator;
746*8975f5c5SAndroid Build Coastguard Worker     using const_iterator = typename Storage::const_iterator;
747*8975f5c5SAndroid Build Coastguard Worker 
748*8975f5c5SAndroid Build Coastguard Worker     FlatUnorderedSet()  = default;
749*8975f5c5SAndroid Build Coastguard Worker     ~FlatUnorderedSet() = default;
750*8975f5c5SAndroid Build Coastguard Worker 
begin()751*8975f5c5SAndroid Build Coastguard Worker     iterator begin() { return mData.begin(); }
begin()752*8975f5c5SAndroid Build Coastguard Worker     const_iterator begin() const { return mData.begin(); }
end()753*8975f5c5SAndroid Build Coastguard Worker     iterator end() { return mData.end(); }
end()754*8975f5c5SAndroid Build Coastguard Worker     const_iterator end() const { return mData.end(); }
755*8975f5c5SAndroid Build Coastguard Worker 
find(const T & value)756*8975f5c5SAndroid Build Coastguard Worker     iterator find(const T &value)
757*8975f5c5SAndroid Build Coastguard Worker     {
758*8975f5c5SAndroid Build Coastguard Worker         for (auto it = mData.begin(); it != mData.end(); ++it)
759*8975f5c5SAndroid Build Coastguard Worker         {
760*8975f5c5SAndroid Build Coastguard Worker             if (*it == value)
761*8975f5c5SAndroid Build Coastguard Worker             {
762*8975f5c5SAndroid Build Coastguard Worker                 return it;
763*8975f5c5SAndroid Build Coastguard Worker             }
764*8975f5c5SAndroid Build Coastguard Worker         }
765*8975f5c5SAndroid Build Coastguard Worker         return mData.end();
766*8975f5c5SAndroid Build Coastguard Worker     }
767*8975f5c5SAndroid Build Coastguard Worker 
find(const T & value)768*8975f5c5SAndroid Build Coastguard Worker     const_iterator find(const T &value) const
769*8975f5c5SAndroid Build Coastguard Worker     {
770*8975f5c5SAndroid Build Coastguard Worker         for (auto it = mData.begin(); it != mData.end(); ++it)
771*8975f5c5SAndroid Build Coastguard Worker         {
772*8975f5c5SAndroid Build Coastguard Worker             if (*it == value)
773*8975f5c5SAndroid Build Coastguard Worker             {
774*8975f5c5SAndroid Build Coastguard Worker                 return it;
775*8975f5c5SAndroid Build Coastguard Worker             }
776*8975f5c5SAndroid Build Coastguard Worker         }
777*8975f5c5SAndroid Build Coastguard Worker         return mData.end();
778*8975f5c5SAndroid Build Coastguard Worker     }
779*8975f5c5SAndroid Build Coastguard Worker 
empty()780*8975f5c5SAndroid Build Coastguard Worker     bool empty() const { return mData.empty(); }
781*8975f5c5SAndroid Build Coastguard Worker 
insert(const T & value)782*8975f5c5SAndroid Build Coastguard Worker     void insert(const T &value)
783*8975f5c5SAndroid Build Coastguard Worker     {
784*8975f5c5SAndroid Build Coastguard Worker         ASSERT(!contains(value));
785*8975f5c5SAndroid Build Coastguard Worker         mData.push_back(value);
786*8975f5c5SAndroid Build Coastguard Worker     }
787*8975f5c5SAndroid Build Coastguard Worker 
erase(const T & value)788*8975f5c5SAndroid Build Coastguard Worker     void erase(const T &value)
789*8975f5c5SAndroid Build Coastguard Worker     {
790*8975f5c5SAndroid Build Coastguard Worker         ASSERT(contains(value));
791*8975f5c5SAndroid Build Coastguard Worker         mData.remove_and_permute(value);
792*8975f5c5SAndroid Build Coastguard Worker     }
793*8975f5c5SAndroid Build Coastguard Worker 
remove(const T & value)794*8975f5c5SAndroid Build Coastguard Worker     void remove(const T &value) { erase(value); }
795*8975f5c5SAndroid Build Coastguard Worker 
contains(const T & value)796*8975f5c5SAndroid Build Coastguard Worker     bool contains(const T &value) const { return find(value) != end(); }
797*8975f5c5SAndroid Build Coastguard Worker 
clear()798*8975f5c5SAndroid Build Coastguard Worker     void clear() { mData.clear(); }
799*8975f5c5SAndroid Build Coastguard Worker 
800*8975f5c5SAndroid Build Coastguard Worker     bool operator==(const FlatUnorderedSet<T, N> &other) const { return mData == other.mData; }
801*8975f5c5SAndroid Build Coastguard Worker 
802*8975f5c5SAndroid Build Coastguard Worker   private:
803*8975f5c5SAndroid Build Coastguard Worker     Storage mData;
804*8975f5c5SAndroid Build Coastguard Worker };
805*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
806*8975f5c5SAndroid Build Coastguard Worker 
807*8975f5c5SAndroid Build Coastguard Worker #endif  // COMMON_FASTVECTOR_H_
808