diff --git a/include/rexy/binary.hpp b/include/rexy/binary.hpp index 8a77353..a7b4310 100644 --- a/include/rexy/binary.hpp +++ b/include/rexy/binary.hpp @@ -24,9 +24,9 @@ namespace rexy{ - using binary = basic_binary>; + using binary = basic_binary>; - extern template class basic_binary>; + extern template class basic_binary>; } diff --git a/include/rexy/binary_base.hpp b/include/rexy/binary_base.hpp index 8da10b6..840bfdc 100644 --- a/include/rexy/binary_base.hpp +++ b/include/rexy/binary_base.hpp @@ -29,6 +29,7 @@ #include "expression.hpp" #include "traits.hpp" #include "detail/string_appender.hpp" +#include "detail/hasallocator.hpp" namespace rexy{ @@ -60,47 +61,51 @@ namespace rexy{ constexpr const char& operator[](size_t i)const noexcept; }; - template> - class basic_binary : public binary_base + template + class basic_binary : private detail::hasallocator, public binary_base { public: using allocator_type = Allocator; + public: constexpr basic_binary(void)noexcept; constexpr basic_binary(rexy::steal data, size_t size)noexcept; constexpr basic_binary(rexy::steal data, size_t cap, size_t size)noexcept; constexpr basic_binary(rexy::steal data)noexcept; - basic_binary(const char* data, size_t size)noexcept(noexcept(Allocator::copy(data, size))); - basic_binary(const char* data)noexcept(noexcept(Allocator::copy(data, 0))); - basic_binary(const char* data, size_t size, size_t cap)noexcept(noexcept(Allocator::copy(data, size))); - explicit basic_binary(size_t size)noexcept(noexcept(Allocator::allocate(size))); - basic_binary(size_t size, size_t cap)noexcept(noexcept(Allocator::allocate(size))); + basic_binary(const char* data, size_t size)noexcept(noexcept(this->allocate(0))); + basic_binary(const char* data)noexcept(noexcept(this->allocate(0))); + basic_binary(const char* data, size_t size, size_t cap)noexcept(noexcept(this->allocate(0))); + explicit basic_binary(size_t size)noexcept(noexcept(this->allocate(0))); + basic_binary(size_t size, size_t cap)noexcept(noexcept(this->allocate(0))); - basic_binary(const basic_binary& b)noexcept(noexcept(Allocator::copy(b.m_data, b.m_cap))); + basic_binary(const basic_binary& b)noexcept(noexcept(this->allocate(0))); constexpr basic_binary(basic_binary&& b)noexcept; - basic_binary(const binary_base& b)noexcept(noexcept(Allocator::copy(b.get(),b.size()))); + basic_binary(const binary_base& b)noexcept(noexcept(this->allocate(0))); - ~basic_binary(void)noexcept(noexcept(Allocator::free(m_data))); + ~basic_binary(void)noexcept(noexcept(this->deallocate(nullptr,0))); - basic_binary& operator=(const basic_binary& b)noexcept(noexcept(Allocator::copy(b.m_data, b.m_size))); + basic_binary& operator=(const basic_binary& b)noexcept(noexcept(this->allocate(0))); constexpr basic_binary& operator=(basic_binary&& b)noexcept; - basic_binary& operator=(const char* c)noexcept(noexcept(Allocator::copy(c, 0))); - basic_binary& operator=(const binary_base& b)noexcept(noexcept(Allocator::copy(b.get(), b.size()))); + basic_binary& operator=(const char* c)noexcept(noexcept(this->allocate(0))); + basic_binary& operator=(const binary_base& b)noexcept(noexcept(this->allocate(0))); void reset(void) - noexcept(noexcept(Allocator::free(m_data))); + noexcept(noexcept(this->deallocate(nullptr,0))); void reset(char* val, size_t cap, size_t size = 0) - noexcept(noexcept(Allocator::free(m_data))); + noexcept(noexcept(this->deallocate(nullptr,0))); bool resize(size_t newsize) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); void append(const char* data, size_t len) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); + + using detail::hasallocator::allocator; + private: basic_binary& _copy_data(const char* data, size_t len) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); }; template diff --git a/include/rexy/binary_base.tpp b/include/rexy/binary_base.tpp index 6a55353..3b71ce4 100644 --- a/include/rexy/binary_base.tpp +++ b/include/rexy/binary_base.tpp @@ -87,43 +87,64 @@ namespace rexy{ template basic_binary::basic_binary(const char* data, size_t size) - noexcept(noexcept(Allocator::copy(data, size))): - binary_base(reinterpret_cast(Allocator::copy(data, size)), size){} + noexcept(noexcept(this->allocate(0))): + binary_base(size ? this->allocate(size) : nullptr, size) + { + if(size) + memcpy(m_data, data, size); + } template basic_binary::basic_binary(const char* data) - noexcept(noexcept(Allocator::copy(data, 0))): - basic_binary(data, cx::strlen(data)){} + noexcept(noexcept(this->allocate(0))): + basic_binary(data ? this->allocate(cx::strlen(data)) : nullptr, cx::strlen(data)) + { + if(data) + memcpy(m_data, data, m_cap); + } template basic_binary::basic_binary(const char* data, size_t size, size_t cap) - noexcept(noexcept(Allocator::copy(data, size))): - binary_base(reinterpret_cast(Allocator::copy(data, size)), size, cap){} + noexcept(noexcept(this->allocate(0))): + binary_base(size ? this->allocate(size) : nullptr, size, cap) + { + if(size) + memcpy(m_data, data, size); + } template basic_binary::basic_binary(size_t size) - noexcept(noexcept(Allocator::allocate(size))): - binary_base(reinterpret_cast(Allocator::allocate(size)), size){} + noexcept(noexcept(this->allocate(0))): + binary_base(this->allocate(size), size){} template basic_binary::basic_binary(size_t size, size_t cap) - noexcept(noexcept(Allocator::allocate(size))): - binary_base(reinterpret_cast(size ? Allocator::allocate(size) : nullptr), size, cap){} + noexcept(noexcept(this->allocate(0))): + binary_base(size ? this->allocate(size) : nullptr, size, cap){} template basic_binary::basic_binary(const basic_binary& b) - noexcept(noexcept(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){} + noexcept(noexcept(this->allocate(0))): + binary_base(b.m_size ? this->allocate(b.m_size) : nullptr, b.m_size, b.m_size) + { + if(b.m_size) + memcpy(m_data, b.m_data, b.m_size); + } template constexpr basic_binary::basic_binary(basic_binary&& b)noexcept: binary_base(cx::exchange(b.m_data, nullptr), b.m_size, b.m_cap){} template - basic_binary::basic_binary(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()){} + basic_binary::basic_binary(const binary_base& b) + noexcept(noexcept(this->allocate(0))): + binary_base(b.size() ? this->allocate(b.size()) : nullptr, b.size(), b.size()) + { + if(b.size()) + memcpy(m_data, b.get(), b.size()); + } template basic_binary::~basic_binary(void) - noexcept(noexcept(Allocator::free(m_data))) + noexcept(noexcept(this->deallocate(nullptr,0))) { - Allocator::free(m_data); + this->deallocate(m_data, m_cap); } template basic_binary& basic_binary::operator=(const basic_binary& b) - noexcept(noexcept(Allocator::copy(b.m_data, b.m_size))) + noexcept(noexcept(this->allocate(0))) { return _copy_data(b.get(), b.size()); } @@ -136,37 +157,37 @@ namespace rexy{ } template basic_binary& basic_binary::operator=(const char* c) - noexcept(noexcept(Allocator::copy(c, 0))) + noexcept(noexcept(this->allocate(0))) { return _copy_data(c, strlen(c)); } template basic_binary& basic_binary::operator=(const binary_base& b) - noexcept(noexcept(Allocator::copy(b.get(), b.size()))) + noexcept(noexcept(this->allocate(0))) { return _copy_data(b.get(), b.size()); } template void basic_binary::reset(void) - noexcept(noexcept(Allocator::free(m_data))) + noexcept(noexcept(this->deallocate(nullptr,0))) { - Allocator::free(m_data); + this->deallocate(m_data, m_cap); m_data = nullptr; m_cap = m_size = 0; } template void basic_binary::reset(char* val, size_t cap, size_t size) - noexcept(noexcept(Allocator::free(m_data))) + noexcept(noexcept(this->deallocate(nullptr,0))) { - Allocator::free(m_data); + this->deallocate(m_data, m_cap); m_data = val; m_cap = cap; m_size = size; } template bool basic_binary::resize(size_t newsize) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { if(newsize < m_cap) return false; @@ -180,8 +201,8 @@ namespace rexy{ } template void basic_binary::append(const char* data, size_t len) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { if(m_size + len > m_cap) resize(cx::max(m_cap*2, m_size+len)); @@ -190,8 +211,8 @@ namespace rexy{ } template basic_binary& basic_binary::_copy_data(const char* data, size_t len) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { if(!len) return (*this = basic_binary(rexy::steal(nullptr), 0, 0)); diff --git a/include/rexy/detail/default_allocator.hpp b/include/rexy/detail/default_allocator.hpp index c659622..c9e35ca 100644 --- a/include/rexy/detail/default_allocator.hpp +++ b/include/rexy/detail/default_allocator.hpp @@ -20,28 +20,74 @@ #define REXY_DEFAULT_ALLOCATOR_HPP #include //size_t -#include //memcpy +#include //true_type, false_type #include namespace rexy{ namespace detail{ - template + template struct default_allocator { - static void free(void* data){ - ::operator delete(data, std::align_val_t{Alignment}); + using pointer = T*; + using const_pointer = const T*; + using void_pointer = void*; + using const_void_pointer = const void*; + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; + using is_always_equal = std::true_type; + using propagate_on_container_copy_assignment = std::false_type; + using propagate_on_container_move_assignment = std::false_type; + using propagate_on_container_swap = std::false_type; + + template + struct rebind{ + using other = default_allocator; + }; + + private: + constexpr bool has_overflow(size_type n)const{ + return n > max_size(); } - static void* allocate(size_t size){ - return ::operator new(size, std::align_val_t{Alignment}); + + public: + default_allocator(void) = default; + default_allocator(const default_allocator&) = default; + default_allocator(default_allocator&&) = default; + template + constexpr default_allocator(const default_allocator&)noexcept{} + ~default_allocator(void) = default; + + pointer allocate(size_type n){ + size_type bytes = has_overflow(n) ? size_type{-1} : n*sizeof(T); + if constexpr(alignof(T) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__){ + return reinterpret_cast(::operator new(bytes)); + }else{ + return reinterpret_cast(::operator new(bytes, static_cast(alignof(T)))); + } } - static void* copy(const void* c, size_t size){ - char* tmp = reinterpret_cast(allocate(size)); - memcpy(tmp, c, size); - return tmp; + void deallocate(pointer p, size_type n){ + size_type bytes = has_overflow(n) ? size_type{-1} : n*sizeof(T); + if constexpr(alignof(T) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__){ + ::operator delete(p, bytes); + }else{ + ::operator delete(p, bytes, static_cast(alignof(T))); + } + } + constexpr size_type max_size(void)const{ + return size_type{-1}/sizeof(T); } }; + template + constexpr bool operator==(const default_allocator&, const default_allocator&){ + return true; + } + template + constexpr bool operator!=(const default_allocator&, const default_allocator&){ + return false; + } } } diff --git a/include/rexy/detail/hasallocator.hpp b/include/rexy/detail/hasallocator.hpp new file mode 100644 index 0000000..066afbe --- /dev/null +++ b/include/rexy/detail/hasallocator.hpp @@ -0,0 +1,46 @@ +/** + 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_DETAIL_HASALLOCATOR_HPP +#define REXY_DETAIL_HASALLOCATOR_HPP + +namespace rexy::detail{ + + template + struct hasallocator + { + Alloc m_alloc; + + auto allocate(typename Alloc::size_type bytes)noexcept(noexcept(m_alloc.allocate(0))){ + return m_alloc.allocate(bytes); + } + void deallocate(typename Alloc::pointer p, typename Alloc::size_type bytes)noexcept(noexcept(m_alloc.deallocate(nullptr,0))){ + m_alloc.deallocate(p, bytes); + } + + Alloc& allocator(void){ + return m_alloc; + } + const Alloc& allocator(void)const{ + return m_alloc; + } + }; + +} + +#endif diff --git a/include/rexy/string.hpp b/include/rexy/string.hpp index b780d78..6e6d029 100644 --- a/include/rexy/string.hpp +++ b/include/rexy/string.hpp @@ -25,9 +25,9 @@ namespace rexy{ //new allocated string - using string = basic_string>; + using string = basic_string>; - extern template class basic_string>; + extern template class basic_string>; } diff --git a/include/rexy/string_base.hpp b/include/rexy/string_base.hpp index cea1525..1832c26 100644 --- a/include/rexy/string_base.hpp +++ b/include/rexy/string_base.hpp @@ -29,6 +29,7 @@ #include "traits.hpp" #include "expression.hpp" #include "detail/string_appender.hpp" +#include "detail/hasallocator.hpp" namespace rexy{ @@ -36,8 +37,8 @@ namespace rexy{ class string_base { protected: - size_t m_length = 0; - size_t m_cap = 0; + size_t m_length = 0; //length of string not including null terminator + size_t m_cap = 0; //size of current buffer not including null terminator char* m_data = nullptr; protected: @@ -77,66 +78,67 @@ namespace rexy{ //Supplies all functions that string_base can't implement template - class basic_string : public string_base + class basic_string : private detail::hasallocator, public string_base { public: using allocator_type = Allocator; private: basic_string& _copy_string(const char* s, size_t len) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); public: constexpr basic_string(void)noexcept; constexpr basic_string(rexy::steal data, size_t len)noexcept; constexpr basic_string(rexy::steal data, size_t len, size_t cap)noexcept; constexpr basic_string(rexy::steal data)noexcept; - basic_string(const char* data, size_t len)noexcept(noexcept(Allocator::copy(data,len))); - basic_string(const char* data)noexcept(noexcept(Allocator::copy(data, m_cap))); - explicit basic_string(size_t len)noexcept(noexcept(Allocator::allocate(len))); - basic_string(size_t len, size_t cap)noexcept(noexcept(Allocator::allocate(len))); + basic_string(const char* data, size_t len)noexcept(noexcept(this->allocate(data,len))); + basic_string(const char* data)noexcept(noexcept(this->allocate(data, m_cap))); + explicit basic_string(size_t len)noexcept(noexcept(this->allocate(len))); + basic_string(size_t len, size_t cap)noexcept(noexcept(this->allocate(len))); //normal copy and move ctors - basic_string(const basic_string& b)noexcept(noexcept(Allocator::copy(b.m_data, b.m_length))); + basic_string(const basic_string& b)noexcept(noexcept(this->allocate(b.m_data, b.m_length))); constexpr basic_string(basic_string&& s)noexcept(noexcept(cx::exchange(s.m_data, nullptr))); - basic_string(const string_base& b)noexcept(noexcept(Allocator::copy(b.get(), b.length()))); + basic_string(const string_base& b)noexcept(noexcept(this->allocate(b.get(), b.length()))); //dtor - ~basic_string(void)noexcept(noexcept(Allocator::free(m_data))); + ~basic_string(void)noexcept(noexcept(this->deallocate(nullptr, 0))); basic_string& operator=(const basic_string& s) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); constexpr basic_string& operator=(basic_string&& s)noexcept; //Copy from c string basic_string& operator=(const char* c) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); //Copy from other string_base basic_string& operator=(const string_base& s) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); //Replace managed pointer. Frees existing value - void reset(char* val = nullptr)noexcept(noexcept(Allocator::free(m_data))); - void reset(char* val, size_t len)noexcept(noexcept(Allocator::free(m_data))); + void reset(char* val = nullptr)noexcept(noexcept(this->deallocate(m_data))); + void reset(char* val, size_t len)noexcept(noexcept(this->deallocate(m_data))); bool resize(size_t newsize) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); void append(const char* data, size_t len) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); void append(const char* data) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); void append(const string_base& s) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))); + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))); + using detail::hasallocator::allocator; }; //Like an expression template but not really diff --git a/include/rexy/string_base.tpp b/include/rexy/string_base.tpp index ef2b9c8..da1bc4b 100644 --- a/include/rexy/string_base.tpp +++ b/include/rexy/string_base.tpp @@ -47,41 +47,51 @@ namespace rexy{ string_base(data.value(), len, cap){} template basic_string::basic_string(const char* data, size_t len) - noexcept(noexcept(Allocator::copy(data,len))): - string_base(reinterpret_cast(len ? Allocator::copy(data, len+1) : nullptr), len, len) + noexcept(noexcept(this->allocate(0))): + string_base(len ? this->allocate(len+1) : nullptr, len, len) { - m_data[len] = 0; + if(len){ + memcpy(m_data, data, len); + m_data[len] = 0; + } } template basic_string::basic_string(const char* data) - noexcept(noexcept(Allocator::copy(data, m_cap))): + noexcept(noexcept(this->allocate(0))): string_base(data ? strlen(data) : 0) { if(m_cap){ - m_data = reinterpret_cast(Allocator::copy(data, m_cap+1)); + m_data = this->allocate(m_cap+1); + memcpy(m_data, data, m_cap); m_length = m_cap; } } template basic_string::basic_string(size_t len) - noexcept(noexcept(Allocator::allocate(len))): - string_base(reinterpret_cast(len ? Allocator::allocate(len+1) : nullptr), len) + noexcept(noexcept(this->allocate(0))): + string_base(len ? this->allocate(len+1) : nullptr, len) { - m_data[len] = 0; + if(len) + m_data[len] = 0; } template basic_string::basic_string(size_t len, size_t cap) - noexcept(noexcept(Allocator::allocate(len))): - string_base(reinterpret_cast(len ? Allocator::allocate(len+1) : nullptr), len, cap) + noexcept(noexcept(this->allocate(len))): + string_base(len ? this->allocate(len+1) : nullptr, len, cap) { - m_data[len] = 0; + if(len) + m_data[len] = 0; } //normal copy and move ctors template basic_string::basic_string(const basic_string& 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_length){} + noexcept(noexcept(this->allocate(0))): + string_base(b.m_length ? this->allocate(b.m_length+1) : nullptr, b.m_length, b.m_length) + { + if(b.m_length) + memcpy(m_data, b.m_data, b.m_length+1); + } template constexpr basic_string::basic_string(basic_string&& s) noexcept(noexcept(cx::exchange(s.m_data, nullptr))): @@ -89,21 +99,25 @@ namespace rexy{ template basic_string::basic_string(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.length()){} + noexcept(noexcept(this->allocate(b.length()))): + string_base(b.length() ? this->allocate(b.length()+1) : nullptr, b.length(), b.length()) + { + if(b.length()) + memcpy(m_data, b.get(), b.length()+1); + } //dtor template basic_string::~basic_string(void) - noexcept(noexcept(Allocator::free(m_data))) + noexcept(noexcept(this->deallocate(nullptr, 0))) { - Allocator::free(m_data); + this->deallocate(m_data, m_cap+1); } template basic_string& basic_string::operator=(const basic_string& s) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr, 0))) { if(s.m_length < m_cap){ memcpy(m_data, s.m_data, s.m_length+1); @@ -123,16 +137,16 @@ namespace rexy{ //Copy from c string template basic_string& basic_string::operator=(const char* c) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { return _copy_string(c, strlen(c)); } //Copy from other string_base template basic_string& basic_string::operator=(const string_base& s) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { return _copy_string(s.get(), s.length()); } @@ -140,26 +154,26 @@ namespace rexy{ //Replace managed pointer. Frees existing value template void basic_string::reset(char* val) - noexcept(noexcept(Allocator::free(m_data))) + noexcept(noexcept(this->deallocate(m_data,0))) { - Allocator::free(m_data); + this->deallocate(m_data,m_cap+1); m_data = val; m_length = val ? strlen(val) : 0; m_cap = m_length; } template void basic_string::reset(char* val, size_t len) - noexcept(noexcept(Allocator::free(m_data))) + noexcept(noexcept(this->deallocate(m_data,0))) { - Allocator::free(m_data); + this->deallocate(m_data,m_cap+1); m_data = val; m_length = len; m_cap = len; } template bool basic_string::resize(size_t newsize) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { if(newsize < m_cap) return false; @@ -167,8 +181,8 @@ namespace rexy{ } template void basic_string::append(const char* data, size_t len) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { if(len+m_length <= m_cap){ memcpy(m_data+m_length, data, len); @@ -188,24 +202,24 @@ namespace rexy{ } template void basic_string::append(const char* data) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { if(data) append(data, strlen(data)); } template void basic_string::append(const string_base& s) - noexcept(noexcept(Allocator::allocate(0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { append(s.get(), s.length()); } template basic_string& basic_string::_copy_string(const char* s, size_t len) - noexcept(noexcept(Allocator::copy(nullptr,0)) && - noexcept(Allocator::free(nullptr))) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr,0))) { if(!len) return (*this = basic_string(rexy::steal(nullptr), 0, 0)); diff --git a/src/binary.cpp b/src/binary.cpp index 3b68d68..c7da6d6 100644 --- a/src/binary.cpp +++ b/src/binary.cpp @@ -21,6 +21,6 @@ namespace rexy{ - template class basic_binary>; + template class basic_binary>; } diff --git a/src/filerd.cpp b/src/filerd.cpp index 768006a..996cec2 100644 --- a/src/filerd.cpp +++ b/src/filerd.cpp @@ -76,9 +76,11 @@ namespace rexy{ return fread(dest, 1, bytes, m_fp); } rexy::string filerd::read(size_t bytes)noexcept{ - char* tmp = reinterpret_cast(rexy::string::allocator_type::allocate(bytes)); + rexy::string ret; + char* tmp = ret.allocator().allocate(bytes); size_t written = read(tmp, bytes); - return rexy::string(rexy::steal(tmp), written); + ret.reset(tmp, written); + return ret; } rexy::string filerd::readln(size_t max)noexcept{ rexy::string ret; @@ -95,9 +97,11 @@ namespace rexy{ rexy::binary filerd::read_bin(size_t bytes) noexcept(std::is_nothrow_constructible, size_t, size_t>::value) { - char* tmp = reinterpret_cast(rexy::binary::allocator_type::allocate(bytes)); + rexy::binary ret; + char* tmp = ret.allocator().allocate(bytes); size_t written = read(tmp, bytes); - return rexy::binary(rexy::steal(tmp), written, written); + ret.reset(tmp, written); + return ret; } size_t filerd::write(const char* c, size_t bytes)noexcept{ return fwrite(c, 1, bytes, m_fp); diff --git a/src/string.cpp b/src/string.cpp index 53e2b9b..2abbf3d 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -21,6 +21,6 @@ namespace rexy{ - template class basic_string>; + template class basic_string>; }