#ifndef RAII_BINARY_HPP #define RAII_BINARY_HPP #include //size_t #include //move #include //memcpy #include namespace raii{ namespace detail{ template struct default_binary_allocator{ static void free(void* data){ ::operator delete(data); } static void* allocate(size_t size){ return ::operator new(size, std::align_val_t(Alignment)); } static void* copy(const void* c, size_t size){ char* tmp = reinterpret_cast(allocate(size)); memcpy(tmp, c, size); return tmp; } }; } class binary_base { protected: char* m_data = nullptr; size_t m_size = 0; size_t m_cap = 0; public: constexpr binary_base(void) = default; constexpr binary_base(char* data, size_t size): m_data(data), m_size(size){} protected: template binary_base(const binary_base& b): m_data(Allocator::copy(b.m_data, b.m_cap)), m_size(b.m_size), m_cap(b.m_cap){} binary_base(binary_base&&); public: ~binary_base(void) = default; char* release(void); 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;} char& operator[](size_t i); const char& operator[](size_t i)const; }; template> class binary : public binary_base { public: constexpr binary(void) = default; binary(char* data, size_t size): binary_base(Allocator::copy(data, size), size){} binary(size_t size): binary_base(Allocator::allocate(size), size){} binary(const binary& b): binary_base(b) { m_data = Allocator::copy(b.m_data, b.m_cap); } binary(binary&& b): binary_base(std::move(b)){} ~binary(void){ Allocator::free(m_data); } binary& operator=(const binary& b){ binary tmp(b); return (*this = std::move(tmp)); } binary& operator=(binary&& b){ m_size = b.m_size; m_cap = b.m_cap; std::swap(m_data, b.m_data); return *this; } void reset(void){ Allocator::free(m_data); m_data = nullptr; m_cap = m_size = 0; } void reset(char* val, size_t cap, size_t size = 0){ Allocator::free(m_data); m_data = val; m_cap = cap; m_size = size; } bool resize(size_t newsize){ if(newsize < m_cap) return false; binary tmp(newsize); if(!tmp) return false; memcpy(tmp.m_data, m_data, m_size); *this = std::move(tmp); return true; } }; } #endif