Line data Source code
1 : #ifdef __PLUMED_HAS_ASMJIT
2 : // This file is part of AsmJit project <https://asmjit.com>
3 : //
4 : // See asmjit.h or LICENSE.md for license and copyright information
5 : // SPDX-License-Identifier: Zlib
6 :
7 : #ifndef ASMJIT_CORE_ZONEVECTOR_H_INCLUDED
8 : #define ASMJIT_CORE_ZONEVECTOR_H_INCLUDED
9 :
10 : #include "support.h"
11 : #include "zone.h"
12 :
13 : ASMJIT_BEGIN_NAMESPACE
14 :
15 : //! \addtogroup asmjit_zone
16 : //! \{
17 :
18 : //! Base class used by \ref ZoneVector template.
19 : class ZoneVectorBase {
20 : public:
21 : ASMJIT_NONCOPYABLE(ZoneVectorBase)
22 :
23 : // STL compatibility;
24 : typedef uint32_t size_type;
25 : typedef ptrdiff_t difference_type;
26 :
27 : //! Vector data (untyped).
28 : void* _data = nullptr;
29 : //! Size of the vector.
30 : size_type _size = 0;
31 : //! Capacity of the vector.
32 : size_type _capacity = 0;
33 :
34 : protected:
35 : //! \name Construction & Destruction
36 : //! \{
37 :
38 : //! Creates a new instance of `ZoneVectorBase`.
39 1896948 : inline ZoneVectorBase() noexcept {}
40 :
41 : inline ZoneVectorBase(ZoneVectorBase&& other) noexcept
42 : : _data(other._data),
43 : _size(other._size),
44 : _capacity(other._capacity) {}
45 :
46 : //! \}
47 :
48 : //! \cond INTERNAL
49 : //! \name Internal
50 : //! \{
51 :
52 82476 : inline void _release(ZoneAllocator* allocator, uint32_t sizeOfT) noexcept {
53 82476 : if (_data != nullptr) {
54 82476 : allocator->release(_data, _capacity * sizeOfT);
55 : reset();
56 : }
57 82476 : }
58 :
59 : ASMJIT_API Error _grow(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept;
60 : ASMJIT_API Error _resize(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept;
61 : ASMJIT_API Error _reserve(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept;
62 :
63 : inline void _swap(ZoneVectorBase& other) noexcept {
64 : std::swap(_data, other._data);
65 : std::swap(_size, other._size);
66 : std::swap(_capacity, other._capacity);
67 : }
68 :
69 : //! \}
70 : //! \endcond
71 :
72 : public:
73 : //! \name Accessors
74 : //! \{
75 :
76 : //! Tests whether the vector is empty.
77 339822 : inline bool empty() const noexcept { return _size == 0; }
78 : //! Returns the vector size.
79 4071223 : inline size_type size() const noexcept { return _size; }
80 : //! Returns the vector capacity.
81 : inline size_type capacity() const noexcept { return _capacity; }
82 :
83 : //! \}
84 :
85 : //! \name Utilities
86 : //! \{
87 :
88 : //! Makes the vector empty (won't change the capacity or data pointer).
89 : inline void clear() noexcept { _size = 0; }
90 : //! Resets the vector data and set its `size` to zero.
91 : inline void reset() noexcept {
92 522348 : _data = nullptr;
93 522348 : _size = 0;
94 412380 : _capacity = 0;
95 82476 : }
96 :
97 : //! Truncates the vector to at most `n` items.
98 : inline void truncate(size_type n) noexcept {
99 : _size = Support::min(_size, n);
100 : }
101 :
102 : //! Sets size of the vector to `n`. Used internally by some algorithms.
103 : inline void _setSize(size_type n) noexcept {
104 : ASMJIT_ASSERT(n <= _capacity);
105 106711 : _size = n;
106 : }
107 :
108 : //! \}
109 : };
110 :
111 : //! Template used to store and manage array of Zone allocated data.
112 : //!
113 : //! This template has these advantages over other std::vector<>:
114 : //! - Always non-copyable (designed to be non-copyable, we want it).
115 : //! - Optimized for working only with POD types.
116 : //! - Uses ZoneAllocator, thus small vectors are almost for free.
117 : //! - Explicit allocation, ZoneAllocator is not part of the data.
118 : template <typename T>
119 : class ZoneVector : public ZoneVectorBase {
120 : public:
121 : ASMJIT_NONCOPYABLE(ZoneVector)
122 :
123 : // STL compatibility;
124 : typedef T value_type;
125 : typedef T* pointer;
126 : typedef const T* const_pointer;
127 : typedef T& reference;
128 : typedef const T& const_reference;
129 :
130 : typedef T* iterator;
131 : typedef const T* const_iterator;
132 : typedef std::reverse_iterator<iterator> reverse_iterator;
133 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
134 :
135 : //! \name Construction & Destruction
136 : //! \{
137 :
138 27492 : inline ZoneVector() noexcept : ZoneVectorBase() {}
139 : inline ZoneVector(ZoneVector&& other) noexcept : ZoneVector(other) {}
140 :
141 : //! \}
142 :
143 : //! \name Accessors
144 : //! \{
145 :
146 : //! Returns vector data.
147 604824 : inline T* data() noexcept { return static_cast<T*>(_data); }
148 : //! Returns vector data (const)
149 764737 : inline const T* data() const noexcept { return static_cast<const T*>(_data); }
150 :
151 : //! Returns item at the given index `i` (const).
152 : inline const T& at(size_t i) const noexcept {
153 : ASMJIT_ASSERT(i < _size);
154 : return data()[i];
155 : }
156 :
157 : inline void _setEndPtr(T* p) noexcept {
158 : ASMJIT_ASSERT(p >= data() && p <= data() + _capacity);
159 260869 : _setSize(uint32_t((uintptr_t)(p - data())));
160 : }
161 :
162 : //! \}
163 :
164 : //! \name STL Compatibility (Iterators)
165 : //! \{
166 :
167 : inline iterator begin() noexcept { return iterator(data()); };
168 : inline const_iterator begin() const noexcept { return const_iterator(data()); };
169 :
170 249383 : inline iterator end() noexcept { return iterator(data() + _size); };
171 353790 : inline const_iterator end() const noexcept { return const_iterator(data() + _size); };
172 :
173 : inline reverse_iterator rbegin() noexcept { return reverse_iterator(end()); };
174 : inline const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); };
175 :
176 : inline reverse_iterator rend() noexcept { return reverse_iterator(begin()); };
177 : inline const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); };
178 :
179 : inline const_iterator cbegin() const noexcept { return const_iterator(data()); };
180 : inline const_iterator cend() const noexcept { return const_iterator(data() + _size); };
181 :
182 : inline const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); };
183 : inline const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); };
184 :
185 : //! \}
186 :
187 : //! \name Utilities
188 : //! \{
189 :
190 : //! Swaps this vector with `other`.
191 : ASMJIT_FORCE_INLINE void swap(ZoneVector<T>& other) noexcept { _swap(other); }
192 :
193 : //! Prepends `item` to the vector.
194 : ASMJIT_FORCE_INLINE Error prepend(ZoneAllocator* allocator, const T& item) noexcept {
195 : if (ASMJIT_UNLIKELY(_size == _capacity))
196 : ASMJIT_PROPAGATE(grow(allocator, 1));
197 :
198 : ::memmove(static_cast<T*>(_data) + 1, _data, size_t(_size) * sizeof(T));
199 : memcpy(_data, &item, sizeof(T));
200 :
201 : _size++;
202 : return kErrorOk;
203 : }
204 :
205 : //! Inserts an `item` at the specified `index`.
206 : ASMJIT_FORCE_INLINE Error insert(ZoneAllocator* allocator, size_t index, const T& item) noexcept {
207 : ASMJIT_ASSERT(index <= _size);
208 :
209 : if (ASMJIT_UNLIKELY(_size == _capacity))
210 : ASMJIT_PROPAGATE(grow(allocator, 1));
211 :
212 : T* dst = static_cast<T*>(_data) + index;
213 : ::memmove(dst + 1, dst, size_t(_size - index) * sizeof(T));
214 : memcpy(dst, &item, sizeof(T));
215 : _size++;
216 :
217 : return kErrorOk;
218 : }
219 :
220 : //! Appends `item` to the vector.
221 : ASMJIT_FORCE_INLINE Error append(ZoneAllocator* allocator, const T& item) noexcept {
222 393142 : if (ASMJIT_UNLIKELY(_size == _capacity))
223 298821 : ASMJIT_PROPAGATE(grow(allocator, 1));
224 :
225 393142 : memcpy(static_cast<T*>(_data) + _size, &item, sizeof(T));
226 393142 : _size++;
227 :
228 393142 : return kErrorOk;
229 : }
230 :
231 : //! Appends `other` vector at the end of this vector.
232 : ASMJIT_FORCE_INLINE Error concat(ZoneAllocator* allocator, const ZoneVector<T>& other) noexcept {
233 54984 : uint32_t size = other._size;
234 54984 : if (_capacity - _size < size)
235 54984 : ASMJIT_PROPAGATE(grow(allocator, size));
236 :
237 54984 : if (size) {
238 54984 : memcpy(static_cast<T*>(_data) + _size, other._data, size_t(size) * sizeof(T));
239 54984 : _size += size;
240 : }
241 :
242 : return kErrorOk;
243 : }
244 :
245 : //! Prepends `item` to the vector (unsafe case).
246 : //!
247 : //! Can only be used together with `willGrow()`. If `willGrow(N)` returns `kErrorOk` then N elements
248 : //! can be added to the vector without checking if there is a place for them. Used mostly internally.
249 : ASMJIT_FORCE_INLINE void prependUnsafe(const T& item) noexcept {
250 : ASMJIT_ASSERT(_size < _capacity);
251 0 : T* data = static_cast<T*>(_data);
252 :
253 0 : if (_size)
254 0 : ::memmove(data + 1, data, size_t(_size) * sizeof(T));
255 :
256 : memcpy(data, &item, sizeof(T));
257 0 : _size++;
258 : }
259 :
260 : //! Append s`item` to the vector (unsafe case).
261 : //!
262 : //! Can only be used together with `willGrow()`. If `willGrow(N)` returns `kErrorOk` then N elements
263 : //! can be added to the vector without checking if there is a place for them. Used mostly internally.
264 : ASMJIT_FORCE_INLINE void appendUnsafe(const T& item) noexcept {
265 : ASMJIT_ASSERT(_size < _capacity);
266 :
267 1155031 : memcpy(static_cast<T*>(_data) + _size, &item, sizeof(T));
268 1437771 : _size++;
269 331714 : }
270 :
271 : //! Inserts an `item` at the specified `index` (unsafe case).
272 : ASMJIT_FORCE_INLINE void insertUnsafe(size_t index, const T& item) noexcept {
273 : ASMJIT_ASSERT(_size < _capacity);
274 : ASMJIT_ASSERT(index <= _size);
275 :
276 : T* dst = static_cast<T*>(_data) + index;
277 0 : ::memmove(dst + 1, dst, size_t(_size - index) * sizeof(T));
278 : memcpy(dst, &item, sizeof(T));
279 0 : _size++;
280 : }
281 : //! Concatenates all items of `other` at the end of the vector.
282 : ASMJIT_FORCE_INLINE void concatUnsafe(const ZoneVector<T>& other) noexcept {
283 : uint32_t size = other._size;
284 : ASMJIT_ASSERT(_capacity - _size >= size);
285 :
286 : if (size) {
287 : memcpy(static_cast<T*>(_data) + _size, other._data, size_t(size) * sizeof(T));
288 : _size += size;
289 : }
290 : }
291 :
292 : //! Returns index of the given `val` or `Globals::kNotFound` if it doesn't exist.
293 : ASMJIT_FORCE_INLINE uint32_t indexOf(const T& val) const noexcept {
294 82476 : const T* data = static_cast<const T*>(_data);
295 82476 : uint32_t size = _size;
296 :
297 109968 : for (uint32_t i = 0; i < size; i++)
298 82476 : if (data[i] == val)
299 : return i;
300 : return Globals::kNotFound;
301 : }
302 :
303 : //! Tests whether the vector contains `val`.
304 27492 : inline bool contains(const T& val) const noexcept {
305 27492 : return indexOf(val) != Globals::kNotFound;
306 : }
307 :
308 : //! Removes item at index `i`.
309 54984 : inline void removeAt(size_t i) noexcept {
310 : ASMJIT_ASSERT(i < _size);
311 :
312 54984 : T* data = static_cast<T*>(_data) + i;
313 54984 : size_t size = --_size - i;
314 :
315 54984 : if (size)
316 0 : ::memmove(data, data + 1, size_t(size) * sizeof(T));
317 54984 : }
318 :
319 : //! Pops the last element from the vector and returns it.
320 : inline T pop() noexcept {
321 : ASMJIT_ASSERT(_size > 0);
322 :
323 0 : uint32_t index = --_size;
324 0 : return data()[index];
325 : }
326 :
327 : template<typename CompareT = Support::Compare<Support::SortOrder::kAscending>>
328 : inline void sort(const CompareT& cmp = CompareT()) noexcept {
329 82476 : Support::qSort<T, CompareT>(data(), size(), cmp);
330 : }
331 :
332 : //! Returns item at index `i`.
333 : inline T& operator[](size_t i) noexcept {
334 : ASMJIT_ASSERT(i < _size);
335 3075147 : return data()[i];
336 : }
337 :
338 : //! Returns item at index `i`.
339 47004 : inline const T& operator[](size_t i) const noexcept {
340 : ASMJIT_ASSERT(i < _size);
341 3262133 : return data()[i];
342 : }
343 :
344 : //! Returns a reference to the first element of the vector.
345 : //!
346 : //! \note The vector must have at least one element. Attempting to use `first()` on empty vector will trigger
347 : //! an assertion failure in debug builds.
348 : inline T& first() noexcept { return operator[](0); }
349 : //! \overload
350 : inline const T& first() const noexcept { return operator[](0); }
351 :
352 : //! Returns a reference to the last element of the vector.
353 : //!
354 : //! \note The vector must have at least one element. Attempting to use `last()` on empty vector will trigger
355 : //! an assertion failure in debug builds.
356 27492 : inline T& last() noexcept { return operator[](_size - 1); }
357 : //! \overload
358 0 : inline const T& last() const noexcept { return operator[](_size - 1); }
359 :
360 : //! \}
361 :
362 : //! \name Memory Management
363 : //! \{
364 :
365 : //! Releases the memory held by `ZoneVector<T>` back to the `allocator`.
366 : inline void release(ZoneAllocator* allocator) noexcept {
367 27492 : _release(allocator, sizeof(T));
368 : }
369 :
370 : //! Called to grow the buffer to fit at least `n` elements more.
371 27492 : inline Error grow(ZoneAllocator* allocator, uint32_t n) noexcept {
372 775304 : return ZoneVectorBase::_grow(allocator, sizeof(T), n);
373 : }
374 :
375 : //! Resizes the vector to hold `n` elements.
376 : //!
377 : //! If `n` is greater than the current size then the additional elements' content will be initialized to zero.
378 : //! If `n` is less than the current size then the vector will be truncated to exactly `n` elements.
379 : inline Error resize(ZoneAllocator* allocator, uint32_t n) noexcept {
380 164952 : return ZoneVectorBase::_resize(allocator, sizeof(T), n);
381 : }
382 :
383 : //! Reallocates the internal array to fit at least `n` items.
384 54984 : inline Error reserve(ZoneAllocator* allocator, uint32_t n) noexcept {
385 1169905 : return n > _capacity ? ZoneVectorBase::_reserve(allocator, sizeof(T), n) : Error(kErrorOk);
386 : }
387 :
388 1149615 : inline Error willGrow(ZoneAllocator* allocator, uint32_t n = 1) noexcept {
389 1149615 : return _capacity - _size < n ? grow(allocator, n) : Error(kErrorOk);
390 : }
391 :
392 : //! \}
393 : };
394 :
395 : //! Zone-allocated bit vector.
396 : class ZoneBitVector {
397 : public:
398 : typedef Support::BitWord BitWord;
399 :
400 : ASMJIT_NONCOPYABLE(ZoneBitVector)
401 :
402 : //! \name Constants
403 : //! \{
404 :
405 : enum : uint32_t {
406 : kBitWordSizeInBits = Support::kBitWordSizeInBits
407 : };
408 :
409 : //! \}
410 :
411 : //! \name Members
412 : //! \{
413 :
414 : //! Bits.
415 : BitWord* _data = nullptr;
416 : //! Size of the bit-vector (in bits).
417 : uint32_t _size = 0;
418 : //! Capacity of the bit-vector (in bits).
419 : uint32_t _capacity = 0;
420 :
421 : //! \}
422 :
423 : //! \cond INTERNAL
424 : //! \name Internal
425 : //! \{
426 :
427 : static inline uint32_t _wordsPerBits(uint32_t nBits) noexcept {
428 577332 : return ((nBits + kBitWordSizeInBits - 1) / kBitWordSizeInBits);
429 : }
430 :
431 : static inline void _zeroBits(BitWord* dst, uint32_t nBitWords) noexcept {
432 : for (uint32_t i = 0; i < nBitWords; i++)
433 : dst[i] = 0;
434 : }
435 :
436 : static inline void _fillBits(BitWord* dst, uint32_t nBitWords) noexcept {
437 : for (uint32_t i = 0; i < nBitWords; i++)
438 : dst[i] = ~BitWord(0);
439 : }
440 :
441 : static inline void _copyBits(BitWord* dst, const BitWord* src, uint32_t nBitWords) noexcept {
442 274920 : for (uint32_t i = 0; i < nBitWords; i++)
443 0 : dst[i] = src[i];
444 : }
445 :
446 : //! \}
447 : //! \endcond
448 :
449 : //! \name Construction & Destruction
450 : //! \{
451 :
452 247428 : inline ZoneBitVector() noexcept {}
453 :
454 : inline ZoneBitVector(ZoneBitVector&& other) noexcept
455 : : _data(other._data),
456 : _size(other._size),
457 : _capacity(other._capacity) {}
458 :
459 : //! \}
460 :
461 : //! \name Overloaded Operators
462 : //! \{
463 :
464 : inline bool operator==(const ZoneBitVector& other) const noexcept { return eq(other); }
465 : inline bool operator!=(const ZoneBitVector& other) const noexcept { return !eq(other); }
466 :
467 : //! \}
468 :
469 : //! \name Accessors
470 : //! \{
471 :
472 : //! Tests whether the bit-vector is empty (has no bits).
473 0 : inline bool empty() const noexcept { return _size == 0; }
474 : //! Returns the size of this bit-vector (in bits).
475 0 : inline uint32_t size() const noexcept { return _size; }
476 : //! Returns the capacity of this bit-vector (in bits).
477 : inline uint32_t capacity() const noexcept { return _capacity; }
478 :
479 : //! Returns the size of the `BitWord[]` array in `BitWord` units.
480 82476 : inline uint32_t sizeInBitWords() const noexcept { return _wordsPerBits(_size); }
481 : //! Returns the capacity of the `BitWord[]` array in `BitWord` units.
482 : inline uint32_t capacityInBitWords() const noexcept { return _wordsPerBits(_capacity); }
483 :
484 : //! REturns bit-vector data as `BitWord[]`.
485 109968 : inline BitWord* data() noexcept { return _data; }
486 : //! \overload
487 82476 : inline const BitWord* data() const noexcept { return _data; }
488 :
489 : //! \}
490 :
491 : //! \name Utilities
492 : //! \{
493 :
494 : inline void swap(ZoneBitVector& other) noexcept {
495 : std::swap(_data, other._data);
496 : std::swap(_size, other._size);
497 : std::swap(_capacity, other._capacity);
498 : }
499 :
500 : inline void clear() noexcept {
501 : _size = 0;
502 : }
503 :
504 : inline void reset() noexcept {
505 54984 : _data = nullptr;
506 54984 : _size = 0;
507 54984 : _capacity = 0;
508 54984 : }
509 :
510 : inline void truncate(uint32_t newSize) noexcept {
511 : _size = Support::min(_size, newSize);
512 : _clearUnusedBits();
513 : }
514 :
515 0 : inline bool bitAt(uint32_t index) const noexcept {
516 : ASMJIT_ASSERT(index < _size);
517 913260 : return Support::bitVectorGetBit(_data, index);
518 : }
519 :
520 : inline void setBit(uint32_t index, bool value) noexcept {
521 : ASMJIT_ASSERT(index < _size);
522 696930 : Support::bitVectorSetBit(_data, index, value);
523 614454 : }
524 :
525 : inline void flipBit(uint32_t index) noexcept {
526 : ASMJIT_ASSERT(index < _size);
527 : Support::bitVectorFlipBit(_data, index);
528 : }
529 :
530 : ASMJIT_FORCE_INLINE Error append(ZoneAllocator* allocator, bool value) noexcept {
531 : uint32_t index = _size;
532 : if (ASMJIT_UNLIKELY(index >= _capacity))
533 : return _append(allocator, value);
534 :
535 : uint32_t idx = index / kBitWordSizeInBits;
536 : uint32_t bit = index % kBitWordSizeInBits;
537 :
538 : if (bit == 0)
539 : _data[idx] = BitWord(value) << bit;
540 : else
541 : _data[idx] |= BitWord(value) << bit;
542 :
543 : _size++;
544 : return kErrorOk;
545 : }
546 :
547 : ASMJIT_API Error copyFrom(ZoneAllocator* allocator, const ZoneBitVector& other) noexcept;
548 :
549 : ASMJIT_FORCE_INLINE void clearAll() noexcept {
550 : _zeroBits(_data, _wordsPerBits(_size));
551 : }
552 :
553 : ASMJIT_FORCE_INLINE void fillAll() noexcept {
554 : _fillBits(_data, _wordsPerBits(_size));
555 : _clearUnusedBits();
556 : }
557 :
558 : ASMJIT_FORCE_INLINE void clearBits(uint32_t start, uint32_t count) noexcept {
559 : ASMJIT_ASSERT(start <= _size);
560 : ASMJIT_ASSERT(_size - start >= count);
561 :
562 : Support::bitVectorClear(_data, start, count);
563 : }
564 :
565 : ASMJIT_FORCE_INLINE void fillBits(uint32_t start, uint32_t count) noexcept {
566 : ASMJIT_ASSERT(start <= _size);
567 : ASMJIT_ASSERT(_size - start >= count);
568 :
569 : Support::bitVectorFill(_data, start, count);
570 : }
571 :
572 : //! Performs a logical bitwise AND between bits specified in this array and bits in `other`. If `other` has less
573 : //! bits than `this` then all remaining bits are set to zero.
574 : //!
575 : //! \note The size of the BitVector is unaffected by this operation.
576 : ASMJIT_FORCE_INLINE void and_(const ZoneBitVector& other) noexcept {
577 : BitWord* dst = _data;
578 : const BitWord* src = other._data;
579 :
580 : uint32_t thisBitWordCount = sizeInBitWords();
581 : uint32_t otherBitWordCount = other.sizeInBitWords();
582 : uint32_t commonBitWordCount = Support::min(thisBitWordCount, otherBitWordCount);
583 :
584 : uint32_t i = 0;
585 : while (i < commonBitWordCount) {
586 : dst[i] = dst[i] & src[i];
587 : i++;
588 : }
589 :
590 : while (i < thisBitWordCount) {
591 : dst[i] = 0;
592 : i++;
593 : }
594 : }
595 :
596 : //! Performs a logical bitwise AND between bits specified in this array and negated bits in `other`. If `other`
597 : //! has less bits than `this` then all remaining bits are kept intact.
598 : //!
599 : //! \note The size of the BitVector is unaffected by this operation.
600 : ASMJIT_FORCE_INLINE void andNot(const ZoneBitVector& other) noexcept {
601 : BitWord* dst = _data;
602 : const BitWord* src = other._data;
603 :
604 : uint32_t commonBitWordCount = _wordsPerBits(Support::min(_size, other._size));
605 : for (uint32_t i = 0; i < commonBitWordCount; i++)
606 : dst[i] = dst[i] & ~src[i];
607 : }
608 :
609 : //! Performs a logical bitwise OP between bits specified in this array and bits in `other`. If `other` has less
610 : //! bits than `this` then all remaining bits are kept intact.
611 : //!
612 : //! \note The size of the BitVector is unaffected by this operation.
613 : ASMJIT_FORCE_INLINE void or_(const ZoneBitVector& other) noexcept {
614 0 : BitWord* dst = _data;
615 0 : const BitWord* src = other._data;
616 :
617 : uint32_t commonBitWordCount = _wordsPerBits(Support::min(_size, other._size));
618 0 : for (uint32_t i = 0; i < commonBitWordCount; i++)
619 0 : dst[i] = dst[i] | src[i];
620 : _clearUnusedBits();
621 : }
622 :
623 : ASMJIT_FORCE_INLINE void _clearUnusedBits() noexcept {
624 0 : uint32_t idx = _size / kBitWordSizeInBits;
625 0 : uint32_t bit = _size % kBitWordSizeInBits;
626 :
627 0 : if (!bit)
628 : return;
629 0 : _data[idx] &= (BitWord(1) << bit) - 1u;
630 : }
631 :
632 : ASMJIT_FORCE_INLINE bool eq(const ZoneBitVector& other) const noexcept {
633 : if (_size != other._size)
634 : return false;
635 :
636 : const BitWord* aData = _data;
637 : const BitWord* bData = other._data;
638 : uint32_t numBitWords = _wordsPerBits(_size);
639 :
640 : for (uint32_t i = 0; i < numBitWords; i++)
641 : if (aData[i] != bData[i])
642 : return false;
643 : return true;
644 : }
645 :
646 : //! \}
647 :
648 : //! \name Memory Management
649 : //! \{
650 :
651 27492 : inline void release(ZoneAllocator* allocator) noexcept {
652 54984 : if (!_data) return;
653 54984 : allocator->release(_data, _capacity / 8);
654 : reset();
655 : }
656 :
657 : inline Error resize(ZoneAllocator* allocator, uint32_t newSize, bool newBitsValue = false) noexcept {
658 274920 : return _resize(allocator, newSize, newSize, newBitsValue);
659 : }
660 :
661 : ASMJIT_API Error _resize(ZoneAllocator* allocator, uint32_t newSize, uint32_t idealCapacity, bool newBitsValue) noexcept;
662 : ASMJIT_API Error _append(ZoneAllocator* allocator, bool value) noexcept;
663 :
664 : //! \}
665 :
666 : //! \name Iterators
667 : //! \{
668 :
669 : class ForEachBitSet : public Support::BitVectorIterator<BitWord> {
670 : public:
671 : inline explicit ForEachBitSet(const ZoneBitVector& bitVector) noexcept
672 54984 : : Support::BitVectorIterator<BitWord>(bitVector.data(), bitVector.sizeInBitWords()) {}
673 : };
674 :
675 : template<class Operator>
676 : class ForEachBitOp : public Support::BitVectorOpIterator<BitWord, Operator> {
677 : public:
678 27492 : inline ForEachBitOp(const ZoneBitVector& a, const ZoneBitVector& b) noexcept
679 27492 : : Support::BitVectorOpIterator<BitWord, Operator>(a.data(), b.data(), a.sizeInBitWords()) {
680 : ASMJIT_ASSERT(a.size() == b.size());
681 27492 : }
682 : };
683 :
684 : //! \}
685 : };
686 :
687 : //! \}
688 :
689 : ASMJIT_END_NAMESPACE
690 :
691 : #endif // ASMJIT_CORE_ZONEVECTOR_H_INCLUDED
692 :
693 : #endif // __PLUMED_HAS_ASMJIT
|