/** 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_HPP #define REXY_BINARY_HPP #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{ class binary_base { protected: char* m_data = nullptr; size_t m_size = 0; size_t m_cap = 0; public: 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; binary_base(const binary_base& b)noexcept; ~binary_base(void)noexcept = default; public: constexpr char* release(void)noexcept; 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; constexpr const char& operator[](size_t i)const noexcept; }; template> class binary_data : public binary_base { 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))); 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(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))); constexpr binary_data& operator=(binary_data&& b)noexcept; void reset(void) noexcept(noexcept(Allocator::free(m_data))); void reset(char* val, size_t cap, size_t size = 0) noexcept(noexcept(Allocator::free(m_data))); bool resize(size_t newsize) noexcept(noexcept(Allocator::allocate(0)) && noexcept(Allocator::free(nullptr))); void append(const char* data, size_t len) noexcept(noexcept(Allocator::allocate(0)) && noexcept(Allocator::free(nullptr))); }; using binary = binary_data<>; namespace detail{ std::true_type is_binary_type_helper(binary_base); std::false_type is_binary_type_helper(...); template struct is_binary_type{ constexpr static bool value = std::is_same::type>())),std::true_type>::value; }; template using enable_if_binary = std::enable_if_t<(is_binary_type::value && ...),int>; } template = 0> bool operator==(Left&& l, Right&& r)noexcept{ return l && r && l.size() == r.size() && l.capacity() == r.capacity() && !memcmp(l.get(), r.get(), l.size()); } template = 0> bool operator!=(Left&& l, Right&& r)noexcept{ return !(std::forward(l) == std::forward(r)); } template auto operator+(const rexy::binary_data& l, const rexy::binary_data& r) noexcept(std::is_nothrow_constructible, size_t>::value) { rexy::binary_data retval(l.size() + r.size()); memcpy(retval.get(), l.get(), l.size()); memcpy(retval.get()+l.size(), r.get(), r.size()); return retval; } template decltype(auto) operator+=(rexy::binary_data& l, const rexy::binary_data& r) noexcept(noexcept(All::allocate(0))) { l.resize(l.size() + r.size()); memcpy(l.get()+l.size(), r.get(), r.size()); return l; } } //namespace rexy #undef STOP_STRICT_ALIAS_WARNING #include "binary.tpp" #ifdef REXY_STRING_BASE_HPP #include "detail/binary_string_conv.hpp" #endif #endif