From 01e78a1a01d7c776dc1cf6a78ed6ab679f9dbe29 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Wed, 23 Jun 2021 12:51:20 -0700 Subject: [PATCH] Add thin buffer wrapping class --- CMakeLists.txt | 2 +- include/rexy/buffer.hpp | 97 ++++++++++++++++++++ include/rexy/buffer.tpp | 171 +++++++++++++++++++++++++++++++++++ include/rexy/string_base.hpp | 2 +- src/ensure.cpp | 2 + 5 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 include/rexy/buffer.hpp create mode 100644 include/rexy/buffer.tpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fa798cb..64fa6f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/rexy/buffer.hpp b/include/rexy/buffer.hpp new file mode 100644 index 0000000..86b8fb0 --- /dev/null +++ b/include/rexy/buffer.hpp @@ -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 . +*/ + +#ifndef REXY_BUFFER_HPP +#define REXY_BUFFER_HPP + +#include "allocator.hpp" +#include "detail/hasallocator.hpp" +#include //size_t, ptrdiff_t +#include //reverse_iterator + +namespace rexy{ + + template> + class buffer : protected detail::hasallocator + { + 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; + using const_reverse_iterator = std::reverse_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 diff --git a/include/rexy/buffer.tpp b/include/rexy/buffer.tpp new file mode 100644 index 0000000..c04d8a6 --- /dev/null +++ b/include/rexy/buffer.tpp @@ -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 . +*/ + +#ifndef REXY_BUFFER_TPP +#define REXY_BUFFER_TPP + +#include //memcpy +#include //exchange, swap + +namespace rexy{ + + template + constexpr buffer::buffer(void){} + template + buffer::buffer(size_type cap)noexcept(noexcept(this->allocate(0))): + m_data(this->allocate(sizeof(value_type) * cap)), + m_cap(cap), + m_size(0){} + template + buffer::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 + constexpr buffer::buffer(buffer&& b)noexcept: + m_data(std::exchange(b.m_data, nullptr)), + m_cap(b.m_cap), + m_size(b.m_size){} + template + buffer::~buffer(void)noexcept(noexcept(this->deallocate(nullptr, 0))){ + this->deallocate(m_data, m_cap * sizeof(value_type)); + } + template + buffer& buffer::operator=(const buffer& b) + noexcept(noexcept(this->allocate(0)) && + noexcept(this->deallocate(nullptr, 0))) + { + return (*this = buffer(b)); + } + template + constexpr buffer& buffer::operator=(buffer&& b)noexcept{ + std::swap(m_data, b.m_data); + m_cap = b.m_cap; + m_size = b.m_size; + return *this; + } + template + constexpr auto buffer::data(void) -> pointer{ + return m_data; + } + template + constexpr auto buffer::data(void)const -> const_pointer{ + return m_data; + } + template + void buffer::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 + constexpr void buffer::set_size(size_type size){ + m_size = size; + } + template + constexpr auto buffer::cap(void)const -> size_type{ + return m_cap; + } + template + constexpr auto buffer::size(void)const -> const size_type&{ + return m_size; + } + template + constexpr auto buffer::size(void) -> size_type&{ + return m_size; + } + template + constexpr auto buffer::release(void) -> pointer{ + return std::exchange(m_data, nullptr); + } + + template + constexpr auto buffer::operator[](size_type i) -> reference{ + return m_data[i]; + } + template + constexpr auto buffer::operator[](size_type i)const -> const_reference{ + return m_data[i]; + } + template + constexpr auto buffer::at(size_type i) -> reference{ + return m_data[i]; + } + template + constexpr auto buffer::at(size_type i)const -> const_reference{ + return m_data[i]; + } + + template + constexpr auto buffer::begin(void) -> iterator{ + return m_data; + } + template + constexpr auto buffer::begin(void)const -> const_iterator{ + return m_data; + } + template + constexpr auto buffer::cbegin(void)const -> const_iterator{ + return m_data; + } + template + constexpr auto buffer::end(void) -> iterator{ + return m_data + m_cap; + } + template + constexpr auto buffer::end(void)const -> const_iterator{ + return m_data + m_cap; + } + template + constexpr auto buffer::cend(void)const -> const_iterator{ + return m_data + m_cap; + } + template + constexpr auto buffer::rbegin(void) -> reverse_iterator{ + return reverse_iterator(m_data + m_size); + } + template + constexpr auto buffer::rbegin(void)const -> const_reverse_iterator{ + return const_reverse_iterator(m_data + m_size); + } + template + constexpr auto buffer::rend(void) -> reverse_iterator{ + return reverse_iterator(m_data - 1); + } + template + constexpr auto buffer::rend(void)const -> const_reverse_iterator{ + return const_reverse_iterator(m_data - 1); + } + template + constexpr auto buffer::crbegin(void)const -> const_reverse_iterator{ + return const_reverse_iterator(m_data + m_size); + } + template + constexpr auto buffer::crend(void)const -> const_reverse_iterator{ + return const_reverse_iterator(m_data - 1); + } + +} + +#endif diff --git a/include/rexy/string_base.hpp b/include/rexy/string_base.hpp index 8898000..011ab34 100644 --- a/include/rexy/string_base.hpp +++ b/include/rexy/string_base.hpp @@ -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: diff --git a/src/ensure.cpp b/src/ensure.cpp index 16d6baa..1d1d19f 100644 --- a/src/ensure.cpp +++ b/src/ensure.cpp @@ -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"