Line data Source code
1 : /**
2 : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef STAPPLER_CORE_MEMORY_SPMEMVECTOR_H_
25 : #define STAPPLER_CORE_MEMORY_SPMEMVECTOR_H_
26 :
27 : #include "SPMemStorageMem.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::memory {
30 :
31 : template <typename Type>
32 : class vector : public AllocPool {
33 : public:
34 : using allocator_type = Allocator<Type>;
35 :
36 : using pointer = Type *;
37 : using const_pointer = const Type *;
38 : using reference = Type &;
39 : using const_reference = const Type &;
40 :
41 : using size_type = size_t;
42 : using value_type = Type;
43 : using mem_type = storage_mem<Type, 0>;
44 : using self = vector<Type>;
45 :
46 : using iterator = typename mem_type::iterator;
47 : using const_iterator = typename mem_type::const_iterator;
48 : using reverse_iterator = typename mem_type::reverse_iterator;
49 : using const_reverse_iterator = typename mem_type::const_reverse_iterator;
50 :
51 : public:
52 2558628 : vector() noexcept {}
53 130103 : explicit vector( const allocator_type& alloc ) noexcept : _mem(alloc) { }
54 : explicit vector( size_type count, const Type& value, const allocator_type& alloc = allocator_type()) noexcept : _mem(alloc) {
55 : _mem.fill(count, value);
56 : }
57 : explicit vector( size_type count, const allocator_type& alloc = allocator_type() ) noexcept : _mem(alloc) {
58 : _mem.fill(count);
59 : }
60 :
61 : template< class InputIt >
62 10302 : vector( InputIt first, InputIt last, const allocator_type& alloc = allocator_type() ) : _mem(alloc) {
63 10302 : auto size = std::distance(first, last);
64 10302 : _mem.reserve(size);
65 193401 : for (auto it = first; it != last; it ++) {
66 183099 : _mem.emplace_back_unsafe(*it);
67 : }
68 10302 : }
69 :
70 400855 : vector( const vector& other ) noexcept : _mem(other._mem) { }
71 : vector( const vector& other, const allocator_type& alloc ) noexcept : _mem(other._mem, alloc) { }
72 174563 : vector( vector&& other ) noexcept : _mem(std::move(other._mem)) { }
73 : vector( vector&& other, const allocator_type& alloc ) noexcept : _mem(std::move(other._mem), alloc) { }
74 25760 : vector( InitializerList<Type> init, const allocator_type& alloc = allocator_type() ) noexcept : _mem(alloc) {
75 25760 : _mem.reserve(init.size());
76 54945 : for (auto & it : init) {
77 29185 : _mem.emplace_back_unsafe(it);
78 : }
79 25760 : }
80 :
81 192 : vector& operator=( const vector& other ) noexcept {
82 192 : _mem = other._mem;
83 192 : return *this;
84 : }
85 30807 : vector& operator=( vector&& other ) noexcept {
86 30807 : _mem = std::move(other._mem);
87 30807 : return *this;
88 : }
89 0 : vector& operator=( InitializerList<Type> init ) noexcept {
90 0 : _mem.clear();
91 0 : _mem.reserve(init.size());
92 0 : for (auto & it : init) {
93 0 : _mem.emplace_back_unsafe(it);
94 : }
95 0 : return *this;
96 : }
97 :
98 : void assign( size_type count, const Type& value ) {
99 : _mem.fill(count, value);
100 : }
101 :
102 : template< class InputIt >
103 2050 : void assign( InputIt first, InputIt last ) { // @TODO: self-assign protection and modern assignment
104 2050 : _mem.clear();
105 2050 : auto size = std::distance(first, last);
106 2050 : _mem.reserve(size);
107 498997200 : for (auto it = first; it != last; it ++) {
108 498995150 : _mem.emplace_back_unsafe(*it);
109 : }
110 2050 : }
111 :
112 : void assign( InitializerList<Type> init ) {
113 : _mem.clear();
114 : _mem.reserve(init.size());
115 : for (auto & it : init) {
116 : _mem.emplace_back_unsafe(it);
117 : }
118 : }
119 :
120 9150 : void assign_strong(Type *t, size_type s) {
121 9150 : _mem.assign(t, s);
122 9150 : }
123 :
124 4816 : allocator_type get_allocator() const noexcept { return _mem.get_allocator(); }
125 :
126 33675 : reference at( size_type pos ) noexcept { return _mem.at(pos); }
127 154256 : const_reference at( size_type pos ) const noexcept { return _mem.at(pos); }
128 :
129 221067427 : reference operator[]( size_type pos ) noexcept { return _mem.at(pos); }
130 627334 : const_reference operator[]( size_type pos ) const noexcept { return _mem.at(pos); }
131 :
132 10921 : reference front() noexcept { return _mem.front(); }
133 700989 : const_reference front() const noexcept { return _mem.front(); }
134 :
135 3336705 : reference back() noexcept { return _mem.back(); }
136 1061711 : const_reference back() const noexcept { return _mem.back(); }
137 :
138 11031986 : pointer data() noexcept { return _mem.data(); }
139 2394348 : const_pointer data() const noexcept { return _mem.data(); }
140 :
141 51061092 : iterator begin() noexcept { return _mem.begin(); }
142 55358439 : iterator end() noexcept { return _mem.end(); }
143 :
144 4567371 : const_iterator begin() const noexcept { return _mem.begin(); }
145 4838322 : const_iterator end() const noexcept { return _mem.end(); }
146 :
147 : const_iterator cbegin() const noexcept { return _mem.cbegin(); }
148 : const_iterator cend() const noexcept { return _mem.cend(); }
149 :
150 221862 : reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
151 260348 : reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
152 :
153 : const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
154 : const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
155 :
156 : const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
157 : const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
158 :
159 54597229 : size_type size() const noexcept { return _mem.size(); }
160 : size_type capacity() const noexcept { return _mem.capacity(); }
161 7978351 : bool empty() const noexcept { return _mem.empty(); }
162 625 : void reserve_block_optimal() { _mem.reserve_block_optimal(); }
163 1167684 : void reserve( size_type new_cap ) { _mem.reserve(new_cap); }
164 212400 : void shrink_to_fit() { }
165 :
166 986655 : void clear() { _mem.clear(); }
167 :
168 : template< class... Args >
169 118251 : iterator emplace( const_iterator pos, Args&&... args ) {
170 118251 : return _mem.emplace(pos, std::forward<Args>(args)...);
171 : }
172 :
173 : iterator insert( const_iterator pos, const Type& value ) {
174 : return emplace(pos, value);
175 : }
176 : iterator insert( const_iterator pos, Type&& value ) {
177 : return emplace(pos, std::move(value));
178 : }
179 : iterator insert( const_iterator pos, size_type count, const Type& value ) {
180 : return _mem.insert(pos, count, value);
181 : }
182 :
183 : template< class InputIt >
184 0 : iterator insert( const_iterator pos, InputIt first, InputIt last ) {
185 0 : return _mem.insert(pos, first, last);
186 : }
187 :
188 : iterator insert( const_iterator pos, InitializerList<Type> init ) {
189 : return _mem.insert(pos, init.begin(), init.end());
190 : }
191 :
192 34071 : iterator erase( const_iterator pos ) {
193 34071 : return _mem.erase(pos);
194 : }
195 :
196 : iterator erase( const_iterator first, const_iterator last ) {
197 : return _mem.erase(first, last);
198 : }
199 :
200 : template< class... Args >
201 44585270 : reference emplace_back( Args&&... args ) {
202 44585270 : return _mem.emplace_back(std::forward<Args>(args)...);
203 : }
204 :
205 2450424 : void push_back( const Type& value ) {
206 2450424 : emplace_back(value);
207 2450425 : }
208 74513 : void push_back( Type&& value ) {
209 74513 : emplace_back(std::move(value));
210 74513 : }
211 :
212 3717210 : void pop_back() {
213 3717210 : _mem.pop_back();
214 3717209 : }
215 :
216 7775680 : void resize( size_type count ) {
217 7775680 : _mem.resize(count);
218 7775679 : }
219 3621 : void resize( size_type count, const value_type& value ) {
220 3621 : _mem.resize(count, value);
221 3621 : }
222 :
223 : public:
224 : static const vector make_weak(const Type *str, size_type l, const allocator_type& alloc = allocator_type()) {
225 : vector ret(alloc);
226 : if (str) {
227 : ret.assign_weak(str, l);
228 : }
229 : return ret;
230 : }
231 :
232 : vector& assign_weak(const Type *str, size_type l) {
233 : _mem.assign_weak(str, l);
234 : return *this;
235 : }
236 :
237 : bool is_weak() const noexcept {
238 : return _mem.is_weak();
239 : }
240 :
241 1350 : void force_clear() {
242 1350 : _mem.force_clear();
243 1350 : }
244 :
245 : protected:
246 : mem_type _mem;
247 : };
248 :
249 : using bytes = vector<uint8_t>;
250 :
251 : template<typename _Tp> inline bool
252 0 : operator==(const vector<_Tp>& __x, const vector<_Tp>& __y) {
253 0 : return (__x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()));
254 : }
255 :
256 : template<typename _Tp> inline bool
257 : operator<(const vector<_Tp>& __x, const vector<_Tp>& __y) {
258 : return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
259 : }
260 :
261 : template<> inline bool
262 : operator<(const vector<uint8_t>& x, const vector<uint8_t>& y) {
263 : auto len1 = x.size();
264 : auto len2 = y.size();
265 : int result = memcmp(x.data(), y.data(), min(len1, len2));
266 : if (result != 0)
267 : return result < 0;
268 : if (len1 < len2)
269 : return true;
270 : if (len1 > len2)
271 : return false;
272 : return false;
273 : }
274 :
275 : /// Based on operator==
276 : template<typename _Tp> inline bool
277 : operator!=(const vector<_Tp>& __x, const vector<_Tp>& __y) {
278 : return !(__x == __y);
279 : }
280 :
281 : /// Based on operator<
282 : template<typename _Tp> inline bool
283 : operator>(const vector<_Tp>& __x, const vector<_Tp>& __y) {
284 : return __y < __x;
285 : }
286 :
287 : /// Based on operator<
288 : template<typename _Tp> inline bool
289 : operator<=(const vector<_Tp>& __x, const vector<_Tp>& __y) {
290 : return !(__y < __x);
291 : }
292 :
293 : /// Based on operator<
294 : template<typename _Tp> inline bool
295 : operator>=(const vector<_Tp>& __x, const vector<_Tp>& __y) {
296 : return !(__x < __y);
297 : }
298 :
299 : }
300 :
301 : #endif /* STAPPLER_CORE_MEMORY_SPMEMVECTOR_H_ */
|