diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/kstd/include/kstd/vector | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/libs/kstd/include/kstd/vector b/libs/kstd/include/kstd/vector index 7042ff1..a49572b 100644 --- a/libs/kstd/include/kstd/vector +++ b/libs/kstd/include/kstd/vector @@ -590,16 +590,42 @@ namespace kstd //! Append a given element to this vector via copy construction. constexpr auto push_back(value_type const & value) -> void { - increase_capacity_if_full(); - std::allocator_traits<allocator_type>::construct(m_allocator, data() + size(), value); + if (m_capacity == m_size) + { + auto new_capacity = m_capacity == 0 ? 1 : m_capacity * 2; + auto new_data = allocate_n(new_capacity); + std::allocator_traits<allocator_type>::construct(m_allocator, new_data + m_size, value); + uninitialized_move_with_allocator(begin(), new_data, size()); + destroy_n(begin(), size()); + deallocate(); + m_data = new_data; + m_capacity = new_capacity; + } + else + { + std::allocator_traits<allocator_type>::construct(m_allocator, data() + size(), value); + } ++m_size; } //! Append a given element to this vector via move construction. constexpr auto push_back(value_type && value) -> void { - increase_capacity_if_full(); - std::allocator_traits<allocator_type>::construct(m_allocator, data() + size(), std::move(value)); + if (m_capacity == m_size) + { + auto new_capacity = m_capacity == 0 ? 1 : m_capacity * 2; + auto new_data = allocate_n(new_capacity); + std::allocator_traits<allocator_type>::construct(m_allocator, new_data + m_size, std::move(value)); + uninitialized_move_with_allocator(begin(), new_data, size()); + destroy_n(begin(), size()); + deallocate(); + m_data = new_data; + m_capacity = new_capacity; + } + else + { + std::allocator_traits<allocator_type>::construct(m_allocator, data() + size(), std::move(value)); + } ++m_size; } @@ -607,8 +633,21 @@ namespace kstd template<class... Args> constexpr auto emplace_back(Args &&... args) -> reference { - increase_capacity_if_full(); - std::allocator_traits<allocator_type>::construct(m_allocator, data() + size(), std::forward<Args>(args)...); + if (m_capacity == m_size) + { + auto new_capacity = m_capacity == 0 ? 1 : m_capacity * 2; + auto new_data = allocate_n(new_capacity); + std::allocator_traits<allocator_type>::construct(m_allocator, new_data + m_size, std::forward<Args>(args)...); + uninitialized_move_with_allocator(begin(), new_data, size()); + destroy_n(begin(), size()); + deallocate(); + m_data = new_data; + m_capacity = new_capacity; + } + else + { + std::allocator_traits<allocator_type>::construct(m_allocator, data() + size(), std::forward<Args>(args)...); + } ++m_size; return this->back(); } @@ -675,15 +714,6 @@ namespace kstd }); } - //! Check if there is still room in this vector, and if not allocate more space. - constexpr auto increase_capacity_if_full() -> void - { - if (m_size == m_capacity) - { - reserve(m_capacity == 0U ? 1U : m_capacity * 2U); - } - } - //! Move a number of elements from one storage location to another. //! //! @param from The start of the source range. |
