aboutsummaryrefslogtreecommitdiff
path: root/source/10-common/PodVector.hpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2023-10-19 22:50:07 -0700
committerrtk0c <[email protected]>2023-10-19 22:50:07 -0700
commit2c92e07f337e42cf58970443f9de678f85a9b2a4 (patch)
tree075d5407e1e12a9d35cbee6e4c20ad34e0765c42 /source/10-common/PodVector.hpp
parent615809c036f604bce4582cea8ad49c64693f4f45 (diff)
The great renaming: switch to "module style"
Diffstat (limited to 'source/10-common/PodVector.hpp')
-rw-r--r--source/10-common/PodVector.hpp297
1 files changed, 0 insertions, 297 deletions
diff --git a/source/10-common/PodVector.hpp b/source/10-common/PodVector.hpp
deleted file mode 100644
index bd92e7d..0000000
--- a/source/10-common/PodVector.hpp
+++ /dev/null
@@ -1,297 +0,0 @@
-// File adapted from dear-imgui's ImVector, implemented in https://github.com/ocornut/imgUI/blob/master/imgui.h
-#pragma once
-
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <span>
-
-template <typename T>
-class PodVector {
-public:
- using value_type = T;
- using iterator = value_type*;
- using const_iterator = const value_type*;
-
-private:
- int mSize;
- int mCapacity;
- T* mData;
-
-public:
- PodVector() {
- mSize = mCapacity = 0;
- mData = nullptr;
- }
-
- PodVector(const PodVector<T>& src) {
- mSize = mCapacity = 0;
- mData = nullptr;
- operator=(src);
- }
-
- PodVector<T>& operator=(const PodVector<T>& src) {
- clear();
- resize(src.mSize);
- std::memcpy(mData, src.mData, (size_t)mSize * sizeof(T));
- return *this;
- }
-
- PodVector(PodVector&& src) {
- mSize = src.mSize;
- mCapacity = src.mCapacity;
- mData = src.mData;
-
- src.mSize = src.mCapacity = 0;
- src.mData = nullptr;
- }
-
- PodVector& operator=(PodVector&& src) {
- if (this != &src) {
- std::free(mData);
-
- mSize = src.mSize;
- mCapacity = src.mCapacity;
- mData = src.mData;
-
- src.mSize = src.mCapacity = 0;
- src.mData = nullptr;
- }
- return *this;
- }
-
- ~PodVector() {
- std::free(mData);
- }
-
- bool empty() const { return mSize == 0; }
- int size() const { return mSize; }
- int size_in_bytes() const { return mSize * (int)sizeof(T); }
- int max_size() const { return 0x7FFFFFFF / (int)sizeof(T); }
- int capacity() const { return mCapacity; }
-
- T& operator[](int i) {
- assert(i >= 0 && i < mSize);
- return mData[i];
- }
-
- const T& operator[](int i) const {
- assert(i >= 0 && i < mSize);
- return mData[i];
- }
-
- void clear() {
- if (mData) {
- mSize = mCapacity = 0;
- std::free(mData);
- mData = nullptr;
- }
- }
-
- T* begin() { return mData; }
- const T* begin() const { return mData; }
- T* end() { return mData + mSize; }
- const T* end() const { return mData + mSize; }
-
- T* data() { return mData; }
-
- T& front() {
- assert(mSize > 0);
- return mData[0];
- }
-
- const T& front() const {
- assert(mSize > 0);
- return mData[0];
- }
-
- T& back() {
- assert(mSize > 0);
- return mData[mSize - 1];
- }
-
- const T& back() const {
- assert(mSize > 0);
- return mData[mSize - 1];
- }
-
- void swap(PodVector<T>& rhs) {
- int rhs_size = rhs.mSize;
- rhs.mSize = mSize;
- mSize = rhs_size;
- int rhs_cap = rhs.mCapacity;
- rhs.mCapacity = mCapacity;
- mCapacity = rhs_cap;
- T* rhs_mDataTmp = rhs.mData;
- rhs.mData = mData;
- mData = rhs_mDataTmp;
- }
-
- int grow_capacity(int sz) const {
- int newCapacity = mCapacity ? (mCapacity + mCapacity / 2) : 8;
- return newCapacity > sz ? newCapacity : sz;
- }
-
- void resize(int new_size) {
- if (new_size > mCapacity) reserve(grow_capacity(new_size));
- mSize = new_size;
- }
-
- void resize_more(int size) {
- resize(mSize + size);
- }
-
- void resize(int new_size, const T& v) {
- if (new_size > mCapacity) reserve(grow_capacity(new_size));
- if (new_size > mSize) {
- for (int n = mSize; n < new_size; n++) {
- std::memcpy(&mData[n], &v, sizeof(v));
- }
- }
- mSize = new_size;
- }
-
- void resize_more(int size, const T& v) {
- resize(mSize + size, v);
- }
-
- void shrink(int new_size) {
- assert(new_size <= mSize);
- mSize = new_size;
- }
-
- /// Resize a vector to a smaller mSize, guaranteed not to cause a reallocation
- void reserve(int newCapacity) {
- if (newCapacity <= mCapacity) return;
- auto tmp = (T*)std::malloc((size_t)newCapacity * sizeof(T));
- if (mData) {
- std::memcpy(tmp, mData, (size_t)mSize * sizeof(T));
- std::free(mData);
- }
- mData = tmp;
- mCapacity = newCapacity;
- }
-
- void reserve_more(int size) {
- reserve(mSize + size);
- }
-
- /// NB: It is illegal to call push_back/push_front/insert with a reference pointing inside the PodVector data itself! e.g. v.push_back(v[10]) is forbidden.
- void push_back(const T& v) {
- if (mSize == mCapacity) reserve(grow_capacity(mSize + 1));
- std::memcpy(&mData[mSize], &v, sizeof(v));
- mSize++;
- }
-
- void pop_back() {
- assert(mSize > 0);
- mSize--;
- }
-
- void push_front(const T& v) {
- if (mSize == 0) {
- push_back(v);
- } else {
- insert(mData, v);
- }
- }
-
- T* erase(const T* it) {
- assert(it >= mData && it < mData + mSize);
- const ptrdiff_t off = it - mData;
- std::memmove(mData + off, mData + off + 1, ((size_t)mSize - (size_t)off - 1) * sizeof(T));
- mSize--;
- return mData + off;
- }
-
- T* erase(const T* it, const T* it_last) {
- assert(it >= mData && it < mData + mSize && it_last > it && it_last <= mData + mSize);
- const ptrdiff_t count = it_last - it;
- const ptrdiff_t off = it - mData;
- std::memmove(mData + off, mData + off + count, ((size_t)mSize - (size_t)off - count) * sizeof(T));
- mSize -= (int)count;
- return mData + off;
- }
-
- T* erase_unsorted(const T* it) {
- assert(it >= mData && it < mData + mSize);
- const ptrdiff_t off = it - mData;
- if (it < mData + mSize - 1) std::memcpy(mData + off, mData + mSize - 1, sizeof(T));
- mSize--;
- return mData + off;
- }
-
- T* insert(const T* it, const T& v) {
- assert(it >= mData && it <= mData + mSize);
- const ptrdiff_t off = it - mData;
- if (mSize == mCapacity) reserve(grow_capacity(mSize + 1));
- if (off < (int)mSize) std::memmove(mData + off + 1, mData + off, ((size_t)mSize - (size_t)off) * sizeof(T));
- std::memcpy(&mData[off], &v, sizeof(v));
- mSize++;
- return mData + off;
- }
-
- bool contains(const T& v) const {
- const T* data = mData;
- const T* dataEnd = mData + mSize;
- while (data < dataEnd) {
- if (*data++ == v) return true;
- }
- return false;
- }
-
- T* find(const T& v) {
- T* data = mData;
- const T* dataEnd = mData + mSize;
- while (data < dataEnd)
- if (*data == v)
- break;
- else
- ++data;
- return data;
- }
-
- const T* find(const T& v) const {
- const T* data = mData;
- const T* dataEnd = mData + mSize;
- while (data < dataEnd)
- if (*data == v)
- break;
- else
- ++data;
- return data;
- }
-
- bool find_erase(const T& v) {
- const T* it = find(v);
- if (it < mData + mSize) {
- erase(it);
- return true;
- }
- return false;
- }
-
- bool find_erase_unsorted(const T& v) {
- const T* it = find(v);
- if (it < mData + mSize) {
- erase_unsorted(it);
- return true;
- }
- return false;
- }
-
- int index_from_ptr(const T* it) const {
- assert(it >= mData && it < mData + mSize);
- const ptrdiff_t off = it - mData;
- return (int)off;
- }
-
- // Custom utility functions
-
- std::span<T> as_span() { return { mData, (size_t)mSize }; }
- std::span<uint8_t> as_data_span() { return { (uint8_t*)mData, (size_t)mSize * sizeof(T) }; }
- std::span<const T> as_span() const { return { mData, (size_t)mSize }; }
- std::span<const uint8_t> as_data_span() const { return { (uint8_t*)mData, (size_t)mSize * sizeof(T) }; }
-};