From 4cb6992178a0c64736a82208b877fe2d763c4cc0 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 14 Jan 2023 19:42:17 -0600 Subject: [PATCH] [ox/std] Add Vector::emplace --- deps/ox/src/ox/std/vector.hpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index 3712f29d..b03a9c99 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -342,9 +342,12 @@ class Vector: detail::VectorAllocator { [[nodiscard]] constexpr bool contains(const T&) const; - constexpr void insert(std::size_t pos, std::size_t cnt, const T &val); + constexpr iterator<> insert(std::size_t pos, std::size_t cnt, const T &val); - constexpr void insert(std::size_t pos, const T &val); + constexpr iterator<> insert(std::size_t pos, const T &val); + + template + constexpr iterator<> emplace(std::size_t pos, Args&&... args); template constexpr T &emplace_back(Args&&... args); @@ -571,7 +574,8 @@ constexpr bool Vector::contains(const T &v) const } template -constexpr void Vector::insert(std::size_t pos, std::size_t cnt, const T &val) { +constexpr typename Vector::template iterator<> +Vector::insert(std::size_t pos, std::size_t cnt, const T &val) { // TODO: insert should ideally have its own reserve if (m_size + cnt > m_cap) { reserve(m_cap ? m_size + cnt : initialSize); @@ -587,10 +591,12 @@ constexpr void Vector::insert(std::size_t pos, st } } ++m_size; + return begin() + pos; } template -constexpr void Vector::insert(std::size_t pos, const T &val) { +constexpr typename Vector::template iterator<> +Vector::insert(std::size_t pos, const T &val) { // TODO: insert should ideally have its own reserve if (m_size == m_cap) { reserve(m_cap ? m_cap * 2 : initialSize); @@ -604,6 +610,26 @@ constexpr void Vector::insert(std::size_t pos, co std::construct_at(&m_items[pos], val); } ++m_size; + return begin() + pos; +} + +template +template +constexpr typename Vector::template iterator<> +Vector::emplace(std::size_t pos, Args&&... args) { + // TODO: insert should ideally have its own reserve + if (m_size == m_cap) { + reserve(m_cap ? m_cap * 2 : initialSize); + } + if (pos < m_size) { + for (auto i = m_size; i > pos; --i) { + std::construct_at(&m_items[i], std::move(m_items[i - 1])); + } + m_items[pos].~T(); + } + std::construct_at(&m_items[pos], ox::forward(args)...); + ++m_size; + return begin() + pos; } template