8 #include <RADCore/RADLicenseGate.h>
17 #include <initializer_list>
24 #include <type_traits>
34 if (value <= 2)
return 2;
36 for (
size_t shift = 1; shift <
sizeof(size_t) * 8; shift <<= 1) {
37 value |= value >> shift;
52 template<
typename Container>
56 T*
data()
const {
return data_; }
58 size_t size()
const {
return size_; }
60 bool empty()
const {
return size_ == 0; }
62 T&
operator[](
size_t index)
const {
return data_[index]; }
64 T*
begin()
const {
return data_; }
66 T*
end()
const {
return data_ + size_; }
89 size_t size()
const {
return bytes_.size(); }
91 bool empty()
const {
return bytes_.empty(); }
93 uint8_t*
data() {
return bytes_.data(); }
95 const uint8_t*
data()
const {
return bytes_.data(); }
97 uint8_t&
operator[](
size_t index) {
return bytes_[index]; }
99 const uint8_t&
operator[](
size_t index)
const {
return bytes_[index]; }
103 void reserve(
size_t capacity) { bytes_.reserve(capacity); }
105 void append(uint8_t
byte) { bytes_.push_back(
byte); }
109 const auto* first =
static_cast<const uint8_t*
>(
data);
110 bytes_.insert(bytes_.end(), first, first +
size);
117 const std::vector<uint8_t>&
vector()
const {
return bytes_; }
120 std::vector<uint8_t> bytes_;
129 void*
allocate(
size_t size,
size_t alignment =
alignof(std::max_align_t)) {
130 size_t current = offset_;
131 const size_t aligned = (current + alignment - 1) & ~(alignment - 1);
132 if (aligned + size > storage_.size()) {
133 storage_.resize(std::max(storage_.size() * 2, aligned + size));
135 offset_ = aligned + size;
136 return storage_.data() + aligned;
141 size_t used()
const {
return offset_; }
143 size_t capacity()
const {
return storage_.size(); }
146 std::vector<uint8_t> storage_;
156 storage_((blockSize_ * blockCount + sizeof(std::max_align_t) - 1) / sizeof(std::max_align_t)),
158 auto* base =
reinterpret_cast<uint8_t*
>(storage_.data());
159 for (
size_t i = 0; i < blockCount; ++i) {
160 auto* block = base + i * blockSize_;
161 *
reinterpret_cast<uint8_t**
>(block) = freeList_;
168 if (!freeList_)
return nullptr;
169 uint8_t* block = freeList_;
170 freeList_ = *
reinterpret_cast<uint8_t**
>(freeList_);
177 auto* block =
static_cast<uint8_t*
>(ptr);
178 *
reinterpret_cast<uint8_t**
>(block) = freeList_;
186 size_t blockSize_ = 0;
187 std::vector<std::max_align_t> storage_;
188 uint8_t* freeList_ =
nullptr;
213 if (!arena_)
return std::allocator<T>{}.allocate(n);
214 return static_cast<T*
>(arena_->
allocate(
sizeof(T) * n,
alignof(T)));
218 if (!arena_) std::allocator<T>{}.deallocate(ptr, n);
230 template<
typename T,
typename U>
236 template<
typename T,
typename U>
238 return !(lhs == rhs);
242 template<
typename T,
size_t Alignment = alignof(T)>
256 if (posix_memalign(&ptr, Alignment,
sizeof(T) * n) != 0) {
257 throw std::bad_alloc();
259 return static_cast<T*
>(ptr);
266 template<
typename T,
size_t A,
typename U,
size_t B>
272 template<
typename T,
size_t A,
typename U,
size_t B>
274 return !(lhs == rhs);
278 template <
typename T,
typename Alloc = std::allocator<T>>
304 explicit RADVector(
size_t count,
const T& value = T()) {
311 for (
const auto& value : values)
push_back(value);
317 for (
const auto& value : other)
push_back(value);
322 : data_(other.data_),
324 capacity_(other.capacity_),
325 allocator_(std::move(other.allocator_)) {
326 other.data_ =
nullptr;
333 if (
this == &other)
return *
this;
336 for (
const auto& value : other)
push_back(value);
342 if (
this == &other)
return *
this;
346 capacity_ = other.capacity_;
347 allocator_ = std::move(other.allocator_);
348 other.data_ =
nullptr;
373 bool empty() const noexcept {
return size_ == 0; }
375 size_t size() const noexcept {
return size_; }
377 size_t capacity() const noexcept {
return capacity_; }
379 T*
data() noexcept {
return data_; }
381 const T*
data() const noexcept {
return data_; }
384 T&
operator[](
size_t index) noexcept {
return data_[index]; }
386 const T&
operator[](
size_t index)
const noexcept {
return data_[index]; }
389 T&
at(
size_t index) {
390 if (index >= size_)
throw std::out_of_range(
"RADVector::at");
395 const T&
at(
size_t index)
const {
396 if (index >= size_)
throw std::out_of_range(
"RADVector::at");
401 T&
front() noexcept {
return data_[0]; }
403 const T&
front() const noexcept {
return data_[0]; }
405 T&
back() noexcept {
return data_[size_ - 1]; }
407 const T&
back() const noexcept {
return data_[size_ - 1]; }
411 if (newCapacity <= capacity_)
return;
412 reallocate(newCapacity);
417 if (size_ == capacity_)
return;
427 if (newSize < size_) {
428 destroyRange(newSize, size_);
432 reserveForSize(newSize);
433 for (; size_ < newSize; ++size_) {
434 std::allocator_traits<Alloc>::construct(allocator_, data_ + size_);
439 void resize(
size_t newSize,
const T& value) {
440 if (newSize < size_) {
441 destroyRange(newSize, size_);
445 reserveForSize(newSize);
446 for (; size_ < newSize; ++size_) {
447 std::allocator_traits<Alloc>::construct(allocator_, data_ + size_, value);
452 template <
typename... Args>
454 reserveForSize(size_ + 1);
455 std::allocator_traits<Alloc>::construct(
456 allocator_, data_ + size_, std::forward<Args>(args)...);
457 return data_[size_++];
467 if (size_ == 0)
return;
469 std::allocator_traits<Alloc>::destroy(allocator_, data_ + size_);
474 const size_t index =
static_cast<size_t>(position - data_);
475 if (index >= size_)
return end();
476 for (
size_t i = index; i + 1 < size_; ++i) {
477 data_[i] = std::move(data_[i + 1]);
480 return data_ + index;
485 destroyRange(0, size_);
490 void reserveForSize(
size_t desired) {
491 if (desired <= capacity_)
return;
492 const size_t grown = capacity_ == 0 ? 8 : capacity_ + capacity_ / 2;
493 reallocate(std::max(desired, grown));
496 void reallocate(
size_t newCapacity) {
497 T* newData = std::allocator_traits<Alloc>::allocate(allocator_, newCapacity);
498 size_t constructed = 0;
500 for (; constructed < size_; ++constructed) {
501 std::allocator_traits<Alloc>::construct(
502 allocator_, newData + constructed,
503 std::move_if_noexcept(data_[constructed]));
506 for (
size_t i = 0; i < constructed; ++i) {
507 std::allocator_traits<Alloc>::destroy(allocator_, newData + i);
509 std::allocator_traits<Alloc>::deallocate(allocator_, newData, newCapacity);
512 destroyRange(0, size_);
513 if (data_) std::allocator_traits<Alloc>::deallocate(allocator_, data_, capacity_);
515 capacity_ = newCapacity;
518 void destroyRange(
size_t first,
size_t last) noexcept {
519 for (
size_t i = first; i < last; ++i) {
520 std::allocator_traits<Alloc>::destroy(allocator_, data_ + i);
524 void destroyStorage() noexcept {
527 std::allocator_traits<Alloc>::deallocate(allocator_, data_, capacity_);
535 size_t capacity_ = 0;
540 template <
typename T,
size_t InlineN = 8,
typename Alloc = std::allocator<T>>
550 : data_(inlineData()), capacity_(InlineN) {}
556 for (
const auto& value : values)
push_back(value);
563 for (
const auto& value : other)
push_back(value);
569 if (other.usingInline()) {
570 for (
auto& value : other)
push_back(std::move(value));
575 capacity_ = other.capacity_;
576 other.data_ = other.inlineData();
578 other.capacity_ = InlineN;
584 if (
this == &other)
return *
this;
587 for (
const auto& value : other)
push_back(value);
593 if (
this == &other)
return *
this;
594 destroyHeapStorage();
595 data_ = inlineData();
598 if (other.usingInline()) {
599 for (
auto& value : other)
push_back(std::move(value));
604 capacity_ = other.capacity_;
605 other.data_ = other.inlineData();
607 other.capacity_ = InlineN;
614 destroyHeapStorage();
626 bool empty() const noexcept {
return size_ == 0; }
628 size_t size() const noexcept {
return size_; }
630 size_t capacity() const noexcept {
return capacity_; }
634 T*
data() noexcept {
return data_; }
636 const T*
data() const noexcept {
return data_; }
638 T&
operator[](
size_t index) noexcept {
return data_[index]; }
640 const T&
operator[](
size_t index)
const noexcept {
return data_[index]; }
642 T&
back() noexcept {
return data_[size_ - 1]; }
644 const T&
back() const noexcept {
return data_[size_ - 1]; }
648 if (newCapacity <= capacity_)
return;
649 reallocate(newCapacity);
653 template <
typename... Args>
655 if (size_ == capacity_) {
656 reallocate(capacity_ + capacity_ / 2 + 1);
658 new (data_ + size_) T(std::forward<Args>(args)...);
659 return data_[size_++];
669 if (size_ == 0)
return;
675 for (
size_t i = 0; i < size_; ++i) data_[i].~T();
680 using Storage = std::aligned_storage_t<
sizeof(T),
alignof(T)>;
682 T* inlineData() noexcept {
683 return reinterpret_cast<T*
>(inlineStorage_);
686 const T* inlineData() const noexcept {
687 return reinterpret_cast<const T*
>(inlineStorage_);
690 bool usingInline() const noexcept {
691 return data_ == inlineData();
694 void reallocate(
size_t newCapacity) {
695 T* newData = std::allocator_traits<Alloc>::allocate(allocator_, newCapacity);
696 size_t constructed = 0;
698 for (; constructed < size_; ++constructed) {
699 new (newData + constructed) T(std::move_if_noexcept(data_[constructed]));
702 for (
size_t i = 0; i < constructed; ++i) newData[i].~T();
703 std::allocator_traits<Alloc>::deallocate(allocator_, newData, newCapacity);
707 if (!usingInline()) {
708 std::allocator_traits<Alloc>::deallocate(allocator_, data_, capacity_);
712 capacity_ = newCapacity;
715 void destroyHeapStorage() noexcept {
717 if (!usingInline()) {
718 std::allocator_traits<Alloc>::deallocate(allocator_, data_, capacity_);
719 data_ = inlineData();
724 Storage inlineStorage_[InlineN == 0 ? 1 : InlineN];
732 template <
typename T,
typename Alloc = std::allocator<T>>
743 if (data_) std::allocator_traits<Alloc>::deallocate(allocator_, data_, capacity_);
749 for (
const auto& value : other)
push_back(value);
754 if (
this == &other)
return *
this;
757 for (
const auto& value : other)
push_back(value);
763 : data_(other.data_),
764 capacity_(other.capacity_),
768 allocator_(std::move(other.allocator_)) {
769 other.data_ =
nullptr;
778 if (
this == &other)
return *
this;
780 if (data_) std::allocator_traits<Alloc>::deallocate(allocator_, data_, capacity_);
782 capacity_ = other.capacity_;
786 allocator_ = std::move(other.allocator_);
787 other.data_ =
nullptr;
824 const T&
operator*()
const {
return (*owner_)[offset_]; }
843 bool empty() const noexcept {
return size_ == 0; }
845 size_t size() const noexcept {
return size_; }
847 size_t capacity() const noexcept {
return capacity_; }
850 T&
operator[](
size_t index) noexcept {
return data_[physical(index)]; }
852 const T&
operator[](
size_t index)
const noexcept {
return data_[physical(index)]; }
854 T&
front() noexcept {
return (*
this)[0]; }
856 const T&
front() const noexcept {
return (*
this)[0]; }
858 T&
back() noexcept {
return (*
this)[size_ - 1]; }
860 const T&
back() const noexcept {
return (*
this)[size_ - 1]; }
865 if (newCapacity <= capacity_)
return;
866 T* newData = std::allocator_traits<Alloc>::allocate(allocator_, newCapacity);
867 size_t constructed = 0;
869 for (; constructed < size_; ++constructed) {
870 std::allocator_traits<Alloc>::construct(
871 allocator_, newData + constructed,
872 std::move_if_noexcept((*
this)[constructed]));
875 for (
size_t i = 0; i < constructed; ++i) {
876 std::allocator_traits<Alloc>::destroy(allocator_, newData + i);
878 std::allocator_traits<Alloc>::deallocate(allocator_, newData, newCapacity);
882 if (data_) std::allocator_traits<Alloc>::deallocate(allocator_, data_, capacity_);
884 capacity_ = newCapacity;
885 mask_ = capacity_ - 1;
891 template <
typename... Args>
893 if (size_ == capacity_)
reserve(capacity_ * 2);
894 const size_t index = physical(size_);
895 std::allocator_traits<Alloc>::construct(
896 allocator_, data_ + index, std::forward<Args>(args)...);
902 template <
typename... Args>
904 if (size_ == capacity_)
reserve(capacity_ * 2);
905 head_ = (head_ - 1) & mask_;
906 std::allocator_traits<Alloc>::construct(
907 allocator_, data_ + head_, std::forward<Args>(args)...);
924 std::allocator_traits<Alloc>::destroy(allocator_, data_ + head_);
925 head_ = (head_ + 1) & mask_;
932 const size_t index = physical(size_ - 1);
933 std::allocator_traits<Alloc>::destroy(allocator_, data_ + index);
939 for (
size_t i = 0; i < size_; ++i) {
940 std::allocator_traits<Alloc>::destroy(allocator_, data_ + physical(i));
947 size_t physical(
size_t logical)
const noexcept {
948 return (head_ + logical) & mask_;
952 size_t capacity_ = 0;
960 template <
typename T,
typename Alloc = std::allocator<T>>
964 explicit RADQueue(
size_t capacity = 16) : buffer_(capacity) {}
966 bool empty() const noexcept {
return buffer_.empty(); }
968 size_t size() const noexcept {
return buffer_.size(); }
970 T&
front() noexcept {
return buffer_.front(); }
972 const T&
front() const noexcept {
return buffer_.front(); }
974 void push(
const T& value) { buffer_.push_back(value); }
976 void push(T&& value) { buffer_.push_back(std::move(value)); }
978 template <
typename... Args> T&
emplace(Args&&... args) {
979 return buffer_.emplace_back(std::forward<Args>(args)...);
982 void pop() { buffer_.pop_front(); }
991 template <
typename T,
typename Alloc = std::allocator<T>>
995 bool empty() const noexcept {
return values_.empty(); }
997 size_t size() const noexcept {
return values_.size(); }
999 T&
top() noexcept {
return values_.back(); }
1001 const T&
top() const noexcept {
return values_.back(); }
1003 void push(
const T& value) { values_.push_back(value); }
1005 void push(T&& value) { values_.push_back(std::move(value)); }
1007 template <
typename... Args> T&
emplace(Args&&... args) {
1008 return values_.emplace_back(std::forward<Args>(args)...);
1011 void pop() { values_.pop_back(); }
1020 template <
typename T>
1026 mask_(capacity_ - 1),
1027 storage_(std::make_unique<Slot[]>(capacity_)) {}
1032 const size_t head = head_.load(std::memory_order_relaxed);
1033 storage_[head].ptr()->~T();
1034 head_.store((head + 1) & mask_, std::memory_order_relaxed);
1045 return head_.load(std::memory_order_acquire) == tail_.load(std::memory_order_acquire);
1049 size_t capacity() const noexcept {
return capacity_ - 1; }
1058 return emplace(std::move(value));
1062 template <
typename... Args>
1064 const size_t tail = tail_.load(std::memory_order_relaxed);
1065 const size_t next = (tail + 1) & mask_;
1066 if (next == head_.load(std::memory_order_acquire))
return false;
1067 new (storage_[tail].ptr()) T(std::forward<Args>(args)...);
1068 tail_.store(next, std::memory_order_release);
1074 const size_t head = head_.load(std::memory_order_relaxed);
1075 if (head == tail_.load(std::memory_order_acquire))
return false;
1076 T* value = storage_[head].ptr();
1077 out = std::move(*value);
1079 head_.store((head + 1) & mask_, std::memory_order_release);
1085 alignas(T)
unsigned char bytes[
sizeof(T)];
1086 T* ptr() noexcept {
return reinterpret_cast<T*
>(bytes); }
1089 const size_t capacity_;
1091 std::unique_ptr<Slot[]> storage_;
1092 std::atomic<size_t> head_{0};
1093 std::atomic<size_t> tail_{0};
1097 template <
typename K,
typename V,
typename Hash = std::hash<K>,
typename Eq = std::equal_to<K>>
1104 enum class State : uint8_t { Empty, Occupied, Deleted };
1106 State state = State::Empty;
1107 std::optional<value_type> value;
1114 static constexpr
size_t npos = std::numeric_limits<size_t>::max();
1129 rehash(other.capacity_);
1130 for (
const auto& value : other)
insert(value.first, value.second);
1135 if (
this == &other)
return *
this;
1142 rehash(other.capacity_);
1143 for (
const auto& value : other)
insert(value.first, value.second);
1149 : entries_(other.entries_),
1150 capacity_(other.capacity_),
1153 tombstones_(other.tombstones_),
1154 hasher_(std::move(other.hasher_)),
1155 eq_(std::move(other.eq_)) {
1156 other.entries_ =
nullptr;
1157 other.capacity_ = 0;
1160 other.tombstones_ = 0;
1165 if (
this == &other)
return *
this;
1168 entries_ = other.entries_;
1169 capacity_ = other.capacity_;
1170 mask_ = other.mask_;
1171 size_ = other.size_;
1172 tombstones_ = other.tombstones_;
1173 hasher_ = std::move(other.hasher_);
1174 eq_ = std::move(other.eq_);
1175 other.entries_ =
nullptr;
1176 other.capacity_ = 0;
1179 other.tombstones_ = 0;
1205 while (entry_ != end_ && entry_->state != State::Occupied) ++entry_;
1227 while (entry_ != end_ && entry_->state != State::Occupied) ++entry_;
1229 const Entry* entry_;
1243 bool empty() const noexcept {
return size_ == 0; }
1245 size_t size() const noexcept {
return size_; }
1251 if (!entries_)
return;
1252 for (
size_t i = 0; i < capacity_; ++i) {
1253 if (entries_[i].state == State::Occupied) entries_[i].value.reset();
1254 entries_[i].state = State::Empty;
1262 return findIndex(key) != npos;
1267 const size_t index = findIndex(key);
1268 return index == npos ? nullptr : &entries_[index].value->second;
1272 const V*
find(
const K& key)
const {
1273 const size_t index = findIndex(key);
1274 return index == npos ? nullptr : &entries_[index].value->second;
1278 std::pair<iterator, bool>
insert(
const K& key,
const V& value) {
1283 template <
typename KeyArg,
typename ValueArg>
1284 std::pair<iterator, bool>
emplace(KeyArg&& key, ValueArg&& value) {
1286 InsertSlot slot = findInsertSlot(key);
1288 entries_[slot.index].value->second = std::forward<ValueArg>(value);
1289 return {
iterator(entries_ + slot.index, entries_ + capacity_),
false};
1291 if (entries_[slot.index].state == State::Deleted) --tombstones_;
1292 entries_[slot.index].state = State::Occupied;
1293 entries_[slot.index].value.emplace(
1294 std::forward<KeyArg>(key), std::forward<ValueArg>(value));
1296 return {
iterator(entries_ + slot.index, entries_ + capacity_),
true};
1301 return emplace(key, V{}).first->second;
1306 const size_t index = findIndex(key);
1307 if (index == npos)
return false;
1308 entries_[index].value.reset();
1309 entries_[index].state = State::Deleted;
1317 if (desired * 10 < capacity_ * 7)
return;
1318 rehash(desired * 2);
1322 void ensureCapacity() {
1323 if ((size_ + tombstones_ + 1) * 10 >= capacity_ * 7) {
1324 rehash(capacity_ * 2);
1328 void rehash(
size_t requestedCapacity) {
1330 Entry* oldEntries = entries_;
1331 const size_t oldCapacity = capacity_;
1332 entries_ =
new Entry[newCapacity];
1333 capacity_ = newCapacity;
1334 mask_ = newCapacity - 1;
1337 if (!oldEntries)
return;
1338 for (
size_t i = 0; i < oldCapacity; ++i) {
1339 if (oldEntries[i].state == State::Occupied) {
1340 emplace(std::move(oldEntries[i].value->first), std::move(oldEntries[i].value->second));
1341 oldEntries[i].value.reset();
1344 delete[] oldEntries;
1347 size_t findIndex(
const K& key)
const {
1348 if (!entries_)
return npos;
1349 size_t index = hasher_(key) & mask_;
1351 const Entry& entry = entries_[index];
1352 if (entry.state == State::Empty)
return npos;
1353 if (entry.state == State::Occupied && eq_(entry.value->first, key))
return index;
1354 index = (index + 1) & mask_;
1358 template <
typename KeyArg>
1359 InsertSlot findInsertSlot(
const KeyArg& key)
const {
1360 size_t index = hasher_(key) & mask_;
1361 size_t firstDeleted = npos;
1363 const Entry& entry = entries_[index];
1364 if (entry.state == State::Empty) {
1365 return {firstDeleted == npos ? index : firstDeleted,
false};
1367 if (entry.state == State::Deleted) {
1368 if (firstDeleted == npos) firstDeleted = index;
1369 }
else if (eq_(entry.value->first, key)) {
1370 return {index,
true};
1372 index = (index + 1) & mask_;
1376 Entry* entries_ =
nullptr;
1377 size_t capacity_ = 0;
1380 size_t tombstones_ = 0;
1386 template <
typename K,
typename Hash = std::hash<K>,
typename Eq = std::equal_to<K>>
1390 bool empty() const noexcept {
return map_.empty(); }
1392 size_t size() const noexcept {
return map_.size(); }
1396 void reserve(
size_t desired) { map_.reserve(desired); }
1398 bool contains(
const K& key)
const {
return map_.contains(key); }
1400 bool insert(
const K& key) {
return map_.insert(key, Empty{}).second; }
1402 bool erase(
const K& key) {
return map_.erase(key); }
1406 RADFlatHashMap<K, Empty, Hash, Eq> map_;
1410 template <
typename T,
typename Alloc = std::allocator<T>>
1420 for (
const auto& value : values)
push_back(value);
1425 for (
const auto& value : other)
push_back(value);
1430 if (
this == &other)
return *
this;
1432 for (
const auto& value : other)
push_back(value);
1438 : head_(other.head_), tail_(other.tail_), size_(other.size_) {
1439 other.head_ =
nullptr;
1440 other.tail_ =
nullptr;
1446 if (
this == &other)
return *
this;
1448 head_ = other.head_;
1449 tail_ = other.tail_;
1450 size_ = other.size_;
1451 other.head_ =
nullptr;
1452 other.tail_ =
nullptr;
1512 bool empty() const noexcept {
return size_ == 0; }
1514 size_t size() const noexcept {
return size_; }
1516 T&
front() noexcept {
return head_->value; }
1518 const T&
front() const noexcept {
return head_->value; }
1520 T&
back() noexcept {
return tail_->value; }
1522 const T&
back() const noexcept {
return tail_->value; }
1525 template <
typename... Args>
1527 Node* node =
new Node(std::forward<Args>(args)...);
1529 if (tail_) tail_->next = node;
1537 template <
typename... Args>
1539 Node* node =
new Node(std::forward<Args>(args)...);
1541 if (head_) head_->prev = node;
1561 head_ = head_->next;
1562 if (head_) head_->prev =
nullptr;
1563 else tail_ =
nullptr;
1572 tail_ = tail_->prev;
1573 if (tail_) tail_->next =
nullptr;
1574 else head_ =
nullptr;
1581 Node* node = it.node_;
1582 if (!node)
return end();
1583 Node* next = node->next;
1584 if (node->prev) node->prev->next = node->next;
1585 else head_ = node->next;
1586 if (node->next) node->next->prev = node->prev;
1587 else tail_ = node->prev;
1597 Node* next = node->next;
1608 template <
typename... Args>
1609 explicit Node(Args&&... args) : value(std::forward<Args>(args)...) {}
1611 Node* prev =
nullptr;
1612 Node* next =
nullptr;
1615 Node* head_ =
nullptr;
1616 Node* tail_ =
nullptr;
Standard-compatible aligned allocator.
Definition: RADDataStructures.h:243
void deallocate(T *ptr, size_t)
Frees aligned storage.
Definition: RADDataStructures.h:262
T value_type
Definition: RADDataStructures.h:245
T * allocate(size_t n)
Allocates n aligned objects.
Definition: RADDataStructures.h:254
Non-owning contiguous view over T values.
Definition: RADDataStructures.h:45
bool empty() const
Returns true when empty.
Definition: RADDataStructures.h:60
T * begin() const
Returns iterator to first element.
Definition: RADDataStructures.h:64
T * end() const
Returns iterator one past last element.
Definition: RADDataStructures.h:66
size_t size() const
Returns number of elements.
Definition: RADDataStructures.h:58
RADArrayView()=default
Creates an empty view.
T * data() const
Returns pointer to first element.
Definition: RADDataStructures.h:56
RADArrayView(T *data, size_t size)
Creates a view over data and size.
Definition: RADDataStructures.h:50
RADArrayView(Container &container)
Creates a view over a vector-like container.
Definition: RADDataStructures.h:53
T & operator[](size_t index) const
Returns element at index.
Definition: RADDataStructures.h:62
Owning byte array with lightweight append/view helpers.
Definition: RADDataStructures.h:79
const std::vector< uint8_t > & vector() const
Returns std::vector-compatible storage.
Definition: RADDataStructures.h:117
RADByteArray(size_t count)
Creates count zero-initialized bytes.
Definition: RADDataStructures.h:84
RADConstByteArrayView view() const
Returns const view.
Definition: RADDataStructures.h:115
void reserve(size_t capacity)
Reserves byte capacity.
Definition: RADDataStructures.h:103
uint8_t & operator[](size_t index)
Returns mutable byte at index.
Definition: RADDataStructures.h:97
void append(uint8_t byte)
Appends one byte.
Definition: RADDataStructures.h:105
bool empty() const
Returns true when no bytes are stored.
Definition: RADDataStructures.h:91
RADByteArrayView view()
Returns mutable view.
Definition: RADDataStructures.h:113
RADByteArray(const void *data, size_t size)
Creates bytes from raw memory.
Definition: RADDataStructures.h:86
const uint8_t * data() const
Returns const byte pointer.
Definition: RADDataStructures.h:95
size_t size() const
Returns number of bytes.
Definition: RADDataStructures.h:89
void clear()
Clears all bytes.
Definition: RADDataStructures.h:101
void append(const void *data, size_t size)
Appends raw memory bytes.
Definition: RADDataStructures.h:107
const uint8_t & operator[](size_t index) const
Returns const byte at index.
Definition: RADDataStructures.h:99
uint8_t * data()
Returns mutable byte pointer.
Definition: RADDataStructures.h:93
RADByteArray()=default
Creates an empty byte array.
Fixed-size block pool for high-frequency same-size allocations.
Definition: RADDataStructures.h:151
size_t blockSize() const
Returns the block size.
Definition: RADDataStructures.h:183
void deallocate(void *ptr)
Returns one block to the pool.
Definition: RADDataStructures.h:175
RADFixedPool(size_t blockSize, size_t blockCount)
Creates a pool with blockSize bytes per block and blockCount blocks.
Definition: RADDataStructures.h:154
void * allocate()
Allocates one fixed-size block or returns nullptr when exhausted.
Definition: RADDataStructures.h:167
Const forward iterator over occupied map entries.
Definition: RADDataStructures.h:1212
const_iterator & operator++()
Advances to the next occupied entry.
Definition: RADDataStructures.h:1221
const value_type & operator*() const
Returns current key/value pair.
Definition: RADDataStructures.h:1217
const_iterator(const Entry *entry, const Entry *end)
Creates a const iterator over an entry range.
Definition: RADDataStructures.h:1215
bool operator!=(const const_iterator &other) const
Compares iterator position.
Definition: RADDataStructures.h:1223
const value_type * operator->() const
Returns current key/value pair pointer.
Definition: RADDataStructures.h:1219
Forward iterator over occupied map entries.
Definition: RADDataStructures.h:1190
iterator(Entry *entry, Entry *end)
Creates an iterator over an entry range.
Definition: RADDataStructures.h:1193
iterator & operator++()
Advances to the next occupied entry.
Definition: RADDataStructures.h:1199
value_type & operator*() const
Returns current key/value pair.
Definition: RADDataStructures.h:1195
bool operator!=(const iterator &other) const
Compares iterator position.
Definition: RADDataStructures.h:1201
value_type * operator->() const
Returns current key/value pair pointer.
Definition: RADDataStructures.h:1197
Open-addressed flat hash map optimized for cache-local lookups.
Definition: RADDataStructures.h:1098
const_iterator begin() const noexcept
Returns const iterator to first occupied entry.
Definition: RADDataStructures.h:1238
RADFlatHashMap()
Creates an empty map with default capacity.
Definition: RADDataStructures.h:1118
std::pair< iterator, bool > emplace(KeyArg &&key, ValueArg &&value)
Inserts or replaces key/value with forwarding support.
Definition: RADDataStructures.h:1284
iterator end() noexcept
Returns iterator one past the entry table.
Definition: RADDataStructures.h:1236
RADFlatHashMap(const RADFlatHashMap &other)
Copies another map.
Definition: RADDataStructures.h:1128
~RADFlatHashMap()
Destroys entries and releases storage.
Definition: RADDataStructures.h:1184
std::pair< iterator, bool > insert(const K &key, const V &value)
Inserts or replaces key with value.
Definition: RADDataStructures.h:1278
RADFlatHashMap(size_t capacity)
Creates an empty map with at least capacity slots.
Definition: RADDataStructures.h:1123
size_t size() const noexcept
Returns number of occupied entries.
Definition: RADDataStructures.h:1245
const V * find(const K &key) const
Returns const pointer to mapped value for key, or nullptr when absent.
Definition: RADDataStructures.h:1272
V & operator[](const K &key)
Returns mapped value for key, inserting a default value if absent.
Definition: RADDataStructures.h:1300
iterator begin() noexcept
Returns iterator to first occupied entry.
Definition: RADDataStructures.h:1234
const_iterator end() const noexcept
Returns const iterator one past the entry table.
Definition: RADDataStructures.h:1240
bool empty() const noexcept
Returns true when the map contains no entries.
Definition: RADDataStructures.h:1243
std::pair< K, V > value_type
Stored key/value pair type.
Definition: RADDataStructures.h:1101
bool erase(const K &key)
Erases key and returns true when an entry was removed.
Definition: RADDataStructures.h:1305
void reserve(size_t desired)
Reserves enough capacity for desired entries.
Definition: RADDataStructures.h:1316
V * find(const K &key)
Returns pointer to mapped value for key, or nullptr when absent.
Definition: RADDataStructures.h:1266
bool contains(const K &key) const
Returns true when key exists.
Definition: RADDataStructures.h:1261
size_t capacity() const noexcept
Returns current hash table capacity.
Definition: RADDataStructures.h:1247
RADFlatHashMap(RADFlatHashMap &&other) noexcept
Moves another map without rehashing.
Definition: RADDataStructures.h:1148
RADFlatHashMap & operator=(RADFlatHashMap &&other) noexcept
Replaces this map by taking other's storage.
Definition: RADDataStructures.h:1164
void clear() noexcept
Removes all entries while keeping table storage.
Definition: RADDataStructures.h:1250
RADFlatHashMap & operator=(const RADFlatHashMap &other)
Replaces this map with a copy of other.
Definition: RADDataStructures.h:1134
Flat hash set implemented on top of RADFlatHashMap.
Definition: RADDataStructures.h:1387
bool erase(const K &key)
Removes key and returns true when it existed.
Definition: RADDataStructures.h:1402
size_t size() const noexcept
Returns number of stored keys.
Definition: RADDataStructures.h:1392
bool insert(const K &key)
Inserts key and returns true when newly inserted.
Definition: RADDataStructures.h:1400
bool contains(const K &key) const
Returns true when key exists.
Definition: RADDataStructures.h:1398
void reserve(size_t desired)
Reserves capacity for desired keys.
Definition: RADDataStructures.h:1396
void clear() noexcept
Removes all keys.
Definition: RADDataStructures.h:1394
bool empty() const noexcept
Returns true when the set contains no keys.
Definition: RADDataStructures.h:1390
Const forward iterator.
Definition: RADDataStructures.h:1486
const T * operator->() const
Returns current element pointer.
Definition: RADDataStructures.h:1493
const T & operator*() const
Returns current element.
Definition: RADDataStructures.h:1491
const_iterator(const Node *node)
Creates a const iterator from an internal node.
Definition: RADDataStructures.h:1489
const_iterator & operator++()
Advances to next node.
Definition: RADDataStructures.h:1495
bool operator!=(const const_iterator &other) const
Compares iterator inequality.
Definition: RADDataStructures.h:1497
Mutable bidirectional iterator.
Definition: RADDataStructures.h:1463
bool operator!=(const iterator &other) const
Compares iterator inequality.
Definition: RADDataStructures.h:1476
iterator & operator--()
Moves to previous node.
Definition: RADDataStructures.h:1474
iterator(Node *node)
Creates an iterator from an internal node.
Definition: RADDataStructures.h:1466
bool operator==(const iterator &other) const
Compares iterator equality.
Definition: RADDataStructures.h:1478
T & operator*() const
Returns current element.
Definition: RADDataStructures.h:1468
iterator & operator++()
Advances to next node.
Definition: RADDataStructures.h:1472
T * operator->() const
Returns current element pointer.
Definition: RADDataStructures.h:1470
Stable-node doubly linked list for cases where node stability matters.
Definition: RADDataStructures.h:1411
T & back() noexcept
Returns last element.
Definition: RADDataStructures.h:1520
void push_back(const T &value)
Appends a copy at the back.
Definition: RADDataStructures.h:1549
RADList()=default
Creates an empty list.
const T & back() const noexcept
Returns last element.
Definition: RADDataStructures.h:1522
const_iterator end() const noexcept
Returns const end iterator.
Definition: RADDataStructures.h:1510
RADList & operator=(const RADList &other)
Replaces this list with a copy of other.
Definition: RADDataStructures.h:1429
iterator end() noexcept
Returns end iterator.
Definition: RADDataStructures.h:1506
void pop_back()
Removes the last node.
Definition: RADDataStructures.h:1569
void clear() noexcept
Removes all nodes.
Definition: RADDataStructures.h:1594
T & emplace_front(Args &&... args)
Constructs an element at the front and returns it.
Definition: RADDataStructures.h:1538
const T & front() const noexcept
Returns first element.
Definition: RADDataStructures.h:1518
RADList & operator=(RADList &&other) noexcept
Replaces this list by taking other's node chain.
Definition: RADDataStructures.h:1445
RADList(const RADList &other)
Copies another list.
Definition: RADDataStructures.h:1424
const_iterator begin() const noexcept
Returns const iterator to first node.
Definition: RADDataStructures.h:1508
T & emplace_back(Args &&... args)
Constructs an element at the back and returns it.
Definition: RADDataStructures.h:1526
iterator begin() noexcept
Returns iterator to first node.
Definition: RADDataStructures.h:1504
void push_front(const T &value)
Prepends a copy at the front.
Definition: RADDataStructures.h:1553
size_t size() const noexcept
Returns number of nodes.
Definition: RADDataStructures.h:1514
void push_back(T &&value)
Appends a moved value at the back.
Definition: RADDataStructures.h:1551
void push_front(T &&value)
Prepends a moved value at the front.
Definition: RADDataStructures.h:1555
RADList(RADList &&other) noexcept
Moves another list by taking its node chain.
Definition: RADDataStructures.h:1437
RADList(std::initializer_list< T > values)
Creates a list from initializer-list values.
Definition: RADDataStructures.h:1419
T & front() noexcept
Returns first element.
Definition: RADDataStructures.h:1516
bool empty() const noexcept
Returns true when no nodes are present.
Definition: RADDataStructures.h:1512
void pop_front()
Removes the first node.
Definition: RADDataStructures.h:1558
iterator erase(iterator it)
Erases the node at it and returns the following iterator.
Definition: RADDataStructures.h:1580
~RADList()
Destroys all nodes.
Definition: RADDataStructures.h:1458
Standard-compatible allocator backed by RADMonotonicArena.
Definition: RADDataStructures.h:193
RADMonotonicArena * arena() const
Returns backing arena.
Definition: RADDataStructures.h:221
RADMonotonicAllocator(const RADMonotonicAllocator< U > &other)
Converts from another monotonic allocator type.
Definition: RADDataStructures.h:209
RADMonotonicAllocator()=default
Creates an allocator without an arena; allocations use std::allocator.
RADMonotonicAllocator(RADMonotonicArena *arena)
Creates an allocator using arena.
Definition: RADDataStructures.h:206
void deallocate(T *ptr, size_t n)
No-op for arena allocations; std fallback deallocates normally.
Definition: RADDataStructures.h:217
T value_type
Definition: RADDataStructures.h:195
T * allocate(size_t n)
Allocates n objects.
Definition: RADDataStructures.h:212
Simple monotonic arena for short-lived allocations.
Definition: RADDataStructures.h:124
size_t capacity() const
Returns backing capacity.
Definition: RADDataStructures.h:143
size_t used() const
Returns allocated bytes in the current generation.
Definition: RADDataStructures.h:141
RADMonotonicArena(size_t capacity=65536)
Creates an arena with initial capacity bytes.
Definition: RADDataStructures.h:127
void * allocate(size_t size, size_t alignment=alignof(std::max_align_t))
Allocates size bytes with alignment.
Definition: RADDataStructures.h:129
void reset()
Resets all allocations without releasing storage.
Definition: RADDataStructures.h:139
FIFO queue adapter backed by RADRingBuffer.
Definition: RADDataStructures.h:961
void push(const T &value)
Pushes a copy at the back.
Definition: RADDataStructures.h:974
void push(T &&value)
Pushes a moved value at the back.
Definition: RADDataStructures.h:976
T & emplace(Args &&... args)
Constructs an element at the back.
Definition: RADDataStructures.h:978
void clear()
Removes all queued elements.
Definition: RADDataStructures.h:984
const T & front() const noexcept
Returns the front element.
Definition: RADDataStructures.h:972
T & front() noexcept
Returns the front element.
Definition: RADDataStructures.h:970
void pop()
Removes the front element.
Definition: RADDataStructures.h:982
size_t size() const noexcept
Returns number of queued elements.
Definition: RADDataStructures.h:968
RADQueue(size_t capacity=16)
Creates a queue with initial ring capacity.
Definition: RADDataStructures.h:964
bool empty() const noexcept
Returns true when the queue is empty.
Definition: RADDataStructures.h:966
Const forward iterator over logical ring order.
Definition: RADDataStructures.h:815
T value_type
Definition: RADDataStructures.h:818
const T * pointer
Definition: RADDataStructures.h:820
bool operator!=(const const_iterator &other) const
Definition: RADDataStructures.h:826
const T & operator*() const
Definition: RADDataStructures.h:824
const_iterator(const RADRingBuffer *owner, size_t offset)
Definition: RADDataStructures.h:823
std::forward_iterator_tag iterator_category
Definition: RADDataStructures.h:817
const T & reference
Definition: RADDataStructures.h:821
std::ptrdiff_t difference_type
Definition: RADDataStructures.h:819
const_iterator & operator++()
Definition: RADDataStructures.h:825
Forward iterator over logical ring order.
Definition: RADDataStructures.h:796
iterator(RADRingBuffer *owner, size_t offset)
Definition: RADDataStructures.h:804
std::ptrdiff_t difference_type
Definition: RADDataStructures.h:800
T & reference
Definition: RADDataStructures.h:802
T * pointer
Definition: RADDataStructures.h:801
iterator & operator++()
Definition: RADDataStructures.h:806
std::forward_iterator_tag iterator_category
Definition: RADDataStructures.h:798
T value_type
Definition: RADDataStructures.h:799
bool operator!=(const iterator &other) const
Definition: RADDataStructures.h:807
T & operator*() const
Definition: RADDataStructures.h:805
Power-of-two circular buffer with push/pop at both ends.
Definition: RADDataStructures.h:733
void push_back(const T &value)
Appends a copy at the back.
Definition: RADDataStructures.h:913
iterator begin() noexcept
Returns iterator to the logical first element.
Definition: RADDataStructures.h:834
void pop_front()
Removes the logical first element.
Definition: RADDataStructures.h:922
const T & operator[](size_t index) const noexcept
Returns const logical element index without bounds checking.
Definition: RADDataStructures.h:852
size_t capacity() const noexcept
Returns allocated ring capacity.
Definition: RADDataStructures.h:847
T & back() noexcept
Returns last logical element.
Definition: RADDataStructures.h:858
RADRingBuffer(size_t capacity=16)
Creates a ring buffer with at least capacity slots.
Definition: RADDataStructures.h:736
T & operator[](size_t index) noexcept
Returns logical element index without bounds checking.
Definition: RADDataStructures.h:850
RADRingBuffer(RADRingBuffer &&other) noexcept
Moves another ring buffer without moving individual elements.
Definition: RADDataStructures.h:762
void push_back(T &&value)
Appends a moved value at the back.
Definition: RADDataStructures.h:915
~RADRingBuffer()
Destroys elements and releases storage.
Definition: RADDataStructures.h:741
void push_front(const T &value)
Prepends a copy at the front.
Definition: RADDataStructures.h:917
bool empty() const noexcept
Returns true when no elements are stored.
Definition: RADDataStructures.h:843
T & front() noexcept
Returns first logical element.
Definition: RADDataStructures.h:854
void push_front(T &&value)
Prepends a moved value at the front.
Definition: RADDataStructures.h:919
const_iterator begin() const noexcept
Returns const iterator to the logical first element.
Definition: RADDataStructures.h:838
const T & back() const noexcept
Returns last logical element.
Definition: RADDataStructures.h:860
void pop_back()
Removes the logical last element.
Definition: RADDataStructures.h:930
RADRingBuffer & operator=(RADRingBuffer &&other) noexcept
Replaces this buffer by taking other's storage.
Definition: RADDataStructures.h:777
T & emplace_front(Args &&... args)
Constructs an element at the logical front.
Definition: RADDataStructures.h:903
void clear() noexcept
Destroys all elements while keeping storage.
Definition: RADDataStructures.h:938
RADRingBuffer(const RADRingBuffer &other)
Copies another ring buffer in logical order.
Definition: RADDataStructures.h:747
const T & front() const noexcept
Returns first logical element.
Definition: RADDataStructures.h:856
RADRingBuffer & operator=(const RADRingBuffer &other)
Replaces this buffer with a copy of other.
Definition: RADDataStructures.h:753
const_iterator end() const noexcept
Returns const iterator one past the logical last element.
Definition: RADDataStructures.h:840
void reserve(size_t requestedCapacity)
Ensures capacity is at least requestedCapacity.
Definition: RADDataStructures.h:863
size_t size() const noexcept
Returns number of stored elements.
Definition: RADDataStructures.h:845
T & emplace_back(Args &&... args)
Constructs an element at the logical back.
Definition: RADDataStructures.h:892
iterator end() noexcept
Returns iterator one past the logical last element.
Definition: RADDataStructures.h:836
Vector with InlineN elements of inline storage before heap allocation.
Definition: RADDataStructures.h:541
void push_back(T &&value)
Appends value by move.
Definition: RADDataStructures.h:665
const T * data() const noexcept
Returns const contiguous storage pointer.
Definition: RADDataStructures.h:636
RADSmallVector()
Creates an empty small vector using inline storage.
Definition: RADDataStructures.h:549
RADSmallVector(const RADSmallVector &other)
Copies another small vector.
Definition: RADDataStructures.h:560
size_t size() const noexcept
Returns number of elements.
Definition: RADDataStructures.h:628
iterator end() noexcept
Returns iterator one past the last element.
Definition: RADDataStructures.h:622
void pop_back()
Removes the last element when present.
Definition: RADDataStructures.h:668
size_t capacity() const noexcept
Returns current capacity, including inline capacity.
Definition: RADDataStructures.h:630
const T & operator[](size_t index) const noexcept
Returns const element at index without bounds checking.
Definition: RADDataStructures.h:640
void push_back(const T &value)
Appends a copy of value.
Definition: RADDataStructures.h:663
bool usingInlineStorage() const noexcept
Returns true while storage is still inline.
Definition: RADDataStructures.h:632
RADSmallVector(std::initializer_list< T > values)
Creates a small vector from initializer-list values.
Definition: RADDataStructures.h:553
RADSmallVector & operator=(RADSmallVector &&other) noexcept
Replaces this vector by moving from other.
Definition: RADDataStructures.h:592
RADSmallVector & operator=(const RADSmallVector &other)
Replaces this vector with a copy of other.
Definition: RADDataStructures.h:583
T & emplace_back(Args &&... args)
Constructs an element at the end and returns it.
Definition: RADDataStructures.h:654
T & operator[](size_t index) noexcept
Returns element at index without bounds checking.
Definition: RADDataStructures.h:638
void clear() noexcept
Destroys all elements while keeping current storage.
Definition: RADDataStructures.h:674
const_iterator end() const noexcept
Returns const iterator one past the last element.
Definition: RADDataStructures.h:624
T * iterator
Mutable contiguous iterator.
Definition: RADDataStructures.h:544
const T * const_iterator
Const contiguous iterator.
Definition: RADDataStructures.h:546
~RADSmallVector()
Destroys elements and heap storage, if allocated.
Definition: RADDataStructures.h:613
T * data() noexcept
Returns mutable contiguous storage pointer.
Definition: RADDataStructures.h:634
bool empty() const noexcept
Returns true when no elements are stored.
Definition: RADDataStructures.h:626
T & back() noexcept
Returns last element; vector must not be empty.
Definition: RADDataStructures.h:642
const T & back() const noexcept
Returns last element; vector must not be empty.
Definition: RADDataStructures.h:644
const_iterator begin() const noexcept
Returns const iterator to first element.
Definition: RADDataStructures.h:620
void reserve(size_t newCapacity)
Ensures capacity is at least newCapacity.
Definition: RADDataStructures.h:647
RADSmallVector(RADSmallVector &&other) noexcept
Moves another small vector.
Definition: RADDataStructures.h:567
iterator begin() noexcept
Returns iterator to first element.
Definition: RADDataStructures.h:618
Lock-free single-producer/single-consumer bounded queue.
Definition: RADDataStructures.h:1021
size_t capacity() const noexcept
Returns usable queue capacity.
Definition: RADDataStructures.h:1049
bool try_pop(T &out)
Attempts to pop into out; returns false when empty.
Definition: RADDataStructures.h:1073
RADSpscQueue(size_t capacity)
Creates a queue with usable capacity rounded to a power of two.
Definition: RADDataStructures.h:1024
RADSpscQueue(const RADSpscQueue &)=delete
SPSC queues own atomic storage and cannot be copied.
bool emplace(Args &&... args)
Attempts to construct an item in-place; returns false when full.
Definition: RADDataStructures.h:1063
bool empty() const noexcept
Returns true when no item is available.
Definition: RADDataStructures.h:1044
RADSpscQueue & operator=(const RADSpscQueue &)=delete
SPSC queues own atomic storage and cannot be copied.
~RADSpscQueue()
Destroys any elements still queued.
Definition: RADDataStructures.h:1030
bool try_push(const T &value)
Attempts to push a copy; returns false when full.
Definition: RADDataStructures.h:1052
bool try_push(T &&value)
Attempts to push a moved value; returns false when full.
Definition: RADDataStructures.h:1057
LIFO stack adapter backed by RADVector.
Definition: RADDataStructures.h:992
const T & top() const noexcept
Returns the top element.
Definition: RADDataStructures.h:1001
size_t size() const noexcept
Returns number of stacked elements.
Definition: RADDataStructures.h:997
T & top() noexcept
Returns the top element.
Definition: RADDataStructures.h:999
void push(const T &value)
Pushes a copy onto the stack.
Definition: RADDataStructures.h:1003
bool empty() const noexcept
Returns true when the stack is empty.
Definition: RADDataStructures.h:995
void push(T &&value)
Pushes a moved value onto the stack.
Definition: RADDataStructures.h:1005
void clear()
Removes all elements.
Definition: RADDataStructures.h:1013
T & emplace(Args &&... args)
Constructs an element on top of the stack.
Definition: RADDataStructures.h:1007
void pop()
Removes the top element.
Definition: RADDataStructures.h:1011
Contiguous dynamic array optimized for RADLib hot paths.
Definition: RADDataStructures.h:279
T & emplace_back(Args &&... args)
Constructs an element at the end and returns it.
Definition: RADDataStructures.h:453
const_iterator cbegin() const noexcept
Returns const iterator to first element.
Definition: RADDataStructures.h:364
const T & at(size_t index) const
Returns const element at index or throws std::out_of_range.
Definition: RADDataStructures.h:395
size_t size_type
Unsigned size type.
Definition: RADDataStructures.h:286
const_iterator cend() const noexcept
Returns const iterator one past the last element.
Definition: RADDataStructures.h:370
const T & const_reference
Const reference type.
Definition: RADDataStructures.h:290
iterator end() noexcept
Returns iterator one past the last element.
Definition: RADDataStructures.h:366
RADVector & operator=(const RADVector &other)
Replaces this vector with a copy of other.
Definition: RADDataStructures.h:332
size_t size() const noexcept
Returns the number of constructed elements.
Definition: RADDataStructures.h:375
const T & front() const noexcept
Returns first element; vector must not be empty.
Definition: RADDataStructures.h:403
RADVector()=default
Creates an empty vector.
void clear() noexcept
Destroys all elements while keeping capacity.
Definition: RADDataStructures.h:484
const T & operator[](size_t index) const noexcept
Returns const element at index without bounds checking.
Definition: RADDataStructures.h:386
void resize(size_t newSize, const T &value)
Resizes with copies of value for new elements.
Definition: RADDataStructures.h:439
RADVector(RADVector &&other) noexcept
Moves another vector without moving individual elements when possible.
Definition: RADDataStructures.h:321
const T & back() const noexcept
Returns last element; vector must not be empty.
Definition: RADDataStructures.h:407
void push_back(T &&value)
Appends value by move.
Definition: RADDataStructures.h:463
const_iterator begin() const noexcept
Returns const iterator to first element.
Definition: RADDataStructures.h:362
void reserve(size_t newCapacity)
Ensures capacity is at least newCapacity.
Definition: RADDataStructures.h:410
RADVector(size_t count, const T &value=T())
Creates count copies of value.
Definition: RADDataStructures.h:304
iterator erase(const_iterator position)
Removes the element at position and returns the next iterator.
Definition: RADDataStructures.h:473
T & reference
Mutable reference type.
Definition: RADDataStructures.h:288
RADVector(std::initializer_list< T > values)
Creates a vector from initializer-list values.
Definition: RADDataStructures.h:309
T * data() noexcept
Returns mutable contiguous storage pointer.
Definition: RADDataStructures.h:379
void push_back(const T &value)
Appends a copy of value.
Definition: RADDataStructures.h:461
size_t capacity() const noexcept
Returns allocated element capacity.
Definition: RADDataStructures.h:377
T * pointer
Mutable pointer type.
Definition: RADDataStructures.h:292
void shrink_to_fit()
Releases unused capacity when possible.
Definition: RADDataStructures.h:416
const T * data() const noexcept
Returns const contiguous storage pointer.
Definition: RADDataStructures.h:381
void resize(size_t newSize)
Resizes with value-initialized new elements.
Definition: RADDataStructures.h:426
Alloc allocator_type
Allocator type.
Definition: RADDataStructures.h:284
bool empty() const noexcept
Returns true when the vector contains no elements.
Definition: RADDataStructures.h:373
T & at(size_t index)
Returns element at index or throws std::out_of_range.
Definition: RADDataStructures.h:389
void pop_back()
Removes the last element when present.
Definition: RADDataStructures.h:466
RADVector & operator=(RADVector &&other) noexcept
Replaces this vector by taking other's storage.
Definition: RADDataStructures.h:341
const T * const_iterator
Const contiguous iterator.
Definition: RADDataStructures.h:298
T & front() noexcept
Returns first element; vector must not be empty.
Definition: RADDataStructures.h:401
T & operator[](size_t index) noexcept
Returns element at index without bounds checking.
Definition: RADDataStructures.h:384
T * iterator
Mutable contiguous iterator.
Definition: RADDataStructures.h:296
T value_type
Stored value type.
Definition: RADDataStructures.h:282
RADVector(const RADVector &other)
Copies another vector.
Definition: RADDataStructures.h:315
~RADVector()
Destroys all elements and releases owned storage.
Definition: RADDataStructures.h:355
iterator begin() noexcept
Returns iterator to first element.
Definition: RADDataStructures.h:360
T & back() noexcept
Returns last element; vector must not be empty.
Definition: RADDataStructures.h:405
const_iterator end() const noexcept
Returns const iterator one past the last element.
Definition: RADDataStructures.h:368
const T * const_pointer
Const pointer type.
Definition: RADDataStructures.h:294
constexpr size_t nextPowerOfTwo(size_t value)
Returns the next power-of-two capacity at least as large as value.
Definition: RADDataStructures.h:33
Definition: RADDataStructures.h:28
bool operator!=(const RADMonotonicAllocator< T > &lhs, const RADMonotonicAllocator< U > &rhs)
Compares monotonic allocators by backing arena.
Definition: RADDataStructures.h:237
RADArrayView< uint8_t > RADByteArrayView
Mutable byte view.
Definition: RADDataStructures.h:74
RADArrayView< const uint8_t > RADConstByteArrayView
Const byte view.
Definition: RADDataStructures.h:76
bool operator==(const RADMonotonicAllocator< T > &lhs, const RADMonotonicAllocator< U > &rhs)
Compares monotonic allocators by backing arena.
Definition: RADDataStructures.h:231
Rebinds the allocator to another value type.
Definition: RADDataStructures.h:249
Rebinds the allocator to another value type.
Definition: RADDataStructures.h:199