Create vector.h
This commit is contained in:
parent
ce07b55c34
commit
a9ab6d97fd
106
src/src/utils/vector.h
Normal file
106
src/src/utils/vector.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <new>
|
||||||
|
#include <utility>
|
||||||
|
#include <cassert>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class CreateVector {
|
||||||
|
static_assert(std::is_trivially_destructible_v<T>, "CreateVector only supports trivially destructible types for max performance.");
|
||||||
|
|
||||||
|
T* data_ = nullptr;
|
||||||
|
size_t size_ = 0;
|
||||||
|
size_t capacity_ = 0;
|
||||||
|
|
||||||
|
static constexpr size_t kMinCapacity = 8;
|
||||||
|
|
||||||
|
inline void grow(size_t minCapacity) {
|
||||||
|
size_t newCap = capacity_ ? capacity_ * 2 : kMinCapacity;
|
||||||
|
if (newCap < minCapacity) newCap = minCapacity;
|
||||||
|
|
||||||
|
T* newData = (T*)std::malloc(newCap * sizeof(T));
|
||||||
|
if (data_) {
|
||||||
|
std::memcpy(newData, data_, size_ * sizeof(T));
|
||||||
|
std::free(data_);
|
||||||
|
}
|
||||||
|
data_ = newData;
|
||||||
|
capacity_ = newCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline CreateVector() = default;
|
||||||
|
|
||||||
|
inline ~CreateVector() {
|
||||||
|
std::free(data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CreateVector(const CreateVector&) = delete;
|
||||||
|
inline CreateVector& operator=(const CreateVector&) = delete;
|
||||||
|
|
||||||
|
inline CreateVector(CreateVector&& other) noexcept
|
||||||
|
: data_(other.data_), size_(other.size_), capacity_(other.capacity_) {
|
||||||
|
other.data_ = nullptr;
|
||||||
|
other.size_ = 0;
|
||||||
|
other.capacity_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CreateVector& operator=(CreateVector&& other) noexcept {
|
||||||
|
if (this != &other) {
|
||||||
|
std::free(data_);
|
||||||
|
data_ = other.data_;
|
||||||
|
size_ = other.size_;
|
||||||
|
capacity_ = other.capacity_;
|
||||||
|
other.data_ = nullptr;
|
||||||
|
other.size_ = 0;
|
||||||
|
other.capacity_ = 0;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void push_back(const T& value) {
|
||||||
|
if (size_ == capacity_) grow(size_ + 1);
|
||||||
|
data_[size_++] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void push_back(T&& value) {
|
||||||
|
if (size_ == capacity_) grow(size_ + 1);
|
||||||
|
data_[size_++] = std::move(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void pop_back() {
|
||||||
|
assert(size_ > 0);
|
||||||
|
--size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void clear() {
|
||||||
|
size_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void resize(size_t newSize) {
|
||||||
|
if (newSize > capacity_) grow(newSize);
|
||||||
|
size_ = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void reserve(size_t newCap) {
|
||||||
|
if (newCap > capacity_) grow(newCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T& operator[](size_t index) {
|
||||||
|
assert(index < size_);
|
||||||
|
return data_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const T& operator[](size_t index) const {
|
||||||
|
assert(index < size_);
|
||||||
|
return data_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T* data() { return data_; }
|
||||||
|
inline const T* data() const { return data_; }
|
||||||
|
|
||||||
|
inline size_t size() const { return size_; }
|
||||||
|
inline size_t capacity() const { return capacity_; }
|
||||||
|
inline bool empty() const { return size_ == 0; }
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user