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