2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-05 13:15:51 +00:00

rstl: Make use of variable templates where applicable

While we're at it, we can use if constexpr on some conditional checks.
This commit is contained in:
Lioncash 2019-10-04 00:14:10 -04:00
parent cbcba6f184
commit 00a4df5aa6

View File

@ -242,12 +242,12 @@ class reserved_vector : public _reserved_vector_base<T> {
const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]._value; } const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]._value; }
template <typename Tp> template <typename Tp>
static void static void
destroy(Tp& t, std::enable_if_t<std::is_destructible<Tp>::value && !std::is_trivially_destructible<Tp>::value>* = 0) { destroy(Tp& t, std::enable_if_t<std::is_destructible_v<Tp> && !std::is_trivially_destructible_v<Tp>>* = nullptr) {
t.Tp::~Tp(); t.Tp::~Tp();
} }
template <typename Tp> template <typename Tp>
static void static void
destroy(Tp& t, std::enable_if_t<!std::is_destructible<Tp>::value || std::is_trivially_destructible<Tp>::value>* = 0) { destroy(Tp& t, std::enable_if_t<!std::is_destructible_v<Tp> || std::is_trivially_destructible_v<Tp>>* = nullptr) {
} }
public: public:
@ -262,82 +262,107 @@ public:
reserved_vector(const T(&l)[LN]) reserved_vector(const T(&l)[LN])
: x0_size(LN) { : x0_size(LN) {
static_assert(LN <= N, "initializer array too large for reserved_vector"); static_assert(LN <= N, "initializer array too large for reserved_vector");
for (size_t i = 0; i < LN; ++i) for (size_t i = 0; i < LN; ++i) {
::new (static_cast<void*>(std::addressof(_value(i)))) T(l[i]); ::new (static_cast<void*>(std::addressof(_value(i)))) T(l[i]);
}
} }
reserved_vector(const reserved_vector& other) : x0_size(other.x0_size) { reserved_vector(const reserved_vector& other) : x0_size(other.x0_size) {
for (size_t i = 0; i < x0_size; ++i) for (size_t i = 0; i < x0_size; ++i) {
::new (static_cast<void*>(std::addressof(_value(i)))) T(other._value(i)); ::new (static_cast<void*>(std::addressof(_value(i)))) T(other._value(i));
}
} }
reserved_vector& operator=(const reserved_vector& other) { reserved_vector& operator=(const reserved_vector& other) {
size_t i = 0; size_t i = 0;
if (other.x0_size > x0_size) { if (other.x0_size > x0_size) {
for (; i < x0_size; ++i) for (; i < x0_size; ++i) {
_value(i) = other._value(i); _value(i) = other._value(i);
for (; i < other.x0_size; ++i) }
for (; i < other.x0_size; ++i) {
::new (static_cast<void*>(std::addressof(_value(i)))) T(other._value(i)); ::new (static_cast<void*>(std::addressof(_value(i)))) T(other._value(i));
}
} else if (other.x0_size < x0_size) { } else if (other.x0_size < x0_size) {
for (; i < other.x0_size; ++i) for (; i < other.x0_size; ++i) {
_value(i) = other._value(i); _value(i) = other._value(i);
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value) }
for (; i < x0_size; ++i)
if constexpr (std::is_destructible_v<T> && !std::is_trivially_destructible_v<T>) {
for (; i < x0_size; ++i) {
destroy(_value(i)); destroy(_value(i));
}
}
} else { } else {
for (; i < other.x0_size; ++i) for (; i < other.x0_size; ++i) {
_value(i) = other._value(i); _value(i) = other._value(i);
}
} }
x0_size = other.x0_size; x0_size = other.x0_size;
return *this; return *this;
} }
reserved_vector(reserved_vector&& other) : x0_size(other.x0_size) { reserved_vector(reserved_vector&& other) : x0_size(other.x0_size) {
for (size_t i = 0; i < x0_size; ++i) for (size_t i = 0; i < x0_size; ++i) {
::new (static_cast<void*>(std::addressof(_value(i)))) T(std::forward<T>(other._value(i))); ::new (static_cast<void*>(std::addressof(_value(i)))) T(std::forward<T>(other._value(i)));
}
} }
reserved_vector& operator=(reserved_vector&& other) { reserved_vector& operator=(reserved_vector&& other) {
size_t i = 0; size_t i = 0;
if (other.x0_size > x0_size) { if (other.x0_size > x0_size) {
for (; i < x0_size; ++i) for (; i < x0_size; ++i) {
_value(i) = std::forward<T>(other._value(i)); _value(i) = std::forward<T>(other._value(i));
for (; i < other.x0_size; ++i) }
for (; i < other.x0_size; ++i) {
::new (static_cast<void*>(std::addressof(_value(i)))) T(std::forward<T>(other._value(i))); ::new (static_cast<void*>(std::addressof(_value(i)))) T(std::forward<T>(other._value(i)));
}
} else if (other.x0_size < x0_size) { } else if (other.x0_size < x0_size) {
for (; i < other.x0_size; ++i) for (; i < other.x0_size; ++i) {
_value(i) = std::forward<T>(other._value(i)); _value(i) = std::forward<T>(other._value(i));
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value) }
for (; i < x0_size; ++i)
if constexpr (std::is_destructible_v<T> && !std::is_trivially_destructible_v<T>) {
for (; i < x0_size; ++i) {
destroy(_value(i)); destroy(_value(i));
}
}
} else { } else {
for (; i < other.x0_size; ++i) for (; i < other.x0_size; ++i) {
_value(i) = std::forward<T>(other._value(i)); _value(i) = std::forward<T>(other._value(i));
}
} }
x0_size = other.x0_size; x0_size = other.x0_size;
return *this; return *this;
} }
~reserved_vector() { ~reserved_vector() {
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value) if constexpr (std::is_destructible_v<T> && !std::is_trivially_destructible_v<T>) {
for (size_t i = 0; i < x0_size; ++i) for (size_t i = 0; i < x0_size; ++i) {
destroy(_value(i)); destroy(_value(i));
}
}
} }
void push_back(const T& d) { void push_back(const T& d) {
#ifndef NDEBUG #ifndef NDEBUG
if (x0_size == N) if (x0_size == N) {
Log.report(logvisor::Fatal, fmt("push_back() called on full rstl::reserved_vector.")); Log.report(logvisor::Fatal, fmt("push_back() called on full rstl::reserved_vector."));
}
#endif #endif
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(d); ::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(d);
++x0_size; ++x0_size;
} }
void push_back(T&& d) { void push_back(T&& d) {
#ifndef NDEBUG #ifndef NDEBUG
if (x0_size == N) if (x0_size == N) {
Log.report(logvisor::Fatal, fmt("push_back() called on full rstl::reserved_vector.")); Log.report(logvisor::Fatal, fmt("push_back() called on full rstl::reserved_vector."));
}
#endif #endif
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(d)); ::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(d));
++x0_size; ++x0_size;
} }
@ -345,34 +370,41 @@ public:
template <class... _Args> template <class... _Args>
void emplace_back(_Args&&... args) { void emplace_back(_Args&&... args) {
#ifndef NDEBUG #ifndef NDEBUG
if (x0_size == N) if (x0_size == N) {
Log.report(logvisor::Fatal, fmt("emplace_back() called on full rstl::reserved_vector.")); Log.report(logvisor::Fatal, fmt("emplace_back() called on full rstl::reserved_vector."));
}
#endif #endif
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<_Args>(args)...); ::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<_Args>(args)...);
++x0_size; ++x0_size;
} }
void pop_back() { void pop_back() {
#ifndef NDEBUG #ifndef NDEBUG
if (x0_size == 0) if (x0_size == 0) {
Log.report(logvisor::Fatal, fmt("pop_back() called on empty rstl::reserved_vector.")); Log.report(logvisor::Fatal, fmt("pop_back() called on empty rstl::reserved_vector."));
}
#endif #endif
--x0_size; --x0_size;
destroy(_value(x0_size)); destroy(_value(x0_size));
} }
iterator insert(const_iterator pos, const T& value) { iterator insert(const_iterator pos, const T& value) {
#ifndef NDEBUG #ifndef NDEBUG
if (x0_size == N) if (x0_size == N) {
Log.report(logvisor::Fatal, fmt("insert() called on full rstl::reserved_vector.")); Log.report(logvisor::Fatal, fmt("insert() called on full rstl::reserved_vector."));
}
#endif #endif
auto target_it = base::_const_cast_iterator(pos); auto target_it = base::_const_cast_iterator(pos);
if (pos == cend()) { if (pos == cend()) {
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(value); ::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(value);
} else { } else {
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(_value(x0_size - 1))); ::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(_value(x0_size - 1)));
for (auto it = end() - 1; it != target_it; --it) for (auto it = end() - 1; it != target_it; --it) {
*it = std::forward<T>(*(it - 1)); *it = std::forward<T>(*(it - 1));
}
*target_it = value; *target_it = value;
} }
++x0_size; ++x0_size;
@ -389,8 +421,9 @@ public:
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(value)); ::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(value));
} else { } else {
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(_value(x0_size - 1))); ::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(_value(x0_size - 1)));
for (auto it = end() - 1; it != target_it; --it) for (auto it = end() - 1; it != target_it; --it) {
*it = std::forward<T>(*(it - 1)); *it = std::forward<T>(*(it - 1));
}
*target_it = std::forward<T>(value); *target_it = std::forward<T>(value);
} }
++x0_size; ++x0_size;
@ -399,59 +432,75 @@ public:
void resize(size_t size) { void resize(size_t size) {
#ifndef NDEBUG #ifndef NDEBUG
if (size > N) if (size > N) {
Log.report(logvisor::Fatal, fmt("resize() call overflows rstl::reserved_vector.")); Log.report(logvisor::Fatal, fmt("resize() call overflows rstl::reserved_vector."));
}
#endif #endif
if (size > x0_size) { if (size > x0_size) {
for (size_t i = x0_size; i < size; ++i) for (size_t i = x0_size; i < size; ++i) {
::new (static_cast<void*>(std::addressof(_value(i)))) T(); ::new (static_cast<void*>(std::addressof(_value(i)))) T();
}
x0_size = size; x0_size = size;
} else if (size < x0_size) { } else if (size < x0_size) {
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value) if constexpr (std::is_destructible_v<T> && !std::is_trivially_destructible_v<T>) {
for (size_t i = size; i < x0_size; ++i) for (size_t i = size; i < x0_size; ++i) {
destroy(_value(i)); destroy(_value(i));
}
}
x0_size = size; x0_size = size;
} }
} }
void resize(size_t size, const T& value) { void resize(size_t size, const T& value) {
#ifndef NDEBUG #ifndef NDEBUG
if (size > N) if (size > N) {
Log.report(logvisor::Fatal, fmt("resize() call overflows rstl::reserved_vector.")); Log.report(logvisor::Fatal, fmt("resize() call overflows rstl::reserved_vector."));
}
#endif #endif
if (size > x0_size) { if (size > x0_size) {
for (size_t i = x0_size; i < size; ++i) for (size_t i = x0_size; i < size; ++i) {
::new (static_cast<void*>(std::addressof(_value(i)))) T(value); ::new (static_cast<void*>(std::addressof(_value(i)))) T(value);
}
x0_size = size; x0_size = size;
} else if (size < x0_size) { } else if (size < x0_size) {
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value) if constexpr (std::is_destructible_v<T> && !std::is_trivially_destructible_v<T>) {
for (size_t i = size; i < x0_size; ++i) for (size_t i = size; i < x0_size; ++i) {
destroy(_value(i)); destroy(_value(i));
}
}
x0_size = size; x0_size = size;
} }
} }
iterator erase(const_iterator pos) { iterator erase(const_iterator pos) {
#ifndef NDEBUG #ifndef NDEBUG
if (x0_size == 0) if (x0_size == 0) {
Log.report(logvisor::Fatal, fmt("erase() called on empty rstl::reserved_vector.")); Log.report(logvisor::Fatal, fmt("erase() called on empty rstl::reserved_vector."));
}
#endif #endif
for (auto it = base::_const_cast_iterator(pos) + 1; it != end(); ++it)
for (auto it = base::_const_cast_iterator(pos) + 1; it != end(); ++it) {
*(it - 1) = std::forward<T>(*it); *(it - 1) = std::forward<T>(*it);
}
--x0_size; --x0_size;
destroy(_value(x0_size)); destroy(_value(x0_size));
return base::_const_cast_iterator(pos); return base::_const_cast_iterator(pos);
} }
void pop_front() { void pop_front() {
if (x0_size != 0) if (x0_size != 0) {
erase(begin()); erase(begin());
}
} }
void clear() { void clear() {
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value) if constexpr (std::is_destructible_v<T> && !std::is_trivially_destructible_v<T>) {
for (auto it = begin(); it != end(); ++it) for (auto it = begin(); it != end(); ++it) {
destroy(*it); destroy(*it);
}
}
x0_size = 0; x0_size = 0;
} }
@ -482,15 +531,17 @@ public:
T& operator[](size_t idx) { T& operator[](size_t idx) {
#ifndef NDEBUG #ifndef NDEBUG
if (idx >= x0_size) if (idx >= x0_size) {
Log.report(logvisor::Fatal, fmt("out of bounds access on reserved_vector.")); Log.report(logvisor::Fatal, fmt("out of bounds access on reserved_vector."));
}
#endif #endif
return _value(idx); return _value(idx);
} }
const T& operator[](size_t idx) const { const T& operator[](size_t idx) const {
#ifndef NDEBUG #ifndef NDEBUG
if (idx >= x0_size) if (idx >= x0_size) {
Log.report(logvisor::Fatal, fmt("out of bounds access on reserved_vector.")); Log.report(logvisor::Fatal, fmt("out of bounds access on reserved_vector."));
}
#endif #endif
return _value(idx); return _value(idx);
} }