[ox/std] Make Vector functions also noexcept for pointers

This commit is contained in:
Gary Talent 2023-06-25 17:21:29 -05:00
parent 696bae0721
commit 822090f309

View File

@ -236,6 +236,7 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
private: private:
static constexpr auto initialCap = SmallVectorSize > 0 ? SmallVectorSize : 50; 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_size = 0;
std::size_t m_cap = 0; std::size_t m_cap = 0;
T *m_items = nullptr; T *m_items = nullptr;
@ -247,7 +248,7 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
constexpr Vector(std::initializer_list<T> list) noexcept; constexpr Vector(std::initializer_list<T> list) noexcept;
constexpr Vector(const Vector &other) noexcept(ox::is_integral_v<T>); constexpr Vector(const Vector &other) noexcept(useNoexcept);
constexpr Vector(Vector &&other) noexcept; constexpr Vector(Vector &&other) noexcept;
@ -311,9 +312,9 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size); return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
} }
constexpr bool operator==(const Vector &other) const noexcept(ox::is_integral_v<T>); constexpr bool operator==(const Vector &other) const noexcept(useNoexcept);
constexpr Vector &operator=(const Vector &other) noexcept(ox::is_integral_v<T>); constexpr Vector &operator=(const Vector &other) noexcept(useNoexcept);
constexpr Vector &operator=(Vector &&other) noexcept; constexpr Vector &operator=(Vector &&other) noexcept;
@ -339,9 +340,9 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
[[nodiscard]] [[nodiscard]]
constexpr bool empty() const noexcept; constexpr bool empty() const noexcept;
constexpr void clear() noexcept(ox::is_integral_v<T>); constexpr void clear() noexcept(useNoexcept);
constexpr void resize(std::size_t size) noexcept(ox::is_integral_v<T>); constexpr void resize(std::size_t size) noexcept(useNoexcept);
[[nodiscard]] [[nodiscard]]
constexpr T *data() noexcept { constexpr T *data() noexcept {
@ -354,36 +355,36 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
} }
[[nodiscard]] [[nodiscard]]
constexpr bool contains(const T&) const noexcept(ox::is_integral_v<T>); constexpr bool contains(const T&) const noexcept(useNoexcept);
constexpr iterator<> insert( constexpr iterator<> insert(
std::size_t pos, std::size_t cnt, const T &val) noexcept(ox::is_integral_v<T>); std::size_t pos, std::size_t cnt, const T &val) noexcept(useNoexcept);
constexpr iterator<> insert(std::size_t pos, const T &val) noexcept(ox::is_integral_v<T>); constexpr iterator<> insert(std::size_t pos, const T &val) noexcept(useNoexcept);
template<typename... Args> template<typename... Args>
constexpr iterator<> emplace(std::size_t pos, Args&&... args) noexcept(ox::is_integral_v<T>); constexpr iterator<> emplace(std::size_t pos, Args&&... args) noexcept(useNoexcept);
template<typename... Args> template<typename... Args>
constexpr T &emplace_back(Args&&... args) noexcept(ox::is_integral_v<T>); constexpr T &emplace_back(Args&&... args) noexcept(useNoexcept);
constexpr void push_back(const T &item) noexcept(ox::is_integral_v<T>); constexpr void push_back(const T &item) noexcept(useNoexcept);
constexpr void pop_back() noexcept(ox::is_integral_v<T>); constexpr void pop_back() noexcept(useNoexcept);
/** /**
* Removes an item from the Vector. * Removes an item from the Vector.
* @param pos iterator at the point to remove * @param pos iterator at the point to remove
* @return Error if index is out of bounds * @return Error if index is out of bounds
*/ */
constexpr Result<iterator<>> erase(const iterator<> &pos) noexcept(ox::is_integral_v<T>); constexpr Result<iterator<>> erase(const iterator<> &pos) noexcept(useNoexcept);
/** /**
* Removes an item from the Vector. * Removes an item from the Vector.
* @param pos position of item to remove * @param pos position of item to remove
* @return Error if index is out of bounds * @return Error if index is out of bounds
*/ */
constexpr Result<iterator<>> erase(std::size_t pos) noexcept(ox::is_integral_v<T>); constexpr Result<iterator<>> erase(std::size_t pos) noexcept(useNoexcept);
/** /**
* Moves the last item in the Vector to position pos and decrements the * Moves the last item in the Vector to position pos and decrements the
@ -391,13 +392,13 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
* @param pos position of item to remove * @param pos position of item to remove
* @return Error if index is out of bounds * @return Error if index is out of bounds
*/ */
constexpr Error unordered_erase(std::size_t pos) noexcept(ox::is_integral_v<T>); constexpr Error unordered_erase(std::size_t pos) noexcept(useNoexcept);
constexpr void reserve(std::size_t cap) noexcept(ox::is_integral_v<T>); constexpr void reserve(std::size_t cap) noexcept(useNoexcept);
private: private:
constexpr void reserveInsert( constexpr void reserveInsert(
std::size_t cap, std::size_t pos, std::size_t offset = 1) noexcept(ox::is_integral_v<T>); std::size_t cap, std::size_t pos, std::size_t offset = 1) noexcept(useNoexcept);
}; };
@ -429,7 +430,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T>
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(const Vector &other) noexcept(ox::is_integral_v<T>) { constexpr Vector<T, SmallVectorSize, Allocator>::Vector(const Vector &other) noexcept(useNoexcept) {
m_size = other.m_size; m_size = other.m_size;
m_cap = other.m_cap; m_cap = other.m_cap;
this->allocate(&m_items, other.m_cap); this->allocate(&m_items, other.m_cap);
@ -458,7 +459,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::~Vector() {
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr bool Vector<T, SmallVectorSize, Allocator>::operator==( constexpr bool Vector<T, SmallVectorSize, Allocator>::operator==(
const Vector &other) const noexcept(ox::is_integral_v<T>) { const Vector &other) const noexcept(useNoexcept) {
if (m_size != other.m_size) { if (m_size != other.m_size) {
return false; return false;
} }
@ -472,7 +473,7 @@ constexpr bool Vector<T, SmallVectorSize, Allocator>::operator==(
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allocator>::operator=( constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allocator>::operator=(
const Vector &other) noexcept(ox::is_integral_v<T>) { const Vector &other) noexcept(useNoexcept) {
if (this != &other) { if (this != &other) {
clear(); clear();
this->deallocate(m_items, m_cap); this->deallocate(m_items, m_cap);
@ -557,7 +558,7 @@ constexpr bool Vector<T, SmallVectorSize, Allocator>::empty() const noexcept {
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr void Vector<T, SmallVectorSize, Allocator>::clear() noexcept(ox::is_integral_v<T>) { constexpr void Vector<T, SmallVectorSize, Allocator>::clear() noexcept(useNoexcept) {
if constexpr(is_class<T>()) { if constexpr(is_class<T>()) {
for (std::size_t i = 0; i < m_size; ++i) { for (std::size_t i = 0; i < m_size; ++i) {
m_items[i].~T(); m_items[i].~T();
@ -567,7 +568,7 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::clear() noexcept(ox::is_in
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr void Vector<T, SmallVectorSize, Allocator>::resize(std::size_t size) noexcept(ox::is_integral_v<T>) { constexpr void Vector<T, SmallVectorSize, Allocator>::resize(std::size_t size) noexcept(useNoexcept) {
if (m_cap < size) { if (m_cap < size) {
reserve(size * 2); reserve(size * 2);
} }
@ -584,7 +585,7 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::resize(std::size_t size) n
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr bool Vector<T, SmallVectorSize, Allocator>::contains(const T &v) const noexcept(ox::is_integral_v<T>) { constexpr bool Vector<T, SmallVectorSize, Allocator>::contains(const T &v) const noexcept(useNoexcept) {
for (std::size_t i = 0; i < m_size; i++) { for (std::size_t i = 0; i < m_size; i++) {
if (m_items[i] == v) { if (m_items[i] == v) {
return true; return true;
@ -596,7 +597,7 @@ constexpr bool Vector<T, SmallVectorSize, Allocator>::contains(const T &v) const
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<> constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<>
Vector<T, SmallVectorSize, Allocator>::insert( Vector<T, SmallVectorSize, Allocator>::insert(
std::size_t pos, std::size_t cnt, const T &val) noexcept(ox::is_integral_v<T>) { std::size_t pos, std::size_t cnt, const T &val) noexcept(useNoexcept) {
if (m_size + cnt > m_cap) { if (m_size + cnt > m_cap) {
reserveInsert(m_cap ? m_size + cnt : initialCap, pos, cnt); reserveInsert(m_cap ? m_size + cnt : initialCap, pos, cnt);
if (pos < m_size) { if (pos < m_size) {
@ -624,7 +625,7 @@ Vector<T, SmallVectorSize, Allocator>::insert(
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<> constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<>
Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, const T &val) noexcept(ox::is_integral_v<T>) { Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, const T &val) noexcept(useNoexcept) {
if (m_size == m_cap) { if (m_size == m_cap) {
reserveInsert(m_cap ? m_cap * 2 : initialCap, pos); reserveInsert(m_cap ? m_cap * 2 : initialCap, pos);
if (pos < m_size) { if (pos < m_size) {
@ -649,7 +650,7 @@ Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, const T &val) noe
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
template<typename... Args> template<typename... Args>
constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<> constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<>
Vector<T, SmallVectorSize, Allocator>::emplace(std::size_t pos, Args&&... args) noexcept(ox::is_integral_v<T>) { Vector<T, SmallVectorSize, Allocator>::emplace(std::size_t pos, Args&&... args) noexcept(useNoexcept) {
if (m_size == m_cap) { if (m_size == m_cap) {
reserveInsert(m_cap ? m_cap * 2 : initialCap); reserveInsert(m_cap ? m_cap * 2 : initialCap);
if (pos < m_size) { if (pos < m_size) {
@ -671,8 +672,7 @@ Vector<T, SmallVectorSize, Allocator>::emplace(std::size_t pos, Args&&... args)
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
template<typename... Args> template<typename... Args>
constexpr T &Vector<T, SmallVectorSize, Allocator>::emplace_back(Args&&... args) constexpr T &Vector<T, SmallVectorSize, Allocator>::emplace_back(Args&&... args) noexcept(useNoexcept) {
noexcept(ox::is_integral_v<T>) {
if (m_size == m_cap) { if (m_size == m_cap) {
reserve(m_cap ? m_cap * 2 : initialCap); reserve(m_cap ? m_cap * 2 : initialCap);
} }
@ -682,7 +682,7 @@ noexcept(ox::is_integral_v<T>) {
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr void Vector<T, SmallVectorSize, Allocator>::push_back(const T &item) noexcept(ox::is_integral_v<T>) { constexpr void Vector<T, SmallVectorSize, Allocator>::push_back(const T &item) noexcept(useNoexcept) {
if (m_size == m_cap) { if (m_size == m_cap) {
reserve(m_cap ? m_cap * 2 : initialCap); reserve(m_cap ? m_cap * 2 : initialCap);
} }
@ -691,20 +691,20 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::push_back(const T &item) n
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr void Vector<T, SmallVectorSize, Allocator>::pop_back() noexcept(ox::is_integral_v<T>) { constexpr void Vector<T, SmallVectorSize, Allocator>::pop_back() noexcept(useNoexcept) {
--m_size; --m_size;
m_items[m_size].~T(); m_items[m_size].~T();
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr Result<typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>> constexpr Result<typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>>
Vector<T, SmallVectorSize, Allocator>::erase(const iterator<> &pos) noexcept(ox::is_integral_v<T>) { Vector<T, SmallVectorSize, Allocator>::erase(const iterator<> &pos) noexcept(useNoexcept) {
return erase(pos.offset()); return erase(pos.offset());
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr Result<typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>> constexpr Result<typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>>
Vector<T, SmallVectorSize, Allocator>::erase(std::size_t pos) noexcept(ox::is_integral_v<T>) { Vector<T, SmallVectorSize, Allocator>::erase(std::size_t pos) noexcept(useNoexcept) {
if (pos >= m_size) { if (pos >= m_size) {
return OxError(1, "Vector::erase failed: pos is greater than Vector size"); return OxError(1, "Vector::erase failed: pos is greater than Vector size");
} }
@ -718,7 +718,7 @@ Vector<T, SmallVectorSize, Allocator>::erase(std::size_t pos) noexcept(ox::is_in
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr Error Vector<T, SmallVectorSize, Allocator>::unordered_erase(std::size_t pos) constexpr Error Vector<T, SmallVectorSize, Allocator>::unordered_erase(std::size_t pos)
noexcept(ox::is_integral_v<T>) { noexcept(useNoexcept) {
if (pos >= m_size) { if (pos >= m_size) {
return OxError(1); return OxError(1);
} }
@ -729,7 +729,7 @@ constexpr Error Vector<T, SmallVectorSize, Allocator>::unordered_erase(std::size
} }
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) noexcept(ox::is_integral_v<T>) { constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) noexcept(useNoexcept) {
if (cap <= m_cap) { if (cap <= m_cap) {
return; return;
} }
@ -751,7 +751,7 @@ template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr void Vector<T, SmallVectorSize, Allocator>::reserveInsert( constexpr void Vector<T, SmallVectorSize, Allocator>::reserveInsert(
std::size_t cap, std::size_t cap,
std::size_t pos, std::size_t pos,
std::size_t offset) noexcept(ox::is_integral_v<T>) { std::size_t offset) noexcept(useNoexcept) {
if (cap <= m_cap) { if (cap <= m_cap) {
return; return;
} }