[ox/std] Make Vector only call constructor and destructor on valid items
This commit is contained in:
		
							
								
								
									
										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" | ||||
|  | ||||
| #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 { | ||||
|  | ||||
| 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<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> | ||||
| 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 { | ||||
| 	m_size = 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++) { | ||||
| 		m_items[i] = {}; | ||||
| 	} | ||||
| @@ -95,7 +95,7 @@ template<typename T> | ||||
| Vector<T>::Vector(Vector<T> &other) noexcept { | ||||
| 	m_size = other.m_size; | ||||
| 	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++) { | ||||
| 		m_items[i] = ox::move(other.m_items[i]); | ||||
| 	} | ||||
| @@ -113,7 +113,12 @@ Vector<T>::Vector(Vector<T> &&other) noexcept { | ||||
|  | ||||
| template<typename T> | ||||
| 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; | ||||
| } | ||||
|  | ||||
| @@ -244,7 +249,7 @@ template<typename T> | ||||
| void Vector<T>::expandCap(std::size_t cap) noexcept { | ||||
| 	auto oldItems = m_items; | ||||
| 	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 | ||||
| 		const auto itRange = cap > m_size ? m_size : cap; | ||||
| 		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++) { | ||||
| 			new (&m_items[i]) T; | ||||
| 		} | ||||
| 		delete[] oldItems; | ||||
| 		delete[] reinterpret_cast<char*>(m_items); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user