From f537cb8bdff8a7f11a62a05fb95db6af3200d9ef Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sun, 6 Mar 2022 11:12:14 -0800 Subject: [PATCH] Make rexy::buffer capable of holding non trivially destructible types --- include/rexy/buffer.hpp | 3 +++ include/rexy/buffer.tpp | 49 ++++++++++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/include/rexy/buffer.hpp b/include/rexy/buffer.hpp index 63a02f1..a4d026e 100644 --- a/include/rexy/buffer.hpp +++ b/include/rexy/buffer.hpp @@ -50,6 +50,9 @@ namespace rexy{ public: constexpr buffer(void); + buffer(const_pointer data, size_type length)noexcept(noexcept(this->allocate(0))); + template + buffer(const Iter& start, const Iter& last); buffer(size_type cap)noexcept(noexcept(this->allocate(0))); buffer(const buffer& b)noexcept(noexcept(this->allocate(0))); constexpr buffer(buffer&& b)noexcept; diff --git a/include/rexy/buffer.tpp b/include/rexy/buffer.tpp index 4c15e32..c87358e 100644 --- a/include/rexy/buffer.tpp +++ b/include/rexy/buffer.tpp @@ -19,7 +19,6 @@ #ifndef REXY_BUFFER_TPP #define REXY_BUFFER_TPP -#include //memcpy #include //exchange, swap namespace rexy{ @@ -27,6 +26,33 @@ namespace rexy{ template constexpr buffer::buffer(void){} template + buffer::buffer(const_pointer data, size_type length)noexcept(noexcept(this->allocate(0))): + m_data(this->allocate(sizeof(value_type) * length)), + m_cap(length), + m_size(length) + { + for(size_type i = 0;i < length;++i){ + new (m_data + i) T(data[i]); + } + } + template + template + buffer::buffer(const Iter& start, const Iter& last){ + size_type count = 0; + for(auto it = start;it != end;++it){ + ++count; + } + m_data = this->allocate(sizeof(value_type) * count); + m_cap = count; + + count = 0; + for(auto it = start;it != end;++it){ + new (m_data + count) T(*it); + ++count; + } + m_size = count; + } + template buffer::buffer(size_type cap)noexcept(noexcept(this->allocate(0))): m_data(this->allocate(sizeof(value_type) * cap)), m_cap(cap), @@ -37,7 +63,9 @@ namespace rexy{ m_cap(b.m_cap), m_size(b.m_size) { - memcpy(m_data, b.m_data, m_cap * sizeof(value_type)); + for(size_type i = 0;i < b.m_size;++i){ + new (m_data + i) T(b.m_data[i]); + } } template constexpr buffer::buffer(buffer&& b)noexcept: @@ -46,6 +74,9 @@ namespace rexy{ m_size(b.m_size){} template buffer::~buffer(void)noexcept(noexcept(this->deallocate(nullptr, 0))){ + for(size_type i = 0;i < m_size;++i){ + m_data[i].~T(); + } this->deallocate(m_data, m_cap * sizeof(value_type)); } template @@ -58,8 +89,8 @@ namespace rexy{ template constexpr buffer& buffer::operator=(buffer&& b)noexcept{ std::swap(m_data, b.m_data); - m_cap = b.m_cap; - m_size = b.m_size; + std::swap(m_size, b.m_size); + std::swap(m_cap, b.m_cap); return *this; } template @@ -74,7 +105,9 @@ namespace rexy{ void buffer::resize(size_type new_cap){ if(new_cap > m_cap){ buffer tmp(new_cap); - memcpy(tmp.m_data, m_data, m_cap * sizeof(value_type)); + for(size_type i = 0;i < m_size;++i){ + new (tmp.m_data + i) T(std::move(m_data[i])); + } std::swap(tmp.m_data, m_data); } m_cap = new_cap; @@ -131,15 +164,15 @@ namespace rexy{ } template constexpr auto buffer::end(void) -> iterator{ - return m_data + m_cap; + return m_data + m_size; } template constexpr auto buffer::end(void)const -> const_iterator{ - return m_data + m_cap; + return m_data + m_size; } template constexpr auto buffer::cend(void)const -> const_iterator{ - return m_data + m_cap; + return m_data + m_size; } template constexpr auto buffer::rbegin(void) -> reverse_iterator{