|
|
|
@@ -26,7 +26,7 @@ namespace ox {
|
|
|
|
|
|
|
|
|
|
namespace detail {
|
|
|
|
|
|
|
|
|
|
template<typename T, typename Allocator, std::size_t Size = 1>
|
|
|
|
|
template<typename T, typename Allocator, size_t Size = 1>
|
|
|
|
|
struct VectorAllocator {
|
|
|
|
|
static_assert(sizeof(AllocAlias<T>) == sizeof(T));
|
|
|
|
|
static_assert(alignof(AllocAlias<T>) == alignof(T));
|
|
|
|
@@ -37,7 +37,7 @@ struct VectorAllocator {
|
|
|
|
|
constexpr VectorAllocator(VectorAllocator const&) noexcept = default;
|
|
|
|
|
constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
|
|
|
|
|
|
|
|
|
|
constexpr void allocate(T **items, std::size_t const cap) noexcept {
|
|
|
|
|
constexpr void allocate(T **items, size_t const cap) noexcept {
|
|
|
|
|
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
|
|
|
|
|
if (std::is_constant_evaluated() || cap > Size) {
|
|
|
|
|
*items = Allocator{}.allocate(cap);
|
|
|
|
@@ -49,8 +49,8 @@ struct VectorAllocator {
|
|
|
|
|
constexpr void moveConstructItemsFrom(
|
|
|
|
|
T **items,
|
|
|
|
|
VectorAllocator *src,
|
|
|
|
|
std::size_t const count,
|
|
|
|
|
std::size_t const cap) noexcept {
|
|
|
|
|
size_t const count,
|
|
|
|
|
size_t const cap) noexcept {
|
|
|
|
|
// this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM,
|
|
|
|
|
// try removing it later
|
|
|
|
|
if (!std::is_constant_evaluated()) {
|
|
|
|
@@ -68,7 +68,7 @@ struct VectorAllocator {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
constexpr void deallocate(T *const items, std::size_t const cap) noexcept {
|
|
|
|
|
constexpr void deallocate(T *const items, size_t const cap) noexcept {
|
|
|
|
|
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
|
|
|
|
|
if (std::is_constant_evaluated()) {
|
|
|
|
|
if (items) {
|
|
|
|
@@ -90,7 +90,7 @@ struct VectorAllocator<T, Allocator, 0> {
|
|
|
|
|
constexpr VectorAllocator(VectorAllocator const&) noexcept = default;
|
|
|
|
|
constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
|
|
|
|
|
|
|
|
|
|
constexpr void allocate(T **items, std::size_t const cap) noexcept {
|
|
|
|
|
constexpr void allocate(T **items, size_t const cap) noexcept {
|
|
|
|
|
*items = Allocator{}.allocate(cap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -98,15 +98,15 @@ struct VectorAllocator<T, Allocator, 0> {
|
|
|
|
|
constexpr void moveConstructItemsFrom(
|
|
|
|
|
T**,
|
|
|
|
|
VectorAllocator*,
|
|
|
|
|
std::size_t const,
|
|
|
|
|
std::size_t const) noexcept {
|
|
|
|
|
size_t const,
|
|
|
|
|
size_t const) noexcept {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[maybe_unused]]
|
|
|
|
|
constexpr void moveItemsFrom(T**, VectorAllocator*, std::size_t const, std::size_t const) noexcept {
|
|
|
|
|
constexpr void moveItemsFrom(T**, VectorAllocator*, size_t const, size_t const) noexcept {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
constexpr void deallocate(T *const items, std::size_t const cap) noexcept {
|
|
|
|
|
constexpr void deallocate(T *const items, size_t const cap) noexcept {
|
|
|
|
|
if (items) {
|
|
|
|
|
Allocator{}.deallocate(items, cap);
|
|
|
|
|
}
|
|
|
|
@@ -116,12 +116,12 @@ struct VectorAllocator<T, Allocator, 0> {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize = 0, typename Allocator = std::allocator<T>>
|
|
|
|
|
template<typename T, size_t SmallVectorSize = 0, typename Allocator = std::allocator<T>>
|
|
|
|
|
class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
using value_type = T;
|
|
|
|
|
using size_type = std::size_t;
|
|
|
|
|
using size_type = size_t;
|
|
|
|
|
|
|
|
|
|
template<typename RefType = T&, typename PtrType = T*, bool reverse = false>
|
|
|
|
|
using iterator = SpanIterator<T, RefType, PtrType, reverse>;
|
|
|
|
@@ -129,18 +129,18 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
private:
|
|
|
|
|
static constexpr auto initialCap = SmallVectorSize > 0 ? SmallVectorSize : 50;
|
|
|
|
|
static constexpr auto useNoexcept = ox::is_integral_v<T> || ox::is_pointer_v<T>;
|
|
|
|
|
std::size_t m_size = 0;
|
|
|
|
|
std::size_t m_cap = 0;
|
|
|
|
|
size_t m_size = 0;
|
|
|
|
|
size_t m_cap = 0;
|
|
|
|
|
T *m_items = nullptr;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
constexpr Vector() noexcept = default;
|
|
|
|
|
|
|
|
|
|
explicit constexpr Vector(std::size_t size) noexcept;
|
|
|
|
|
explicit constexpr Vector(size_t size) noexcept;
|
|
|
|
|
|
|
|
|
|
constexpr Vector(std::initializer_list<T> list) noexcept;
|
|
|
|
|
|
|
|
|
|
constexpr Vector(const Vector &other) noexcept(useNoexcept);
|
|
|
|
|
constexpr Vector(Vector const &other) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
constexpr Vector(Vector &&other) noexcept;
|
|
|
|
|
|
|
|
|
@@ -155,23 +155,23 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr iterator<const T&, const T*> begin() const noexcept {
|
|
|
|
|
return iterator<const T&, const T*>(m_items, 0, m_size);
|
|
|
|
|
constexpr iterator<T const&, T const*> begin() const noexcept {
|
|
|
|
|
return iterator<T const&, T const*>(m_items, 0, m_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr iterator<const T&, const T*> end() const noexcept {
|
|
|
|
|
return iterator<const T&, const T*>(m_items, m_size, m_size);
|
|
|
|
|
constexpr iterator<T const&, T const*> end() const noexcept {
|
|
|
|
|
return iterator<T const&, T const*>(m_items, m_size, m_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr iterator<const T&, const T*> cbegin() const noexcept {
|
|
|
|
|
return iterator<const T&, const T*>(m_items, 0, m_size);
|
|
|
|
|
constexpr iterator<T const&, T const*> cbegin() const noexcept {
|
|
|
|
|
return iterator<T const&, T const*>(m_items, 0, m_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr iterator<const T&, const T*> cend() const noexcept {
|
|
|
|
|
return iterator<const T&, const T*>(m_items, m_size, m_size);
|
|
|
|
|
constexpr iterator<T const&, T const*> cend() const noexcept {
|
|
|
|
|
return iterator<T const&, T const*>(m_items, m_size, m_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
@@ -185,36 +185,36 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr iterator<const T&, const T*, true> crbegin() const noexcept {
|
|
|
|
|
return iterator<const T&, const T*, true>(m_items, m_size - 1, m_size);
|
|
|
|
|
constexpr iterator<T const&, T const*, true> crbegin() const noexcept {
|
|
|
|
|
return iterator<T const&, T const*, true>(m_items, m_size - 1, m_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr iterator<const T&, const T*, true> crend() const noexcept {
|
|
|
|
|
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
|
|
|
|
|
constexpr iterator<T const&, T const*, true> crend() const noexcept {
|
|
|
|
|
return iterator<T const&, T const*, true>(m_items, MaxValue<size_type>, m_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr iterator<const T&, const T*, true> rbegin() const noexcept {
|
|
|
|
|
return iterator<const T&, const T*, true>(m_items, m_size - 1, m_size);
|
|
|
|
|
constexpr iterator<T const&, T const*, true> rbegin() const noexcept {
|
|
|
|
|
return iterator<T const&, T const*, true>(m_items, m_size - 1, m_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr iterator<const T&, const T*, true> rend() const noexcept {
|
|
|
|
|
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
|
|
|
|
|
constexpr iterator<T const&, T const*, true> rend() const noexcept {
|
|
|
|
|
return iterator<T const&, T const*, true>(m_items, MaxValue<size_type>, m_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
constexpr bool operator==(const Vector &other) const noexcept(useNoexcept);
|
|
|
|
|
constexpr bool operator==(Vector const &other) const noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
constexpr Vector &operator=(const Vector &other) noexcept(useNoexcept);
|
|
|
|
|
constexpr Vector &operator=(Vector const &other) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
constexpr Vector &operator=(Vector &&other) noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr T &operator[](std::size_t i) noexcept;
|
|
|
|
|
constexpr T &operator[](size_t i) noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr const T &operator[](std::size_t i) const noexcept;
|
|
|
|
|
constexpr T const &operator[](size_t i) const noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr Result<T*> at(size_t i) noexcept;
|
|
|
|
@@ -226,28 +226,28 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
constexpr Result<T*> front() noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr Result<const T*> front() const noexcept;
|
|
|
|
|
constexpr Result<T const*> front() const noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr Result<T*> back() noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr Result<const T*> back() const noexcept;
|
|
|
|
|
constexpr Result<T const*> back() const noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr std::size_t capacity() const noexcept;
|
|
|
|
|
constexpr size_t capacity() const noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr std::size_t size() const noexcept;
|
|
|
|
|
constexpr size_t size() const noexcept;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr bool empty() const noexcept;
|
|
|
|
|
|
|
|
|
|
constexpr void clear() noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
constexpr void resize(std::size_t size) noexcept(useNoexcept);
|
|
|
|
|
constexpr void resize(size_t size) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
constexpr void reserveResize(std::size_t size) noexcept(useNoexcept);
|
|
|
|
|
constexpr void reserveResize(size_t size) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr T *data() noexcept {
|
|
|
|
@@ -255,7 +255,7 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr const T *data() const noexcept {
|
|
|
|
|
constexpr T const *data() const noexcept {
|
|
|
|
|
return m_items;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -263,12 +263,12 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
constexpr bool contains(MaybeView_t<T> const&) const noexcept;
|
|
|
|
|
|
|
|
|
|
constexpr iterator<T&, T*, false> insert(
|
|
|
|
|
std::size_t pos, std::size_t cnt, T const &val) noexcept(useNoexcept);
|
|
|
|
|
size_t pos, size_t cnt, T const &val) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
constexpr iterator<T&, T*, false> insert(std::size_t pos, T val) noexcept(useNoexcept);
|
|
|
|
|
constexpr iterator<T&, T*, false> insert(size_t pos, T val) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
template<typename... Args>
|
|
|
|
|
constexpr iterator<T&, T*, false> emplace(std::size_t pos, Args&&... args) noexcept(useNoexcept);
|
|
|
|
|
constexpr iterator<T&, T*, false> emplace(size_t pos, Args&&... args) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
template<typename... Args>
|
|
|
|
|
constexpr T &emplace_back(Args&&... args) noexcept(useNoexcept);
|
|
|
|
@@ -284,14 +284,14 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
* @param pos iterator at the point to remove
|
|
|
|
|
* @return Error if index is out of bounds
|
|
|
|
|
*/
|
|
|
|
|
constexpr Result<iterator<T&, T*, false>> erase(const iterator<> &pos) noexcept(useNoexcept);
|
|
|
|
|
constexpr Result<iterator<T&, T*, false>> erase(iterator<> const &pos) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes an item from the Vector.
|
|
|
|
|
* @param pos position of item to remove
|
|
|
|
|
* @return Error if index is out of bounds
|
|
|
|
|
*/
|
|
|
|
|
constexpr Result<iterator<T&, T*, false>> erase(std::size_t pos) noexcept(useNoexcept);
|
|
|
|
|
constexpr Result<iterator<T&, T*, false>> erase(size_t pos) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Moves the last item in the Vector to position pos and decrements the
|
|
|
|
@@ -299,59 +299,62 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|
|
|
|
* @param pos position of item to remove
|
|
|
|
|
* @return Error if index is out of bounds
|
|
|
|
|
*/
|
|
|
|
|
constexpr Error unordered_erase(std::size_t pos) noexcept(useNoexcept);
|
|
|
|
|
constexpr Error unordered_erase(size_t pos) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
constexpr Error remove(MaybeView_t<T> const &val);
|
|
|
|
|
|
|
|
|
|
constexpr void reserve(std::size_t cap) noexcept(useNoexcept);
|
|
|
|
|
constexpr void reserve(size_t cap) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
constexpr void shrink_to_fit() noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
constexpr void reserveInsert(
|
|
|
|
|
std::size_t cap, std::size_t pos, std::size_t offset = 1) noexcept(useNoexcept);
|
|
|
|
|
size_t cap, size_t pos, size_t offset = 1) noexcept(useNoexcept);
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator, typename RefType, bool reverse>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator, typename RefType, bool reverse>
|
|
|
|
|
using VectorIt = typename Vector<T, SmallVectorSize, Allocator>::template iterator<RefType, reverse>;
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator, typename RefType, bool reverse>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator, typename RefType, bool reverse>
|
|
|
|
|
constexpr VectorIt<T, SmallVectorSize, Allocator, RefType, reverse> operator+(
|
|
|
|
|
std::size_t n,
|
|
|
|
|
const VectorIt<T, SmallVectorSize, Allocator, RefType, reverse> &a) {
|
|
|
|
|
size_t n,
|
|
|
|
|
VectorIt<T, SmallVectorSize, Allocator, RefType, reverse> const &a) {
|
|
|
|
|
return a + n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::size_t size) noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(size_t const size) noexcept {
|
|
|
|
|
m_size = size;
|
|
|
|
|
m_cap = m_size;
|
|
|
|
|
this->allocate(&m_items, m_cap);
|
|
|
|
|
for (std::size_t i = 0; i < size; ++i) {
|
|
|
|
|
for (size_t i = 0; i < size; ++i) {
|
|
|
|
|
std::construct_at(&m_items[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T> list) noexcept {
|
|
|
|
|
reserve(list.size());
|
|
|
|
|
for (auto &item : list) {
|
|
|
|
|
emplace_back(std::move(item));
|
|
|
|
|
m_size = list.size();
|
|
|
|
|
m_cap = m_size;
|
|
|
|
|
this->allocate(&m_items, m_cap);
|
|
|
|
|
for (size_t i{}; auto &item : list) {
|
|
|
|
|
std::construct_at(&m_items[i], std::move(item));
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(const Vector &other) noexcept(useNoexcept) {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(Vector const &other) noexcept(useNoexcept) {
|
|
|
|
|
m_size = other.m_size;
|
|
|
|
|
m_cap = other.m_cap;
|
|
|
|
|
this->allocate(&m_items, other.m_cap);
|
|
|
|
|
for (std::size_t i = 0; i < m_size; ++i) {
|
|
|
|
|
for (size_t i = 0; i < m_size; ++i) {
|
|
|
|
|
std::construct_at(&m_items[i], other.m_items[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(Vector &&other) noexcept {
|
|
|
|
|
m_size = other.m_size;
|
|
|
|
|
m_cap = other.m_cap;
|
|
|
|
@@ -362,20 +365,20 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(Vector &&other) noexcept
|
|
|
|
|
other.m_items = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator>::~Vector() {
|
|
|
|
|
clear();
|
|
|
|
|
this->deallocate(m_items, m_cap);
|
|
|
|
|
m_items = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr bool Vector<T, SmallVectorSize, Allocator>::operator==(
|
|
|
|
|
const Vector &other) const noexcept(useNoexcept) {
|
|
|
|
|
Vector const &other) const noexcept(useNoexcept) {
|
|
|
|
|
if (m_size != other.m_size) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
for (std::size_t i = 0; i < m_size; i++) {
|
|
|
|
|
for (size_t i = 0; i < m_size; i++) {
|
|
|
|
|
if (!(m_items[i] == other.m_items[i])) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@@ -383,9 +386,9 @@ constexpr bool Vector<T, SmallVectorSize, Allocator>::operator==(
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allocator>::operator=(
|
|
|
|
|
const Vector &other) noexcept(useNoexcept) {
|
|
|
|
|
Vector const &other) noexcept(useNoexcept) {
|
|
|
|
|
if (this != &other) {
|
|
|
|
|
clear();
|
|
|
|
|
this->deallocate(m_items, m_cap);
|
|
|
|
@@ -393,14 +396,14 @@ constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allo
|
|
|
|
|
m_size = other.m_size;
|
|
|
|
|
m_cap = other.m_cap;
|
|
|
|
|
this->allocate(&m_items, other.m_cap);
|
|
|
|
|
for (std::size_t i = 0; i < m_size; i++) {
|
|
|
|
|
for (size_t i = 0; i < m_size; i++) {
|
|
|
|
|
std::construct_at(&m_items[i], other.m_items[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allocator>::operator=(
|
|
|
|
|
Vector &&other) noexcept {
|
|
|
|
|
if (this != &other) {
|
|
|
|
@@ -417,35 +420,35 @@ constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allo
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr T &Vector<T, SmallVectorSize, Allocator>::operator[](size_t const i) noexcept {
|
|
|
|
|
boundsCheck(i, size(), "Vector access overflow");
|
|
|
|
|
return m_items[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr const T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) const noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr T const &Vector<T, SmallVectorSize, Allocator>::operator[](size_t const i) const noexcept {
|
|
|
|
|
boundsCheck(i, size(), "Vector access overflow");
|
|
|
|
|
return m_items[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<T*> Vector<T, SmallVectorSize, Allocator>::at(size_t i) noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<T*> Vector<T, SmallVectorSize, Allocator>::at(size_t const i) noexcept {
|
|
|
|
|
if (i < size()) [[likely]] {
|
|
|
|
|
return &operator[](i);
|
|
|
|
|
}
|
|
|
|
|
return ox::Error(1, "Vector: Invalid index");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<T const*> Vector<T, SmallVectorSize, Allocator>::at(size_t i) const noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<T const*> Vector<T, SmallVectorSize, Allocator>::at(size_t const i) const noexcept {
|
|
|
|
|
if (i < size()) [[likely]] {
|
|
|
|
|
return &operator[](i);
|
|
|
|
|
}
|
|
|
|
|
return ox::Error(1, "Vector: Invalid index");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<T*> Vector<T, SmallVectorSize, Allocator>::front() noexcept {
|
|
|
|
|
if (!m_size) {
|
|
|
|
|
return {nullptr, ox::Error(1)};
|
|
|
|
@@ -453,15 +456,15 @@ constexpr Result<T*> Vector<T, SmallVectorSize, Allocator>::front() noexcept {
|
|
|
|
|
return &m_items[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<const T*> Vector<T, SmallVectorSize, Allocator>::front() const noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<T const*> Vector<T, SmallVectorSize, Allocator>::front() const noexcept {
|
|
|
|
|
if (!m_size) {
|
|
|
|
|
return {nullptr, ox::Error(1)};
|
|
|
|
|
}
|
|
|
|
|
return &m_items[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<T*> Vector<T, SmallVectorSize, Allocator>::back() noexcept {
|
|
|
|
|
if (!m_size) {
|
|
|
|
|
return {nullptr, ox::Error(1)};
|
|
|
|
@@ -469,65 +472,65 @@ constexpr Result<T*> Vector<T, SmallVectorSize, Allocator>::back() noexcept {
|
|
|
|
|
return &m_items[m_size - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<const T*> Vector<T, SmallVectorSize, Allocator>::back() const noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<T const*> Vector<T, SmallVectorSize, Allocator>::back() const noexcept {
|
|
|
|
|
if (!m_size) {
|
|
|
|
|
return {nullptr, ox::Error(1)};
|
|
|
|
|
}
|
|
|
|
|
return &m_items[m_size - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr std::size_t Vector<T, SmallVectorSize, Allocator>::capacity() const noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr size_t Vector<T, SmallVectorSize, Allocator>::capacity() const noexcept {
|
|
|
|
|
return m_cap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr std::size_t Vector<T, SmallVectorSize, Allocator>::size() const noexcept {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr size_t Vector<T, SmallVectorSize, Allocator>::size() const noexcept {
|
|
|
|
|
return m_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr bool Vector<T, SmallVectorSize, Allocator>::empty() const noexcept {
|
|
|
|
|
return !m_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::clear() noexcept(useNoexcept) {
|
|
|
|
|
if constexpr(is_class<T>()) {
|
|
|
|
|
for (std::size_t i = 0; i < m_size; ++i) {
|
|
|
|
|
for (size_t i = 0; i < m_size; ++i) {
|
|
|
|
|
m_items[i].~T();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_size = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::resize(std::size_t size) noexcept(useNoexcept) {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::resize(size_t const size) noexcept(useNoexcept) {
|
|
|
|
|
if (m_cap < size) {
|
|
|
|
|
reserve(size * 2);
|
|
|
|
|
}
|
|
|
|
|
if (m_size < size) {
|
|
|
|
|
for (std::size_t i = m_size; i < size; i++) {
|
|
|
|
|
for (size_t i = m_size; i < size; i++) {
|
|
|
|
|
std::construct_at(&m_items[i]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (std::size_t i = size; i < m_size; i++) {
|
|
|
|
|
for (size_t i = size; i < m_size; i++) {
|
|
|
|
|
m_items[i].~T();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_size = size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::reserveResize(std::size_t const size) noexcept(useNoexcept) {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::reserveResize(size_t const size) noexcept(useNoexcept) {
|
|
|
|
|
reserve(size);
|
|
|
|
|
resize(size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr bool Vector<T, SmallVectorSize, Allocator>::contains(MaybeView_t<T> const &v) const noexcept {
|
|
|
|
|
for (std::size_t i = 0; i < m_size; ++i) {
|
|
|
|
|
for (size_t i = 0; i < m_size; ++i) {
|
|
|
|
|
if (m_items[i] == v) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@@ -535,10 +538,10 @@ constexpr bool Vector<T, SmallVectorSize, Allocator>::contains(MaybeView_t<T> co
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::insert(
|
|
|
|
|
std::size_t pos, std::size_t cnt, T const &val) noexcept(useNoexcept) {
|
|
|
|
|
size_t const pos, size_t const cnt, T const &val) noexcept(useNoexcept) {
|
|
|
|
|
if (m_size + cnt > m_cap) {
|
|
|
|
|
reserveInsert(m_cap ? m_size + cnt : initialCap, pos, cnt);
|
|
|
|
|
}
|
|
|
|
@@ -558,9 +561,9 @@ Vector<T, SmallVectorSize, Allocator>::insert(
|
|
|
|
|
return begin() + pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, T val) noexcept(useNoexcept) {
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::insert(size_t pos, T val) noexcept(useNoexcept) {
|
|
|
|
|
if (m_size == m_cap) {
|
|
|
|
|
reserveInsert(m_cap ? m_cap * 2 : initialCap, pos);
|
|
|
|
|
}
|
|
|
|
@@ -576,10 +579,10 @@ Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, T val) noexcept(u
|
|
|
|
|
return begin() + pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename... Args>
|
|
|
|
|
constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::emplace(std::size_t pos, Args&&... args) noexcept(useNoexcept) {
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::emplace(size_t pos, Args&&... args) noexcept(useNoexcept) {
|
|
|
|
|
if (m_size == m_cap) {
|
|
|
|
|
reserveInsert(m_cap ? m_cap * 2 : initialCap, pos);
|
|
|
|
|
if (pos < m_size) {
|
|
|
|
@@ -599,7 +602,7 @@ Vector<T, SmallVectorSize, Allocator>::emplace(std::size_t pos, Args&&... args)
|
|
|
|
|
return begin() + pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename... Args>
|
|
|
|
|
constexpr T &Vector<T, SmallVectorSize, Allocator>::emplace_back(Args&&... args) noexcept(useNoexcept) {
|
|
|
|
|
if (m_size == m_cap) {
|
|
|
|
@@ -610,7 +613,7 @@ constexpr T &Vector<T, SmallVectorSize, Allocator>::emplace_back(Args&&... args)
|
|
|
|
|
return *out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::push_back(T const &item) noexcept(useNoexcept) {
|
|
|
|
|
if (m_size == m_cap) {
|
|
|
|
|
reserve(m_cap ? m_cap * 2 : initialCap);
|
|
|
|
@@ -619,7 +622,7 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::push_back(T const &item) n
|
|
|
|
|
++m_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::push_back(T &&item) noexcept(useNoexcept) {
|
|
|
|
|
if (m_size == m_cap) {
|
|
|
|
|
reserve(m_cap ? m_cap * 2 : initialCap);
|
|
|
|
@@ -628,21 +631,21 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::push_back(T &&item) noexce
|
|
|
|
|
++m_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::pop_back() noexcept(useNoexcept) {
|
|
|
|
|
--m_size;
|
|
|
|
|
m_items[m_size].~T();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>>
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::erase(const iterator<> &pos) noexcept(useNoexcept) {
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::erase(iterator<> const &pos) noexcept(useNoexcept) {
|
|
|
|
|
return erase(pos.offset());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Result<typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>>
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::erase(std::size_t pos) noexcept(useNoexcept) {
|
|
|
|
|
Vector<T, SmallVectorSize, Allocator>::erase(size_t pos) noexcept(useNoexcept) {
|
|
|
|
|
if (pos >= m_size) {
|
|
|
|
|
return ox::Error(1, "Vector::erase failed: pos is greater than Vector size");
|
|
|
|
|
}
|
|
|
|
@@ -654,8 +657,8 @@ Vector<T, SmallVectorSize, Allocator>::erase(std::size_t pos) noexcept(useNoexce
|
|
|
|
|
return begin() + pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Error Vector<T, SmallVectorSize, Allocator>::unordered_erase(std::size_t pos)
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr Error Vector<T, SmallVectorSize, Allocator>::unordered_erase(size_t pos)
|
|
|
|
|
noexcept(useNoexcept) {
|
|
|
|
|
if (pos >= m_size) {
|
|
|
|
|
return ox::Error(1);
|
|
|
|
@@ -666,7 +669,7 @@ constexpr Error Vector<T, SmallVectorSize, Allocator>::unordered_erase(std::size
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr ox::Error Vector<T, SmallVectorSize, Allocator>::remove(MaybeView_t<T> const &val) {
|
|
|
|
|
for (size_t i{}; auto const &v : *this) {
|
|
|
|
|
if (v == val) {
|
|
|
|
@@ -677,18 +680,18 @@ constexpr ox::Error Vector<T, SmallVectorSize, Allocator>::remove(MaybeView_t<T>
|
|
|
|
|
return ox::Error{1, "element not found"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) noexcept(useNoexcept) {
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(size_t cap) noexcept(useNoexcept) {
|
|
|
|
|
if (cap <= m_cap) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const auto oldItems = m_items;
|
|
|
|
|
const auto oldCap = m_cap;
|
|
|
|
|
auto const oldItems = m_items;
|
|
|
|
|
auto const oldCap = m_cap;
|
|
|
|
|
m_cap = cap;
|
|
|
|
|
this->allocate(&m_items, cap);
|
|
|
|
|
if (oldItems) { // move over old items
|
|
|
|
|
const auto itRange = ox::min(cap, m_size);
|
|
|
|
|
for (std::size_t i = 0; i < itRange; ++i) {
|
|
|
|
|
auto const itRange = ox::min(cap, m_size);
|
|
|
|
|
for (size_t i = 0; i < itRange; ++i) {
|
|
|
|
|
std::construct_at(&m_items[i], std::move(oldItems[i]));
|
|
|
|
|
oldItems[i].~T();
|
|
|
|
|
}
|
|
|
|
@@ -696,17 +699,17 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) n
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::shrink_to_fit() noexcept(useNoexcept) {
|
|
|
|
|
if (m_size == m_cap) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const auto oldItems = m_items;
|
|
|
|
|
const auto oldCap = m_cap;
|
|
|
|
|
auto const oldItems = m_items;
|
|
|
|
|
auto const oldCap = m_cap;
|
|
|
|
|
m_cap = m_size;
|
|
|
|
|
this->allocate(&m_items, m_size);
|
|
|
|
|
if (oldItems) { // move over old items
|
|
|
|
|
for (std::size_t i = 0; i < m_size; ++i) {
|
|
|
|
|
for (size_t i = 0; i < m_size; ++i) {
|
|
|
|
|
std::construct_at(&m_items[i], std::move(oldItems[i]));
|
|
|
|
|
oldItems[i].~T();
|
|
|
|
|
}
|
|
|
|
@@ -714,26 +717,26 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::shrink_to_fit() noexcept(u
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
template<typename T, size_t SmallVectorSize, typename Allocator>
|
|
|
|
|
constexpr void Vector<T, SmallVectorSize, Allocator>::reserveInsert(
|
|
|
|
|
std::size_t cap,
|
|
|
|
|
std::size_t pos,
|
|
|
|
|
std::size_t offset) noexcept(useNoexcept) {
|
|
|
|
|
size_t cap,
|
|
|
|
|
size_t pos,
|
|
|
|
|
size_t offset) noexcept(useNoexcept) {
|
|
|
|
|
if (cap <= m_cap) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const auto oldItems = m_items;
|
|
|
|
|
const auto oldCap = m_cap;
|
|
|
|
|
auto const oldItems = m_items;
|
|
|
|
|
auto const oldCap = m_cap;
|
|
|
|
|
m_cap = cap;
|
|
|
|
|
this->allocate(&m_items, cap);
|
|
|
|
|
if (oldItems) { // move over old items
|
|
|
|
|
auto itRange = ox::min(m_size, pos);
|
|
|
|
|
for (std::size_t i = 0; i < itRange; ++i) {
|
|
|
|
|
for (size_t i = 0; i < itRange; ++i) {
|
|
|
|
|
std::construct_at(&m_items[i], std::move(oldItems[i]));
|
|
|
|
|
oldItems[i].~T();
|
|
|
|
|
}
|
|
|
|
|
itRange = m_size;
|
|
|
|
|
for (std::size_t i = pos; i < itRange; ++i) {
|
|
|
|
|
for (size_t i = pos; i < itRange; ++i) {
|
|
|
|
|
std::construct_at(&m_items[i + offset], std::move(oldItems[i]));
|
|
|
|
|
oldItems[i].~T();
|
|
|
|
|
}
|
|
|
|
@@ -744,8 +747,8 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::reserveInsert(
|
|
|
|
|
|
|
|
|
|
template<typename PlatSpec, typename T>
|
|
|
|
|
[[nodiscard]]
|
|
|
|
|
constexpr auto alignOf(const Vector<T>&) noexcept {
|
|
|
|
|
const typename PlatSpec::size_t i = 0;
|
|
|
|
|
constexpr auto alignOf(Vector<T> const&) noexcept {
|
|
|
|
|
typename PlatSpec::size_t const i = 0;
|
|
|
|
|
return PlatSpec::alignOf(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|