diff --git a/include/rexy/allocator.hpp b/include/rexy/allocator.hpp
new file mode 100644
index 0000000..4196519
--- /dev/null
+++ b/include/rexy/allocator.hpp
@@ -0,0 +1,101 @@
+/**
+ 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_DEFAULT_ALLOCATOR_HPP
+#define REXY_DEFAULT_ALLOCATOR_HPP
+
+#include //size_t
+#include //true_type, false_type
+#include
+#include //numeric_limits
+
+namespace rexy{
+
+ template
+ struct allocator
+ {
+ 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 = allocator;
+ };
+
+ private:
+ constexpr bool has_overflow(size_type n)const{
+ return n > max_size();
+ }
+
+ public:
+ allocator(void) = default;
+ allocator(const allocator&) = default;
+ allocator(allocator&&) = default;
+ template
+ constexpr allocator(const allocator&)noexcept{}
+ ~allocator(void) = default;
+
+ pointer allocate(size_type n){
+ size_type bytes = has_overflow(n) ? std::numeric_limits::max() : 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))));
+ }
+ }
+ void deallocate(pointer p, size_type n){
+#if defined(__clang__) && !defined(__cpp_sized_deallocation)
+ //clang does not enable ::operator delete(void* ptr, std::size_t sz) by default for some reason
+ if constexpr(alignof(T) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__){
+ ::operator delete(p);
+ }else{
+ ::operator delete(p, static_cast(alignof(T)));
+ }
+#else
+ size_type bytes = has_overflow(n) ? std::numeric_limits::max() : n*sizeof(T);
+ if constexpr(alignof(T) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__){
+ ::operator delete(p, bytes);
+ }else{
+ ::operator delete(p, bytes, static_cast(alignof(T)));
+ }
+#endif
+ }
+ constexpr size_type max_size(void)const{
+ return std::numeric_limits::max()/sizeof(T);
+ }
+ };
+ template
+ constexpr bool operator==(const allocator&, const allocator&){
+ return true;
+ }
+ template
+ constexpr bool operator!=(const allocator&, const allocator&){
+ return false;
+ }
+}
+
+#endif
diff --git a/include/rexy/binary.hpp b/include/rexy/binary.hpp
index a7b4310..07949df 100644
--- a/include/rexy/binary.hpp
+++ b/include/rexy/binary.hpp
@@ -20,13 +20,13 @@
#define REXY_BINARY_HPP
#include "binary_base.hpp"
-#include "detail/default_allocator.hpp"
+#include "allocator.hpp"
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 669462f..e580f64 100644
--- a/include/rexy/binary_base.hpp
+++ b/include/rexy/binary_base.hpp
@@ -24,7 +24,6 @@
#include //memcpy
#include
#include "cx/utility.hpp" //max
-#include "detail/default_allocator.hpp"
#include "steal.hpp"
#include "expression.hpp"
#include "traits.hpp"
diff --git a/include/rexy/binary_base.tpp b/include/rexy/binary_base.tpp
index 3b71ce4..d36e860 100644
--- a/include/rexy/binary_base.tpp
+++ b/include/rexy/binary_base.tpp
@@ -24,7 +24,6 @@
#include //memcpy
#include
#include "cx/utility.hpp" //max
-#include "detail/default_allocator.hpp"
#include "steal.hpp"
#include "detail/string_appender.hpp"
diff --git a/include/rexy/detail/default_allocator.hpp b/include/rexy/detail/default_allocator.hpp
deleted file mode 100644
index 08470ba..0000000
--- a/include/rexy/detail/default_allocator.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- 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_DEFAULT_ALLOCATOR_HPP
-#define REXY_DEFAULT_ALLOCATOR_HPP
-
-#include //size_t
-#include //true_type, false_type
-#include
-#include //numeric_limits
-
-namespace rexy{
-
- namespace detail{
-
- template
- struct default_allocator
- {
- 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();
- }
-
- 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) ? std::numeric_limits::max() : 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))));
- }
- }
- void deallocate(pointer p, size_type n){
-#if defined(__clang__) && !defined(__cpp_sized_deallocation)
- //clang does not enable ::operator delete(void* ptr, std::size_t sz) by default for some reason
- if constexpr(alignof(T) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__){
- ::operator delete(p);
- }else{
- ::operator delete(p, static_cast(alignof(T)));
- }
-#else
- size_type bytes = has_overflow(n) ? std::numeric_limits::max() : n*sizeof(T);
- if constexpr(alignof(T) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__){
- ::operator delete(p, bytes);
- }else{
- ::operator delete(p, bytes, static_cast(alignof(T)));
- }
-#endif
- }
- constexpr size_type max_size(void)const{
- return std::numeric_limits::max()/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;
- }
- }
-}
-
-#endif
diff --git a/include/rexy/string.hpp b/include/rexy/string.hpp
index 572e94e..1760b4e 100644
--- a/include/rexy/string.hpp
+++ b/include/rexy/string.hpp
@@ -20,17 +20,17 @@
#define REXY_STRING_HPP
#include "string_base.hpp"
-#include "detail/default_allocator.hpp"
+#include "allocator.hpp"
namespace rexy{
//new allocated string
- using string = basic_string>;
+ using string = basic_string>;
- extern template class basic_string>;
- extern template class basic_string>;
- extern template class basic_string>;
- extern template class basic_string>;
+ extern template class basic_string>;
+ extern template class 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 f7cd07c..0343edd 100644
--- a/include/rexy/string_base.hpp
+++ b/include/rexy/string_base.hpp
@@ -49,7 +49,7 @@ namespace rexy{
using iterator = pointer;
using const_iterator = const_pointer;
- protected:
+ private:
static constexpr size_type EXTRA_SDATA_LEN = 0;
struct ldata{
@@ -80,70 +80,71 @@ namespace rexy{
}m__data;
pointer m_raw = m__data.s.data;
- constexpr void set_islong_flag(bool b){
- if(b)
- m__data.l.islong = b;
- else
- m__data.s.islong = b;
- }
- constexpr bool islong(void)const{
- //common standard layout union member subsequence, never undefined behavior
- return m__data.l.islong;
- }
- constexpr pointer set_short_ptr(void){
- set_islong_flag(false);
- return m_raw = m__data.s.data;
- }
- constexpr pointer set_long_ptr(pointer ptr){
- set_islong_flag(true);
- return m_raw = ptr;
- }
- constexpr pointer get_long_ptr(void){
- return m_raw;
- }
- constexpr pointer get_short_ptr(void){
- return m_raw;
- }
- constexpr const_pointer get_long_ptr(void)const{
- return m_raw;
- }
- constexpr const_pointer get_short_ptr(void)const{
- return m_raw;
- }
- constexpr pointer get_pointer(void){
- return m_raw;
- }
- constexpr const_pointer get_pointer(void)const{
- return m_raw;
- }
- constexpr void set_long_length(size_type len){
- m__data.l.length = len;
- }
- constexpr size_type get_long_length(void)const{
- return m__data.l.length;
- }
- constexpr void set_short_length(size_type len){
- m__data.s.length = static_cast(len);
- }
- constexpr size_type get_short_length(void)const{
- return m__data.s.length;
- }
- constexpr void set_long_capacity(size_type cap){
- m__data.l.capacity = cap;
- }
- constexpr void set_short_capacity(size_type){}
- constexpr size_type get_long_capacity(void)const{
- return m__data.l.capacity;
- }
- constexpr size_type get_short_capacity(void)const{
- return MAX_SHORT_LEN;
- }
- constexpr void set_length(size_type s){
- if(islong())
- set_long_length(s);
- else
- set_short_length(s);
- }
+ protected:
+ constexpr void set_islong_flag(bool b){
+ if(b)
+ m__data.l.islong = b;
+ else
+ m__data.s.islong = b;
+ }
+ constexpr bool islong(void)const{
+ //common standard layout union member subsequence, never undefined behavior
+ return m__data.l.islong;
+ }
+ constexpr pointer set_short_ptr(void){
+ set_islong_flag(false);
+ return m_raw = m__data.s.data;
+ }
+ constexpr pointer set_long_ptr(pointer ptr){
+ set_islong_flag(true);
+ return m_raw = ptr;
+ }
+ constexpr pointer get_long_ptr(void){
+ return m_raw;
+ }
+ constexpr pointer get_short_ptr(void){
+ return m_raw;
+ }
+ constexpr const_pointer get_long_ptr(void)const{
+ return m_raw;
+ }
+ constexpr const_pointer get_short_ptr(void)const{
+ return m_raw;
+ }
+ constexpr pointer get_pointer(void){
+ return m_raw;
+ }
+ constexpr const_pointer get_pointer(void)const{
+ return m_raw;
+ }
+ constexpr void set_long_length(size_type len){
+ m__data.l.length = len;
+ }
+ constexpr size_type get_long_length(void)const{
+ return m__data.l.length;
+ }
+ constexpr void set_short_length(size_type len){
+ m__data.s.length = static_cast(len);
+ }
+ constexpr size_type get_short_length(void)const{
+ return m__data.s.length;
+ }
+ constexpr void set_long_capacity(size_type cap){
+ m__data.l.capacity = cap;
+ }
+ constexpr void set_short_capacity(size_type){}
+ constexpr size_type get_long_capacity(void)const{
+ return m__data.l.capacity;
+ }
+ constexpr size_type get_short_capacity(void)const{
+ return MAX_SHORT_LEN;
+ }
+ constexpr void set_length(size_type s){
+ if(islong())
+ set_long_length(s);
+ else
+ set_short_length(s);
+ }
protected:
constexpr string_base(void)noexcept = default;
@@ -214,6 +215,9 @@ namespace rexy{
constexpr reference operator[](size_type i)noexcept{return get_pointer()[i];}
constexpr const_reference operator[](size_type i)const noexcept{return get_pointer()[i];}
+
+ static constexpr bool uses_sso(void){return true;}
+ static constexpr size_type short_string_size(void){return MAX_SHORT_LEN;}
};
diff --git a/src/binary.cpp b/src/binary.cpp
index c7da6d6..eafd5fd 100644
--- a/src/binary.cpp
+++ b/src/binary.cpp
@@ -17,10 +17,10 @@
*/
#include "rexy/binary.hpp"
-#include "rexy/detail/default_allocator.hpp"
+#include "rexy/allocator.hpp"
namespace rexy{
- template class basic_binary>;
+ template class basic_binary>;
}
diff --git a/src/ensure.cpp b/src/ensure.cpp
index 7204ec3..fb21de5 100644
--- a/src/ensure.cpp
+++ b/src/ensure.cpp
@@ -12,7 +12,7 @@
#include "rexy/traits.hpp"
#include "rexy/detail/binary_string_conv.hpp"
-#include "rexy/detail/default_allocator.hpp"
+#include "rexy/allocator.hpp"
#include "rexy/detail/string_appender.hpp"
#include "rexy/cx/algorithm.hpp"
diff --git a/src/string.cpp b/src/string.cpp
index 8a3f0e9..62fb6bb 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -17,13 +17,13 @@
*/
#include "rexy/string.hpp"
-#include "rexy/detail/default_allocator.hpp"
+#include "rexy/allocator.hpp"
namespace rexy{
- template class basic_string>;
- template class basic_string>;
- template class basic_string>;
- template class basic_string>;
+ template class basic_string>;
+ template class basic_string>;
+ template class basic_string>;
+ template class basic_string>;
}