Line data Source code
1 : /**
2 : Copyright (c) 2019-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_SPMEMORY_H_
25 : #define STAPPLER_CORE_SPMEMORY_H_
26 :
27 : #include "SPMemInterface.h"
28 : #include "SPSpanView.h"
29 : #include "SPString.h"
30 : #include "SPStringView.h"
31 : #include "SPTime.h"
32 :
33 : #ifdef MODULE_STAPPLER_DATA
34 : #include "SPData.h"
35 : #endif
36 :
37 : namespace STAPPLER_VERSIONIZED stappler {
38 :
39 : template <typename T>
40 : class VectorAdapter {
41 : public:
42 141662 : size_t size() const { return size_fn(target); }
43 9176743 : T & back() const { return back_fn(target); }
44 : T & front() const { return front_fn(target); }
45 9177134 : bool empty() const { return empty_fn(target); }
46 286381 : T & at(size_t pos) const { return at_fn(target, pos); }
47 43460265 : T & emplace_back(T &&v) const { return emplace_back_fn(target, move(v)); }
48 :
49 383 : T *begin() const { return begin_fn(target); }
50 383 : T *end() const { return end_fn(target); }
51 :
52 1083762 : void clear() const { clear_fn(target); }
53 1084012 : void reserve(size_t count) const { reserve_fn(target, count); }
54 0 : void resize(size_t count) const { resize_fn(target, count); }
55 :
56 325 : explicit operator bool () const { return target != nullptr; }
57 :
58 53617 : VectorAdapter() = default;
59 :
60 : VectorAdapter(memory::StandartInterface::VectorType<T> &vec);
61 : VectorAdapter(memory::PoolInterface::VectorType<T> &vec);
62 :
63 : public:
64 : void *target = nullptr;
65 : size_t (*size_fn) (void *) = nullptr;
66 : T & (*back_fn) (void *) = nullptr;
67 : T & (*front_fn) (void *) = nullptr;
68 : bool (*empty_fn) (void *) = nullptr;
69 : T & (*at_fn) (void *, size_t) = nullptr;
70 : T & (*emplace_back_fn) (void *, T&&) = nullptr;
71 : T * (*begin_fn) (void *) = nullptr;
72 : T * (*end_fn) (void *) = nullptr;
73 : void (*clear_fn) (void *) = nullptr;
74 : void (*reserve_fn) (void *, size_t) = nullptr;
75 : void (*resize_fn) (void *, size_t) = nullptr;
76 : };
77 :
78 : }
79 :
80 : namespace STAPPLER_VERSIONIZED stappler::mem_pool {
81 :
82 : namespace pool = memory::pool;
83 : namespace allocator = memory::allocator;
84 :
85 : using CharGroupId = stappler::CharGroupId;
86 :
87 : using memory::allocator_t;
88 : using memory::pool_t;
89 :
90 : using stappler::Time;
91 : using stappler::TimeInterval;
92 :
93 : using stappler::StringView;
94 : using stappler::StringViewUtf8;
95 : using stappler::WideStringView;
96 : using stappler::BytesView;
97 : using stappler::SpanView;
98 :
99 : using AllocBase = stappler::memory::AllocPool;
100 :
101 : using String = stappler::memory::string;
102 : using WideString = stappler::memory::u16string;
103 : using Bytes = stappler::memory::vector<uint8_t>;
104 :
105 : using StringStream = stappler::memory::ostringstream;
106 : using OutputStream = std::ostream;
107 :
108 : template <typename T>
109 : using Vector = stappler::memory::vector<T>;
110 :
111 : template <typename K, typename V, typename Compare = std::less<void>>
112 : using Map = stappler::memory::map<K, V, Compare>;
113 :
114 : template <typename T, typename Compare = std::less<void>>
115 : using Set = stappler::memory::set<T, Compare>;
116 :
117 : template <typename T>
118 : using Function = stappler::memory::function<T>;
119 :
120 : using stappler::Callback;
121 :
122 : using stappler::Pair;
123 :
124 : template <typename T, typename V, typename Compare = std::less<void>>
125 : using dict = stappler::memory::dict<T, V, Compare>;
126 :
127 : using Mutex = std::mutex;
128 :
129 : using stappler::makeSpanView;
130 :
131 : template <typename Callback>
132 27006 : inline auto perform(const Callback &cb, memory::pool_t *p) {
133 : struct Context {
134 27006 : Context(memory::pool_t *pool) : _pool(pool) {
135 27006 : memory::pool::push(_pool);
136 27006 : }
137 27006 : ~Context() {
138 27006 : memory::pool::pop();
139 27006 : }
140 :
141 : memory::pool_t *_pool = nullptr;
142 27006 : } holder(p);
143 54012 : return cb();
144 27006 : }
145 :
146 : template <typename Callback>
147 19849 : inline auto perform(const Callback &cb, memory::pool_t *p, uint32_t tag, void *ptr) {
148 : struct Context {
149 19849 : Context(memory::pool_t *pool, uint32_t t, void *p) : _pool(pool) {
150 19849 : memory::pool::push(_pool, t, p);
151 19849 : }
152 19849 : ~Context() {
153 19849 : memory::pool::pop();
154 19849 : }
155 :
156 : memory::pool_t *_pool = nullptr;
157 19849 : } holder(p, tag, ptr);
158 39698 : return cb();
159 19849 : }
160 :
161 : template <typename Callback>
162 105 : inline auto perform_temporary(const Callback &cb, memory::pool_t *p = nullptr) {
163 : struct Context {
164 105 : Context(memory::pool_t *pool)
165 105 : : _pool(pool ? memory::pool::create(pool) : memory::pool::create(memory::pool::acquire())) {
166 105 : memory::pool::push(_pool);
167 105 : }
168 105 : ~Context() {
169 105 : memory::pool::pop();
170 105 : memory::pool::destroy(_pool);
171 105 : }
172 :
173 : memory::pool_t *_pool = nullptr;
174 105 : } holder(p);
175 210 : return cb();
176 105 : }
177 :
178 : template <typename T>
179 13225 : inline bool emplace_ordered(Vector<T> &vec, T val) {
180 13225 : auto lb = std::lower_bound(vec.begin(), vec.end(), val);
181 13225 : if (lb == vec.end()) {
182 12624 : vec.emplace_back(val);
183 12624 : return true;
184 601 : } else if (*lb != val) {
185 526 : vec.emplace(lb, val);
186 526 : return true;
187 : }
188 75 : return false;
189 : }
190 :
191 : template <typename T>
192 : inline bool exists_ordered(Vector<T> &vec, const T & val) {
193 : auto lb = std::lower_bound(vec.begin(), vec.end(), val);
194 : if (lb == vec.end() || *lb != val) {
195 : return false;
196 : }
197 : return true;
198 : }
199 :
200 : }
201 :
202 :
203 : namespace STAPPLER_VERSIONIZED stappler::mem_std {
204 :
205 : namespace pool = memory::pool;
206 : namespace allocator = memory::allocator;
207 :
208 : using memory::allocator_t;
209 : using memory::pool_t;
210 :
211 : using stappler::Time;
212 : using stappler::TimeInterval;
213 :
214 : using stappler::StringView;
215 : using stappler::StringViewUtf8;
216 : using stappler::WideStringView;
217 : using stappler::BytesView;
218 : using stappler::SpanView;
219 :
220 : using AllocBase = stappler::memory::AllocBase;
221 :
222 : using String = std::string;
223 : using WideString = std::u16string;
224 : using Bytes = std::vector<uint8_t>;
225 :
226 : using StringStream = std::stringstream;
227 : using OutputStream = std::ostream;
228 :
229 : template <typename T>
230 : using Vector = std::vector<T>;
231 :
232 : template <typename K, typename V, typename Compare = std::less<void>>
233 : using Map = std::map<K, V, Compare>;
234 :
235 : template <typename T, typename Compare = std::less<void>>
236 : using Set = std::set<T, Compare>;
237 :
238 : template <typename T, typename V>
239 : using HashMap = std::unordered_map<T, V, std::hash<T>, std::equal_to<T>>;
240 :
241 : template <typename T>
242 : using HashSet = std::unordered_set<T, std::hash<T>, std::equal_to<T>, std::allocator<T>>;
243 :
244 : template <typename T>
245 : using Function = std::function<T>;
246 :
247 : using stappler::Callback;
248 :
249 : using stappler::Pair;
250 :
251 : using Mutex = std::mutex;
252 :
253 : using stappler::makeSpanView;
254 :
255 : template <typename Callback>
256 1952 : inline auto perform(const Callback &cb, memory::pool_t *p) {
257 : struct Context {
258 1952 : Context(memory::pool_t *pool) : _pool(pool) {
259 1952 : memory::pool::push(_pool);
260 1952 : }
261 1952 : ~Context() {
262 1952 : memory::pool::pop();
263 1952 : }
264 :
265 : memory::pool_t *_pool = nullptr;
266 1952 : } holder(p);
267 3904 : return cb();
268 1952 : }
269 :
270 : template <typename Callback>
271 : inline auto perform_temporary(const Callback &cb, memory::pool_t *p = nullptr) {
272 : struct Context {
273 : Context(memory::pool_t *pool)
274 : : _pool(pool ? memory::pool::create(pool) : memory::pool::create(memory::pool::acquire())) {
275 : memory::pool::push(_pool);
276 : }
277 : ~Context() {
278 : memory::pool::pop();
279 : memory::pool::destroy(_pool);
280 : }
281 :
282 : memory::pool_t *_pool = nullptr;
283 : } holder(p);
284 : return cb();
285 : }
286 :
287 : template <typename T>
288 1709180 : inline bool emplace_ordered(Vector<T> &vec, T val) {
289 1709180 : auto lb = std::lower_bound(vec.begin(), vec.end(), val);
290 1709180 : if (lb == vec.end()) {
291 241683 : vec.emplace_back(val);
292 241683 : return true;
293 1467497 : } else if (*lb != val) {
294 352171 : vec.emplace(lb, val);
295 352171 : return true;
296 : }
297 1115326 : return false;
298 : }
299 :
300 : template <typename T>
301 : inline bool exists_ordered(Vector<T> &vec, const T & val) {
302 : auto lb = std::lower_bound(vec.begin(), vec.end(), val);
303 : if (lb == vec.end() || *lb != val) {
304 : return false;
305 : }
306 : return true;
307 : }
308 :
309 : }
310 :
311 :
312 : #ifdef MODULE_STAPPLER_DATA
313 :
314 : namespace STAPPLER_VERSIONIZED stappler::mem_pool {
315 :
316 : using Value = stappler::data::ValueTemplate<stappler::memory::PoolInterface>;
317 : using Array = Value::ArrayType;
318 : using Dictionary = Value::DictionaryType;
319 : using EncodeFormat = stappler::data::EncodeFormat;
320 :
321 : inline bool emplace_ordered(Vector<Value> &vec, const Value &val) {
322 : auto lb = std::lower_bound(vec.begin(), vec.end(), val, [&] (const Value &l, const Value &r) {
323 : return l.getInteger() < r.getInteger();
324 : });
325 : if (lb == vec.end()) {
326 : vec.emplace_back(val);
327 : return true;
328 : } else if (*lb != val) {
329 : vec.emplace(lb, val);
330 : return true;
331 : }
332 : return false;
333 : }
334 :
335 : }
336 :
337 :
338 : namespace STAPPLER_VERSIONIZED stappler::mem_std {
339 :
340 : using Value = data::ValueTemplate<stappler::memory::StandartInterface>;
341 : using Array = Value::ArrayType;
342 : using Dictionary = Value::DictionaryType;
343 : using EncodeFormat = stappler::data::EncodeFormat;
344 :
345 : inline bool emplace_ordered(Vector<Value> &vec, const Value &val) {
346 : auto lb = std::lower_bound(vec.begin(), vec.end(), val, [&] (const Value &l, const Value &r) {
347 : return l.getInteger() < r.getInteger();
348 : });
349 : if (lb == vec.end()) {
350 : vec.emplace_back(val);
351 : return true;
352 : } else if (*lb != val) {
353 : vec.emplace(lb, val);
354 : return true;
355 : }
356 : return false;
357 : }
358 :
359 : }
360 :
361 : namespace STAPPLER_VERSIONIZED stappler {
362 :
363 : template <typename T>
364 1148123 : VectorAdapter<T>::VectorAdapter(memory::StandartInterface::VectorType<T> &vec)
365 1289735 : : target(&vec), size_fn([] (void *target) {
366 141612 : return ((mem_std::Vector<T> *)target)->size();
367 10323866 : }), back_fn([] (void *target) -> T & {
368 9175743 : return ((mem_std::Vector<T> *)target)->back();
369 1148123 : }), front_fn([] (void *target) -> T & {
370 0 : return ((mem_std::Vector<T> *)target)->front();
371 10324257 : }), empty_fn([] (void *target) {
372 9176134 : return ((mem_std::Vector<T> *)target)->empty();
373 1434504 : }), at_fn([] (void *target, size_t pos) -> T & {
374 286381 : return ((mem_std::Vector<T> *)target)->at(pos);
375 44597263 : }), emplace_back_fn([] (void *target, T &&v) -> T & {
376 43449140 : return ((mem_std::Vector<T> *)target)->emplace_back(move(v));
377 1148506 : }), begin_fn([] (void *target) -> T * {
378 383 : return &*((mem_std::Vector<T> *)target)->begin();
379 1148506 : }), end_fn([] (void *target) -> T * {
380 383 : return &*((mem_std::Vector<T> *)target)->end();
381 3315447 : }), clear_fn([] (void *target) {
382 1083662 : ((mem_std::Vector<T> *)target)->clear();
383 3313247 : }), reserve_fn([] (void *target, size_t s) {
384 1082562 : ((mem_std::Vector<T> *)target)->reserve(s);
385 1148123 : }), resize_fn([] (void *target, size_t s) {
386 0 : ((mem_std::Vector<T> *)target)->resize(s);
387 1148123 : }) { }
388 :
389 : template <typename T>
390 1800 : VectorAdapter<T>::VectorAdapter(memory::PoolInterface::VectorType<T> &vec)
391 1850 : : target(&vec), size_fn([] (void *target) {
392 50 : return ((mem_pool::Vector<T> *)target)->size();
393 2800 : }), back_fn([] (void *target) -> T & {
394 1000 : return ((mem_pool::Vector<T> *)target)->back();
395 1800 : }), front_fn([] (void *target) -> T & {
396 0 : return ((mem_pool::Vector<T> *)target)->front();
397 2800 : }), empty_fn([] (void *target) {
398 1000 : return ((mem_pool::Vector<T> *)target)->empty();
399 1800 : }), at_fn([] (void *target, size_t pos) -> T & {
400 0 : return ((mem_pool::Vector<T> *)target)->at(pos);
401 12925 : }), emplace_back_fn([] (void *target, T &&v) -> T & {
402 11125 : return ((mem_pool::Vector<T> *)target)->emplace_back(move(v));
403 1800 : }), begin_fn([] (void *target) -> T * {
404 0 : return &*((mem_pool::Vector<T> *)target)->begin();
405 1800 : }), end_fn([] (void *target) -> T * {
406 0 : return &*((mem_pool::Vector<T> *)target)->end();
407 2000 : }), clear_fn([] (void *target) {
408 100 : ((mem_pool::Vector<T> *)target)->clear();
409 4700 : }), reserve_fn([] (void *target, size_t s) {
410 1450 : ((mem_pool::Vector<T> *)target)->reserve(s);
411 1800 : }), resize_fn([] (void *target, size_t s) {
412 0 : ((mem_pool::Vector<T> *)target)->resize(s);
413 1800 : }) { }
414 :
415 : }
416 :
417 : #endif
418 :
419 : #endif /* STAPPLER_CORE_SPMEMORY_H_ */
|