[ox/std] Make Vector only call constructor and destructor on valid items
This commit is contained in:
parent
806eaa229a
commit
16a09d6814
34
deps/ox/src/ox/std/typetraits.hpp
vendored
34
deps/ox/src/ox/std/typetraits.hpp
vendored
@ -10,6 +10,21 @@
|
|||||||
|
|
||||||
#include "bitops.hpp"
|
#include "bitops.hpp"
|
||||||
|
|
||||||
|
#if __has_include(<type_traits>)
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool is_union_v<T> = __is_union(T);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -51,6 +66,25 @@ template<> struct is_integral<uint32_t>: ox::true_type {};
|
|||||||
template<> struct is_integral<int64_t> : ox::true_type {};
|
template<> struct is_integral<int64_t> : ox::true_type {};
|
||||||
template<> struct is_integral<uint64_t>: ox::true_type {};
|
template<> struct is_integral<uint64_t>: ox::true_type {};
|
||||||
|
|
||||||
|
template<typename T> struct is_union: ox::integral_constant<bool, std::is_union_v<T>> {};
|
||||||
|
|
||||||
|
// indicates the type can have members, but not that it necessarily does
|
||||||
|
template<typename T>
|
||||||
|
constexpr uint8_t memberable(int T::*) { return true; }
|
||||||
|
template<typename T>
|
||||||
|
constexpr uint16_t memberable(...) { return false; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_class: ox::integral_constant<bool, !ox::is_union<T>::value && ox::memberable<T>(0)> {};
|
||||||
|
|
||||||
|
namespace test {
|
||||||
|
class TestClass {int i;};
|
||||||
|
union TestUnion {int i;};
|
||||||
|
static_assert(ox::is_class<TestClass>::value == true);
|
||||||
|
static_assert(ox::is_class<TestUnion>::value == false);
|
||||||
|
static_assert(ox::is_class<int>::value == false);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr bool is_signed = ox::integral_constant<bool, T(-1) < T(0)>::value;
|
constexpr bool is_signed = ox::integral_constant<bool, T(-1) < T(0)>::value;
|
||||||
|
|
||||||
|
15
deps/ox/src/ox/std/vector.hpp
vendored
15
deps/ox/src/ox/std/vector.hpp
vendored
@ -85,7 +85,7 @@ template<typename T>
|
|||||||
Vector<T>::Vector(std::size_t size) noexcept {
|
Vector<T>::Vector(std::size_t size) noexcept {
|
||||||
m_size = size;
|
m_size = size;
|
||||||
m_cap = m_size;
|
m_cap = m_size;
|
||||||
m_items = new T[m_cap];
|
m_items = reinterpret_cast<T*>(new char[m_cap * sizeof(T)]);
|
||||||
for (std::size_t i = 0; i < size; i++) {
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
m_items[i] = {};
|
m_items[i] = {};
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ template<typename T>
|
|||||||
Vector<T>::Vector(Vector<T> &other) noexcept {
|
Vector<T>::Vector(Vector<T> &other) noexcept {
|
||||||
m_size = other.m_size;
|
m_size = other.m_size;
|
||||||
m_cap = other.m_cap;
|
m_cap = other.m_cap;
|
||||||
m_items = new T[m_cap];
|
m_items = reinterpret_cast<T*>(new char[m_cap * sizeof(T)]);
|
||||||
for (std::size_t i = 0; i < m_size; i++) {
|
for (std::size_t i = 0; i < m_size; i++) {
|
||||||
m_items[i] = ox::move(other.m_items[i]);
|
m_items[i] = ox::move(other.m_items[i]);
|
||||||
}
|
}
|
||||||
@ -113,7 +113,12 @@ Vector<T>::Vector(Vector<T> &&other) noexcept {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Vector<T>::~Vector() noexcept {
|
Vector<T>::~Vector() noexcept {
|
||||||
delete[] m_items;
|
if constexpr(ox::is_class<T>()) {
|
||||||
|
for (std::size_t i = 0; i < m_size; i++) {
|
||||||
|
m_items[i].~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] reinterpret_cast<char*>(m_items);
|
||||||
m_items = nullptr;
|
m_items = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +249,7 @@ template<typename T>
|
|||||||
void Vector<T>::expandCap(std::size_t cap) noexcept {
|
void Vector<T>::expandCap(std::size_t cap) noexcept {
|
||||||
auto oldItems = m_items;
|
auto oldItems = m_items;
|
||||||
m_cap = cap;
|
m_cap = cap;
|
||||||
m_items = new T[m_cap];
|
m_items = reinterpret_cast<T*>(new char[m_cap * sizeof(T)]);
|
||||||
if (oldItems) { // move over old items
|
if (oldItems) { // move over old items
|
||||||
const auto itRange = cap > m_size ? m_size : cap;
|
const auto itRange = cap > m_size ? m_size : cap;
|
||||||
for (std::size_t i = 0; i < itRange; i++) {
|
for (std::size_t i = 0; i < itRange; i++) {
|
||||||
@ -253,7 +258,7 @@ void Vector<T>::expandCap(std::size_t cap) noexcept {
|
|||||||
for (std::size_t i = itRange; i < m_cap; i++) {
|
for (std::size_t i = itRange; i < m_cap; i++) {
|
||||||
new (&m_items[i]) T;
|
new (&m_items[i]) T;
|
||||||
}
|
}
|
||||||
delete[] oldItems;
|
delete[] reinterpret_cast<char*>(m_items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user