Make rexy::buffer capable of holding non trivially destructible types

This commit is contained in:
rexy712 2022-03-06 11:12:14 -08:00
parent 2e7d214660
commit f537cb8bdf
2 changed files with 44 additions and 8 deletions

View File

@ -50,6 +50,9 @@ namespace rexy{
public:
constexpr buffer(void);
buffer(const_pointer data, size_type length)noexcept(noexcept(this->allocate(0)));
template<class Iter>
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;

View File

@ -19,7 +19,6 @@
#ifndef REXY_BUFFER_TPP
#define REXY_BUFFER_TPP
#include <cstring> //memcpy
#include <utility> //exchange, swap
namespace rexy{
@ -27,6 +26,33 @@ namespace rexy{
template<class T, class Allocator>
constexpr buffer<T,Allocator>::buffer(void){}
template<class T, class Allocator>
buffer<T,Allocator>::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<class T, class Allocator>
template<class Iter>
buffer<T,Allocator>::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<class T, class Allocator>
buffer<T,Allocator>::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<class T, class Allocator>
constexpr buffer<T,Allocator>::buffer(buffer&& b)noexcept:
@ -46,6 +74,9 @@ namespace rexy{
m_size(b.m_size){}
template<class T, class Allocator>
buffer<T,Allocator>::~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<class T, class Allocator>
@ -58,8 +89,8 @@ namespace rexy{
template<class T, class Allocator>
constexpr buffer<T,Allocator>& buffer<T,Allocator>::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<class T, class Allocator>
@ -74,7 +105,9 @@ namespace rexy{
void buffer<T,Allocator>::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<class T, class Allocator>
constexpr auto buffer<T,Allocator>::end(void) -> iterator{
return m_data + m_cap;
return m_data + m_size;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::end(void)const -> const_iterator{
return m_data + m_cap;
return m_data + m_size;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::cend(void)const -> const_iterator{
return m_data + m_cap;
return m_data + m_size;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::rbegin(void) -> reverse_iterator{