/** 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" #include "detail/string_appender.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){} constexpr binary_base::binary_base(const binary_base&)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 binary_data::binary_data(const char* data) 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) 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; } 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: static_binary(str, cx::strlen(str)){} constexpr static_binary::static_binary(const static_binary& s)noexcept: static_binary(s.get(), s.size()){} constexpr static_binary::static_binary(static_binary&& s)noexcept: static_binary(s.get(), s.size()){} constexpr static_binary& static_binary::operator=(const char* str)noexcept{ m_data = const_cast(str); m_size = cx::strlen(str); m_cap = m_size; return *this; } constexpr static_binary& static_binary::operator=(const static_binary& str)noexcept{ m_data = str.m_data; m_size = str.m_size; m_cap = str.m_cap; return *this; } constexpr static_binary& static_binary::operator=(static_binary&& str)noexcept{ m_data = str.m_data; m_size = str.m_size; m_cap = str.m_cap; return *this; } template constexpr size_t binary_cat_expr::size(void)const noexcept{ return this->m_l.size() + this->m_r.size(); } template template binary_cat_expr::operator binary_data(void) noexcept(std::is_nothrow_constructible, size_t>::value && std::is_nothrow_invocable>,decltype(*this)>::value) { auto sz = size(); binary_data ret(sz); detail::string_appender> append(ret); append(*this); return ret; } } #undef STOP_STRICT_ALIAS_WARNING #endif