improve scoped_buffer, it now handles copying

v1
Brett 2023-11-05 19:05:32 -05:00
parent 15bcd37834
commit 288076ed02
1 changed files with 57 additions and 6 deletions

View File

@ -28,7 +28,7 @@
#if __cplusplus >= 202002L #if __cplusplus >= 202002L
#include <bit> #include <bit>
#define ENDIAN_LOOKUP(little_endian) (std::endian::native == std::endian::little && !little_endian) || \ #define ENDIAN_LOOKUP(little_endian) (std::endian::native == std::endian::little && !little_endian) || \
(std::endian::native == std::endian::big && little_endian) (std::endian::native == std::endian::big && little_endian)
#else #else
@ -167,8 +167,8 @@ namespace blt
* The operator * has been overloaded to return the internal buffer. * The operator * has been overloaded to return the internal buffer.
* @tparam T type that is stored in buffer eg char * @tparam T type that is stored in buffer eg char
*/ */
template<typename T> template<typename T, bool = std::is_copy_constructible_v<T> || std::is_copy_assignable_v<T>>
struct scoped_buffer class scoped_buffer
{ {
private: private:
T* _buffer; T* _buffer;
@ -182,7 +182,50 @@ namespace blt
_buffer = new T[size]; _buffer = new T[size];
} }
scoped_buffer(const scoped_buffer& copy) = delete; scoped_buffer(const scoped_buffer& copy)
{
_buffer = new T[copy.size()];
_size = copy._size;
if constexpr (std::is_trivially_copyable_v<T>)
{
std::memcpy(_buffer, copy._buffer, copy.size());
} else
{
if constexpr (std::is_copy_constructible_v<T> && !std::is_copy_assignable_v<T>)
{
for (size_t i = 0; i < this->_size; i++)
_buffer[i] = T(copy[i]);
} else
for (size_t i = 0; i < this->_size; i++)
_buffer[i] = copy[i];
}
}
scoped_buffer& operator=(const scoped_buffer& copy)
{
if (&copy == this)
return *this;
delete[] this->_buffer;
_buffer = new T[copy.size()];
_size = copy._size;
if constexpr (std::is_trivially_copyable_v<T>)
{
std::memcpy(_buffer, copy._buffer, copy.size());
} else
{
if constexpr (std::is_copy_constructible_v<T> && !std::is_copy_assignable_v<T>)
{
for (size_t i = 0; i < this->_size; i++)
_buffer[i] = T(copy[i]);
} else
for (size_t i = 0; i < this->_size; i++)
_buffer[i] = copy[i];
}
return *this;
}
scoped_buffer(scoped_buffer&& move) noexcept scoped_buffer(scoped_buffer&& move) noexcept
{ {
@ -192,8 +235,6 @@ namespace blt
move._buffer = nullptr; move._buffer = nullptr;
} }
scoped_buffer operator=(scoped_buffer& copyAssignment) = delete;
scoped_buffer& operator=(scoped_buffer&& moveAssignment) noexcept scoped_buffer& operator=(scoped_buffer&& moveAssignment) noexcept
{ {
delete[] _buffer; delete[] _buffer;
@ -260,6 +301,16 @@ namespace blt
} }
}; };
template<typename T>
class scoped_buffer<T, false> : scoped_buffer<T, true>
{
using scoped_buffer<T, true>::scoped_buffer;
public:
scoped_buffer(const scoped_buffer& copy) = delete;
scoped_buffer operator=(scoped_buffer& copyAssignment) = delete;
};
template<typename T> template<typename T>
struct nullptr_initializer struct nullptr_initializer
{ {