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"