diff --git a/include/rexy/binary.hpp b/include/rexy/binary.hpp index 58e4f6f..bc5d0fa 100644 --- a/include/rexy/binary.hpp +++ b/include/rexy/binary.hpp @@ -40,25 +40,22 @@ namespace rexy{ public: protected: constexpr binary_base(void)noexcept = default; - constexpr binary_base(char* data, size_t size)noexcept: - m_data(data), m_cap(size){} - constexpr binary_base(char* data, size_t cap, size_t size)noexcept: - m_data(data), m_size(size), m_cap(cap){} - template - binary_base(const binary_base& b)noexcept{} + constexpr binary_base(char* data, size_t size)noexcept; + constexpr binary_base(char* data, size_t cap, size_t size)noexcept; + binary_base(const binary_base& b)noexcept; ~binary_base(void)noexcept = default; public: - constexpr char* release(void)noexcept{return cx::exchange(m_data, nullptr);} + constexpr char* release(void)noexcept; - constexpr size_t size(void)const{return m_size;} - constexpr size_t capacity(void)const{return m_cap;} - constexpr char* get(void){return m_data;} - constexpr const char* get(void)const{return m_data;} - constexpr operator bool(void)const{return m_data;} + constexpr size_t size(void)const; + constexpr size_t capacity(void)const; + constexpr char* get(void); + constexpr const char* get(void)const; + constexpr operator bool(void)const; - constexpr char& operator[](size_t i)noexcept{return m_data[i];} - constexpr const char& operator[](size_t i)const noexcept{return m_data[i];} + constexpr char& operator[](size_t i)noexcept; + constexpr const char& operator[](size_t i)const noexcept; }; template> @@ -69,81 +66,31 @@ namespace rexy{ public: constexpr binary_data(void)noexcept = default; binary_data(const char* data, size_t size) - noexcept(noexcept(Allocator::copy(data, size))): - binary_base(reinterpret_cast(Allocator::copy(data, size)), size){} - constexpr binary_data(rexy::steal data, size_t size)noexcept: - binary_base(data.value(), size){} - constexpr binary_data(rexy::steal data, size_t cap, size_t size)noexcept: - binary_base(data.value(), cap, size){} + noexcept(noexcept(Allocator::copy(data, size))); + 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_base(reinterpret_cast(Allocator::copy(data, size)), cap, size){} + noexcept(noexcept(Allocator::copy(data, size))); binary_data(size_t size) - noexcept(noexcept(Allocator::allocate(size))): - binary_base(reinterpret_cast(Allocator::allocate(size)), size){} + noexcept(noexcept(Allocator::allocate(size))); 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); - } - constexpr binary_data(binary_data&& b)noexcept: - binary_base(cx::exchange(b.m_data, nullptr), b.m_cap, b.m_size){} + 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))) - { - Allocator::free(m_data); - } + 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 tmp(b); - return (*this = std::move(tmp)); - } - constexpr binary_data& operator=(binary_data&& b)noexcept{ - m_size = b.m_size; - m_cap = b.m_cap; - cx::swap(m_data, b.m_data); - return *this; - } + noexcept(noexcept(Allocator::copy(b.m_data, b.m_size))); + constexpr binary_data& operator=(binary_data&& b)noexcept; void reset(void) - noexcept(noexcept(Allocator::free(m_data))) - { - Allocator::free(m_data); - m_data = nullptr; - m_cap = m_size = 0; - } + noexcept(noexcept(Allocator::free(m_data))); void reset(char* val, size_t cap, size_t size = 0) - noexcept(noexcept(Allocator::free(m_data))) - { - Allocator::free(m_data); - m_data = val; - m_cap = cap; - m_size = size; - } + noexcept(noexcept(Allocator::free(m_data))); bool resize(size_t newsize) noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))) - { - if(newsize < m_cap) - return false; - binary_data tmp(newsize); - if(!tmp) - return false; - memcpy(STOP_STRICT_ALIAS_WARNING(tmp).m_data, m_data, m_size); - cx::swap(m_data, STOP_STRICT_ALIAS_WARNING(tmp).m_data); - m_cap = STOP_STRICT_ALIAS_WARNING(tmp).m_cap; - return true; - } + noexcept(Allocator::free(nullptr))); void append(const char* data, size_t len) noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))) - { - if(m_size + len > m_cap) - resize(cx::max(m_cap*2, m_size+len)); - memcpy(m_data+m_size, data, len); - m_size += len; - } + noexcept(Allocator::free(nullptr))); }; using binary = binary_data<>; @@ -189,6 +136,8 @@ namespace rexy{ #undef STOP_STRICT_ALIAS_WARNING +#include "binary.tpp" + #ifdef REXY_STRING_BASE_HPP #include "detail/binary_string_conv.hpp" #endif diff --git a/include/rexy/binary.tpp b/include/rexy/binary.tpp new file mode 100644 index 0000000..38c6f5f --- /dev/null +++ b/include/rexy/binary.tpp @@ -0,0 +1,162 @@ +/** + This file is a part of rexy's general purpose library + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_BINARY_TPP +#define REXY_BINARY_TPP + +#include //size_t +#include //move +#include //memcpy +#include +#include "cx/utility.hpp" //max +#include "detail/default_allocator.hpp" +#include "steal.hpp" + +#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: + m_data(data), m_size(size), m_cap(cap){} + binary_base::binary_base(const binary_base& b)noexcept{} + + constexpr char* binary_base::release(void)noexcept{ + return cx::exchange(m_data, nullptr); + } + + constexpr size_t binary_base::size(void)const{ + return m_size; + } + constexpr size_t binary_base::capacity(void)const{ + return m_cap; + } + constexpr char* binary_base::get(void){ + return m_data; + } + constexpr const char* binary_base::get(void)const{ + return m_data; + } + constexpr binary_base::operator bool(void)const{ + return m_data; + } + + constexpr char& binary_base::operator[](size_t i)noexcept{ + return m_data[i]; + } + constexpr const char& binary_base::operator[](size_t i)const noexcept{ + return m_data[i]; + } + + template + binary_data::binary_data(const char* data, size_t size) + noexcept(noexcept(Allocator::copy(data, size))): + binary_base(reinterpret_cast(Allocator::copy(data, size)), size){} + 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) + noexcept(noexcept(Allocator::copy(data, size))): + binary_base(reinterpret_cast(Allocator::copy(data, size)), cap, size){} + 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(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); + } + template + constexpr binary_data::binary_data(binary_data&& b)noexcept: + binary_base(cx::exchange(b.m_data, nullptr), b.m_cap, b.m_size){} + template + binary_data::~binary_data(void) + noexcept(noexcept(Allocator::free(m_data))) + { + Allocator::free(m_data); + } + template + 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)); + } + template + constexpr binary_data& binary_data::operator=(binary_data&& b)noexcept{ + m_size = b.m_size; + m_cap = b.m_cap; + cx::swap(m_data, b.m_data); + return *this; + } + template + void binary_data::reset(void) + noexcept(noexcept(Allocator::free(m_data))) + { + Allocator::free(m_data); + m_data = nullptr; + m_cap = m_size = 0; + } + template + void binary_data::reset(char* val, size_t cap, size_t size) + noexcept(noexcept(Allocator::free(m_data))) + { + Allocator::free(m_data); + m_data = val; + m_cap = cap; + m_size = size; + } + template + bool binary_data::resize(size_t newsize) + noexcept(noexcept(Allocator::allocate(0)) && + noexcept(Allocator::free(nullptr))) + { + if(newsize < m_cap) + return false; + binary_data tmp(newsize); + if(!tmp) + return false; + memcpy(STOP_STRICT_ALIAS_WARNING(tmp).m_data, m_data, m_size); + cx::swap(m_data, STOP_STRICT_ALIAS_WARNING(tmp).m_data); + m_cap = STOP_STRICT_ALIAS_WARNING(tmp).m_cap; + return true; + } + template + void binary_data::append(const char* data, size_t len) + noexcept(noexcept(Allocator::allocate(0)) && + noexcept(Allocator::free(nullptr))) + { + if(m_size + len > m_cap) + resize(cx::max(m_cap*2, m_size+len)); + memcpy(m_data+m_size, data, len); + m_size += len; + } + +} + +#undef STOP_STRICT_ALIAS_WARNING + +#endif