Add thin buffer wrapping class

This commit is contained in:
rexy712 2021-06-23 12:51:20 -07:00
parent a17886b706
commit 01e78a1a01
5 changed files with 272 additions and 2 deletions

View File

@ -39,7 +39,7 @@ if(BUILD_TESTS)
add_subdirectory(tests)
endif()
set(LIBREXY_PUBLIC_HEADERS "include/rexy/rexy.hpp" "include/rexy/algorithm.hpp" "include/rexy/utility.hpp" "include/rexy/basic_string_hash.hpp" "include/rexy/hash.hpp" "include/rexy/static_string_hash.hpp" "include/rexy/string_hash.hpp" "include/rexy/mpmc_queue.hpp" "include/rexy/mpmc_queue.tpp" "include/rexy/traits.hpp" "include/rexy/steal.hpp" "include/rexy/binary.hpp" "include/rexy/expression.hpp" "include/rexy/binary_base.hpp" "include/rexy/binary_base.tpp" "include/rexy/string_base.hpp" "include/rexy/string.hpp" "include/rexy/filerd.hpp" "include/rexy/string_base.tpp" "include/rexy/allocator.hpp" "include/rexy/meta.hpp")
set(LIBREXY_PUBLIC_HEADERS "include/rexy/rexy.hpp" "include/rexy/algorithm.hpp" "include/rexy/utility.hpp" "include/rexy/basic_string_hash.hpp" "include/rexy/hash.hpp" "include/rexy/static_string_hash.hpp" "include/rexy/string_hash.hpp" "include/rexy/mpmc_queue.hpp" "include/rexy/mpmc_queue.tpp" "include/rexy/traits.hpp" "include/rexy/steal.hpp" "include/rexy/binary.hpp" "include/rexy/expression.hpp" "include/rexy/binary_base.hpp" "include/rexy/binary_base.tpp" "include/rexy/string_base.hpp" "include/rexy/string.hpp" "include/rexy/filerd.hpp" "include/rexy/string_base.tpp" "include/rexy/allocator.hpp" "include/rexy/meta.hpp" "include/rexy/buffer.hpp" "include/rexy/buffer.tpp")
target_compile_options(rexy PRIVATE -Wall -Wextra -pedantic -std=c++17)
install(TARGETS rexy

97
include/rexy/buffer.hpp Normal file
View File

@ -0,0 +1,97 @@
/**
This file is a part of rexy's general purpose library
Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_BUFFER_HPP
#define REXY_BUFFER_HPP
#include "allocator.hpp"
#include "detail/hasallocator.hpp"
#include <cstdlib> //size_t, ptrdiff_t
#include <iterator> //reverse_iterator
namespace rexy{
template<class T, class Allocator = allocator<T>>
class buffer : protected detail::hasallocator<Allocator>
{
public:
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using allocator_type = Allocator;
using iterator = T*;
using const_iterator = const T*;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
protected:
pointer m_data = nullptr;
size_type m_cap = 0;
size_type m_size = 0;
public:
constexpr buffer(void);
buffer(size_type cap)noexcept(noexcept(this->allocate(0)));
buffer(const buffer& b)noexcept(noexcept(this->allocate(0)));
constexpr buffer(buffer&& b)noexcept;
~buffer(void)noexcept(noexcept(this->deallocate(nullptr, 0)));
buffer& operator=(const buffer& b)
noexcept(noexcept(this->allocate(0)) &&
noexcept(this->deallocate(nullptr, 0)));
constexpr buffer& operator=(buffer&& b)noexcept;
constexpr pointer data(void);
constexpr const_pointer data(void)const;
void resize(size_type new_cap);
constexpr void set_size(size_type size);
constexpr size_type cap(void)const;
constexpr const size_type& size(void)const;
constexpr size_type& size(void);
constexpr pointer release(void);
constexpr reference operator[](size_type i);
constexpr const_reference operator[](size_type i)const;
constexpr reference at(size_type i);
constexpr const_reference at(size_type i)const;
constexpr iterator begin(void);
constexpr const_iterator begin(void)const;
constexpr const_iterator cbegin(void)const;
constexpr iterator end(void);
constexpr const_iterator end(void)const;
constexpr const_iterator cend(void)const;
constexpr reverse_iterator rbegin(void);
constexpr const_reverse_iterator rbegin(void)const;
constexpr reverse_iterator rend(void);
constexpr const_reverse_iterator rend(void)const;
constexpr const_reverse_iterator crbegin(void)const;
constexpr const_reverse_iterator crend(void)const;
};
}
#include "buffer.tpp"
#endif

171
include/rexy/buffer.tpp Normal file
View File

@ -0,0 +1,171 @@
/**
This file is a part of rexy's general purpose library
Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_BUFFER_TPP
#define REXY_BUFFER_TPP
#include <cstring> //memcpy
#include <utility> //exchange, swap
namespace rexy{
template<class T, class Allocator>
constexpr buffer<T,Allocator>::buffer(void){}
template<class T, class Allocator>
buffer<T,Allocator>::buffer(size_type cap)noexcept(noexcept(this->allocate(0))):
m_data(this->allocate(sizeof(value_type) * cap)),
m_cap(cap),
m_size(0){}
template<class T, class Allocator>
buffer<T,Allocator>::buffer(const buffer& b)noexcept(noexcept(this->allocate(0))):
m_data(this->allocate(sizeof(value_type) * b.m_cap)),
m_cap(b.m_cap),
m_size(b.m_size)
{
memcpy(m_data, b.m_data, m_cap * sizeof(value_type));
}
template<class T, class Allocator>
constexpr buffer<T,Allocator>::buffer(buffer&& b)noexcept:
m_data(std::exchange(b.m_data, nullptr)),
m_cap(b.m_cap),
m_size(b.m_size){}
template<class T, class Allocator>
buffer<T,Allocator>::~buffer(void)noexcept(noexcept(this->deallocate(nullptr, 0))){
this->deallocate(m_data, m_cap * sizeof(value_type));
}
template<class T, class Allocator>
buffer<T,Allocator>& buffer<T,Allocator>::operator=(const buffer& b)
noexcept(noexcept(this->allocate(0)) &&
noexcept(this->deallocate(nullptr, 0)))
{
return (*this = buffer(b));
}
template<class T, class Allocator>
constexpr buffer<T,Allocator>& buffer<T,Allocator>::operator=(buffer&& b)noexcept{
std::swap(m_data, b.m_data);
m_cap = b.m_cap;
m_size = b.m_size;
return *this;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::data(void) -> pointer{
return m_data;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::data(void)const -> const_pointer{
return m_data;
}
template<class T, class Allocator>
void buffer<T,Allocator>::resize(size_type new_cap){
if(new_cap > m_cap){
buffer tmp(new_cap);
memcpy(tmp.m_data, m_data, m_cap * sizeof(value_type));
std::swap(tmp.m_data, m_data);
}
m_cap = new_cap;
}
template<class T, class Allocator>
constexpr void buffer<T,Allocator>::set_size(size_type size){
m_size = size;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::cap(void)const -> size_type{
return m_cap;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::size(void)const -> const size_type&{
return m_size;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::size(void) -> size_type&{
return m_size;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::release(void) -> pointer{
return std::exchange(m_data, nullptr);
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::operator[](size_type i) -> reference{
return m_data[i];
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::operator[](size_type i)const -> const_reference{
return m_data[i];
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::at(size_type i) -> reference{
return m_data[i];
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::at(size_type i)const -> const_reference{
return m_data[i];
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::begin(void) -> iterator{
return m_data;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::begin(void)const -> const_iterator{
return m_data;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::cbegin(void)const -> const_iterator{
return m_data;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::end(void) -> iterator{
return m_data + m_cap;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::end(void)const -> const_iterator{
return m_data + m_cap;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::cend(void)const -> const_iterator{
return m_data + m_cap;
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::rbegin(void) -> reverse_iterator{
return reverse_iterator(m_data + m_size);
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::rbegin(void)const -> const_reverse_iterator{
return const_reverse_iterator(m_data + m_size);
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::rend(void) -> reverse_iterator{
return reverse_iterator(m_data - 1);
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::rend(void)const -> const_reverse_iterator{
return const_reverse_iterator(m_data - 1);
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::crbegin(void)const -> const_reverse_iterator{
return const_reverse_iterator(m_data + m_size);
}
template<class T, class Allocator>
constexpr auto buffer<T,Allocator>::crend(void)const -> const_reverse_iterator{
return const_reverse_iterator(m_data - 1);
}
}
#endif

View File

@ -70,7 +70,7 @@ namespace rexy{
static constexpr size_type MAX_SHORT_LEN = EXTRA_SDATA_LEN+sizeof(ldata)-2;
//represent short string
struct sdata{
unsigned char islong:1; //common subsequenci with long string
unsigned char islong:1; //common subsequence with long string
unsigned char length:(CHAR_BIT-1); //take away last bit from length for islong, excludes null terminator
value_type data[MAX_SHORT_LEN+1]; //char array for string storage
constexpr sdata(void)noexcept:

View File

@ -5,6 +5,8 @@
#include "rexy/binary.hpp"
#include "rexy/binary_base.hpp"
#include "rexy/binary_base.tpp"
#include "rexy/buffer.hpp"
#include "rexy/buffer.tpp"
#include "rexy/expression.hpp"
#include "rexy/filerd.hpp"
#include "rexy/hash.hpp"