[ox/std] Silently suppress small Vector in constexpr

This commit is contained in:
Gary Talent 2022-02-05 01:33:08 -06:00
parent 60b97094b0
commit 50eb01115d

View File

@ -22,25 +22,25 @@ namespace ox {
namespace detail {
template<typename T, std::size_t Size>
struct SmallVector {
struct VectorAllocator {
private:
std::allocator<T> m_allocator;
AllocAlias<T> m_data[Size] = {};
public:
SmallVector() noexcept = default;
SmallVector(SmallVector&) noexcept = default;
SmallVector(SmallVector&&) noexcept = default;
constexpr VectorAllocator() noexcept = default;
constexpr VectorAllocator(VectorAllocator&) noexcept = default;
constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
protected:
constexpr void allocate(T **items, std::size_t cap) noexcept {
if (cap <= Size) {
*items = reinterpret_cast<T*>(m_data);
} else {
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
if (std::is_constant_evaluated() || cap > Size) {
*items = m_allocator.allocate(cap);
} else {
*items = reinterpret_cast<T*>(m_data);
}
}
constexpr void moveConstructItemsFrom(T **items, SmallVector &src, const std::size_t count, const std::size_t cap) noexcept {
constexpr void moveConstructItemsFrom(T **items, VectorAllocator &src, const std::size_t count, const std::size_t cap) noexcept {
if (cap <= Size) {
const auto dstItems = reinterpret_cast<T*>(m_data);
const auto srcItems = reinterpret_cast<T*>(src.m_data);
@ -51,7 +51,7 @@ struct SmallVector {
}
}
constexpr void moveItemsFrom(T **items, SmallVector &src, const std::size_t count, const std::size_t cap) noexcept {
constexpr void moveItemsFrom(T **items, VectorAllocator &src, const std::size_t count, const std::size_t cap) noexcept {
// this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM,
// try removing it later
if (cap <= Size && count <= Size) {
@ -65,7 +65,8 @@ struct SmallVector {
}
constexpr void deallocate(T *items, std::size_t cap) noexcept {
if (items && static_cast<void*>(items) != static_cast<void*>(m_data)) {
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
if (std::is_constant_evaluated() || (items && static_cast<void*>(items) != static_cast<void*>(m_data))) {
m_allocator.deallocate(items, cap);
}
}
@ -73,24 +74,24 @@ struct SmallVector {
};
template<typename T>
struct SmallVector<T, 0> {
struct VectorAllocator<T, 0> {
private:
std::allocator<T> m_allocator;
public:
SmallVector() noexcept = default;
SmallVector(SmallVector&) noexcept = default;
SmallVector(SmallVector&&) noexcept = default;
constexpr VectorAllocator() noexcept = default;
constexpr VectorAllocator(VectorAllocator&) noexcept = default;
constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
protected:
constexpr void allocate(T **items, std::size_t cap) noexcept {
*items = m_allocator.allocate(cap);
}
[[maybe_unused]]
constexpr void moveConstructItemsFrom(T**, SmallVector&, const std::size_t, const std::size_t) noexcept {
constexpr void moveConstructItemsFrom(T**, VectorAllocator&, const std::size_t, const std::size_t) noexcept {
}
[[maybe_unused]]
constexpr void moveItemsFrom(T**, SmallVector&, const std::size_t, const std::size_t) noexcept {
constexpr void moveItemsFrom(T**, VectorAllocator&, const std::size_t, const std::size_t) noexcept {
}
constexpr void deallocate(T *items, std::size_t cap) noexcept {
@ -104,7 +105,7 @@ struct SmallVector<T, 0> {
}
template<typename T, std::size_t SmallVectorSize = 0>
class Vector: detail::SmallVector<T, SmallVectorSize> {
class Vector: detail::VectorAllocator<T, SmallVectorSize> {
public:
using value_type = T;