diff --git a/include/rexy/binary.hpp b/include/rexy/binary.hpp index 0da9337..2f1a840 100644 --- a/include/rexy/binary.hpp +++ b/include/rexy/binary.hpp @@ -42,7 +42,7 @@ namespace rexy{ protected: constexpr binary_base(void)noexcept = default; constexpr binary_base(char* data, size_t size)noexcept; - constexpr binary_base(char* data, size_t cap, size_t size)noexcept; + constexpr binary_base(char* data, size_t size, size_t cap)noexcept; constexpr binary_base(const binary_base& b)noexcept; ~binary_base(void)noexcept = default; @@ -65,25 +65,27 @@ namespace rexy{ public: using allocator_type = Allocator; public: - constexpr binary_data(void)noexcept = default; - binary_data(const char* data, size_t size) - noexcept(noexcept(Allocator::copy(data, size))); - explicit binary_data(const char* data) - noexcept(noexcept(Allocator::copy(data, 0))); + constexpr binary_data(void)noexcept; constexpr binary_data(rexy::steal data, size_t size)noexcept; constexpr binary_data(rexy::steal data, size_t cap, size_t size)noexcept; - binary_data(const char* data, size_t cap, size_t size) - noexcept(noexcept(Allocator::copy(data, size))); - binary_data(size_t size) - noexcept(noexcept(Allocator::allocate(size))); - binary_data(const binary_data& b) - noexcept(noexcept(Allocator::copy(b.m_data, b.m_cap))); + constexpr binary_data(rexy::steal data)noexcept; + binary_data(const char* data, size_t size)noexcept(noexcept(Allocator::copy(data, size))); + binary_data(const char* data)noexcept(noexcept(Allocator::copy(data, 0))); + binary_data(const char* data, size_t size, size_t cap)noexcept(noexcept(Allocator::copy(data, size))); + explicit binary_data(size_t size)noexcept(noexcept(Allocator::allocate(size))); + binary_data(size_t size, size_t cap)noexcept(noexcept(Allocator::allocate(size))); + + binary_data(const binary_data& b)noexcept(noexcept(Allocator::copy(b.m_data, b.m_cap))); constexpr binary_data(binary_data&& b)noexcept; - ~binary_data(void) - noexcept(noexcept(Allocator::free(m_data))); - binary_data& operator=(const binary_data& b) - noexcept(noexcept(Allocator::copy(b.m_data, b.m_size))); + binary_data(const binary_base& b)noexcept(noexcept(Allocator::copy(b.get(),b.size()))); + + ~binary_data(void)noexcept(noexcept(Allocator::free(m_data))); + + binary_data& operator=(const binary_data& b)noexcept(noexcept(Allocator::copy(b.m_data, b.m_size))); constexpr binary_data& operator=(binary_data&& b)noexcept; + binary_data& operator=(const char* c)noexcept(noexcept(Allocator::copy(c, 0))); + binary_data& operator=(const binary_base& b)noexcept(noexcept(Allocator::copy(b.get(), b.size()))); + void reset(void) noexcept(noexcept(Allocator::free(m_data))); void reset(char* val, size_t cap, size_t size = 0) @@ -94,6 +96,10 @@ namespace rexy{ void append(const char* data, size_t len) noexcept(noexcept(Allocator::allocate(0)) && noexcept(Allocator::free(nullptr))); + private: + binary_data& _copy_data(const char* data, size_t len) + noexcept(noexcept(Allocator::copy(nullptr,0)) && + noexcept(Allocator::free(nullptr))); }; using binary = binary_data<>; diff --git a/include/rexy/binary.tpp b/include/rexy/binary.tpp index e68a48e..874c18a 100644 --- a/include/rexy/binary.tpp +++ b/include/rexy/binary.tpp @@ -28,13 +28,15 @@ #include "steal.hpp" #include "detail/string_appender.hpp" +#include "cx/utility.hpp" //strlen + #define STOP_STRICT_ALIAS_WARNING(x) (x) namespace rexy{ constexpr binary_base::binary_base(char* data, size_t size)noexcept: m_data(data), m_cap(size){} - constexpr binary_base::binary_base(char* data, size_t cap, size_t size)noexcept: + constexpr binary_base::binary_base(char* data, size_t size, size_t cap)noexcept: m_data(data), m_size(size), m_cap(cap){} constexpr binary_base::binary_base(const binary_base&)noexcept{} @@ -65,6 +67,22 @@ namespace rexy{ return m_data[i]; } + template + constexpr binary_data::binary_data(void)noexcept{} + template + constexpr binary_data::binary_data(rexy::steal data)noexcept: + binary_base(data.value() ? cx::strlen(data.value()) : 0) + { + m_data = data.value(); + m_size = m_cap; + } + template + constexpr binary_data::binary_data(rexy::steal data, size_t size)noexcept: + binary_base(data.value(), size){} + template + constexpr binary_data::binary_data(rexy::steal data, size_t cap, size_t size)noexcept: + binary_base(data.value(), cap, size){} + template binary_data::binary_data(const char* data, size_t size) noexcept(noexcept(Allocator::copy(data, size))): @@ -74,29 +92,27 @@ namespace rexy{ noexcept(noexcept(Allocator::copy(data, 0))): binary_data(data, cx::strlen(data)){} template - constexpr binary_data::binary_data(rexy::steal data, size_t size)noexcept: - binary_base(data.value(), size){} - template - constexpr binary_data::binary_data(rexy::steal data, size_t cap, size_t size)noexcept: - binary_base(data.value(), cap, size){} - template - binary_data::binary_data(const char* data, size_t cap, size_t size) + binary_data::binary_data(const char* data, size_t size, size_t cap) noexcept(noexcept(Allocator::copy(data, size))): - binary_base(reinterpret_cast(Allocator::copy(data, size)), cap, size){} + binary_base(reinterpret_cast(Allocator::copy(data, size)), size, cap){} template binary_data::binary_data(size_t size) noexcept(noexcept(Allocator::allocate(size))): binary_base(reinterpret_cast(Allocator::allocate(size)), size){} template + binary_data::binary_data(size_t size, size_t cap) + noexcept(noexcept(Allocator::allocate(size))): + binary_base(reinterpret_cast(size ? Allocator::allocate(size) : nullptr), size, cap){} + template binary_data::binary_data(const binary_data& b) noexcept(noexcept(Allocator::copy(b.m_data, b.m_cap))): - binary_base(b.m_data, b.m_cap, b.m_size) - { - m_data = Allocator::copy(b.m_data, b.m_cap); - } + binary_base(reinterpret_cast(b.m_size ? Allocator::copy(b.m_data, b.m_size) : nullptr), b.m_size, b.m_size){} template constexpr binary_data::binary_data(binary_data&& b)noexcept: - binary_base(cx::exchange(b.m_data, nullptr), b.m_cap, b.m_size){} + binary_base(cx::exchange(b.m_data, nullptr), b.m_size, b.m_cap){} + template + binary_data::binary_data(const binary_base& b)noexcept(noexcept(Allocator::copy(b.get(),b.size()))): + binary_base(reinterpret_cast(b.size() ? Allocator::copy(b.get(), b.size()) : nullptr), b.size(), b.size()){} template binary_data::~binary_data(void) noexcept(noexcept(Allocator::free(m_data))) @@ -107,8 +123,7 @@ namespace rexy{ binary_data& binary_data::operator=(const binary_data& b) noexcept(noexcept(Allocator::copy(b.m_data, b.m_size))) { - binary_data tmp(b); - return (*this = std::move(tmp)); + return _copy_data(b.get(), b.size()); } template constexpr binary_data& binary_data::operator=(binary_data&& b)noexcept{ @@ -118,6 +133,18 @@ namespace rexy{ return *this; } template + binary_data& binary_data::operator=(const char* c) + noexcept(noexcept(Allocator::copy(c, 0))) + { + return _copy_data(c, strlen(c)); + } + template + binary_data& binary_data::operator=(const binary_base& b) + noexcept(noexcept(Allocator::copy(b.m_data, b.m_size))) + { + return _copy_data(b.get(), b.size()); + } + template void binary_data::reset(void) noexcept(noexcept(Allocator::free(m_data))) { @@ -159,6 +186,21 @@ namespace rexy{ memcpy(m_data+m_size, data, len); m_size += len; } + template + binary_data& binary_data::_copy_data(const char* data, size_t len) + noexcept(noexcept(Allocator::copy(nullptr,0)) && + noexcept(Allocator::free(nullptr))) + { + if(!len) + return (*this = binary_data(rexy::steal(nullptr), 0, 0)); + if(len <= m_size){ + m_size = len; + memcpy(m_data, data, len); + return *this; + } + return (*this = binary_data(data, len)); + } + constexpr static_binary::static_binary(const char* str, size_t len)noexcept: binary_base(const_cast(str), len, len){} constexpr static_binary::static_binary(const char* str)noexcept: diff --git a/include/rexy/string_base.tpp b/include/rexy/string_base.tpp index 2bdd746..ddebbd6 100644 --- a/include/rexy/string_base.tpp +++ b/include/rexy/string_base.tpp @@ -81,7 +81,7 @@ namespace rexy{ template string_intermediary::string_intermediary(const string_intermediary& b) noexcept(noexcept(Allocator::copy(b.m_data, b.m_length))): - string_base(reinterpret_cast(b.m_length ? Allocator::copy(b.m_data, b.m_length+1) : nullptr), b.m_length, b.m_cap){} + string_base(reinterpret_cast(b.m_length ? Allocator::copy(b.m_data, b.m_length+1) : nullptr), b.m_length, b.m_length){} template constexpr string_intermediary::string_intermediary(string_intermediary&& s) noexcept(noexcept(cx::exchange(s.m_data, nullptr))): @@ -90,7 +90,7 @@ namespace rexy{ template string_intermediary::string_intermediary(const string_base& b) noexcept(noexcept(Allocator::copy(b.get(), b.length()))): - string_base(reinterpret_cast(b.length() ? Allocator::copy(b.get(), b.length()+1) : nullptr), b.length(), b.capacity()){} + string_base(reinterpret_cast(b.length() ? Allocator::copy(b.get(), b.length()+1) : nullptr), b.length(), b.length()){} //dtor template @@ -207,6 +207,8 @@ namespace rexy{ noexcept(noexcept(Allocator::copy(nullptr,0)) && noexcept(Allocator::free(nullptr))) { + if(!len) + return (*this = string_intermediary(rexy::steal(nullptr), 0, 0)); if(len <= m_length){ m_length = len; memcpy(m_data, s, len);