diff --git a/CMakeLists.txt b/CMakeLists.txt
index 01f4855..9da17f1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,7 +34,7 @@ if(BUILD_TESTS)
add_subdirectory(tests)
endif()
-set(LIBREXY_PUBLIC_HEADERS "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")
+set(LIBREXY_PUBLIC_HEADERS "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/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")
target_compile_options(rexy PRIVATE -Wall -Wextra -pedantic -std=c++17)
install(TARGETS rexy
diff --git a/include/rexy/algorithm.hpp b/include/rexy/algorithm.hpp
new file mode 100644
index 0000000..6a52132
--- /dev/null
+++ b/include/rexy/algorithm.hpp
@@ -0,0 +1,109 @@
+/**
+ 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_ALGORITHM_HPP
+#define REXY_ALGORITHM_HPP
+
+#include "utility.hpp" //swap
+#include //SIZE_MAX
+#include "detail/algorithm.hpp"
+#include //size_t
+
+#include
+
+namespace rexy{
+
+ template
+ constexpr void quicksort(Iter left, Iter right, const Compare& cmp)
+ noexcept(noexcept(detail::qs_partition(left, right, cmp)))
+ {
+ while(left < right){
+ auto real_right = right-1;
+ auto pivot = detail::qs_partition(left, real_right, cmp);
+ quicksort(left, pivot, cmp);
+ left = ++pivot;
+ }
+ }
+
+ template
+ constexpr HIter two_way_search(const HIter& hstart, const HIter& hend, const NIter& nstart, const NIter& nend){
+ size_t j = 0;
+ size_t i = 0;
+ size_t nlen = nend - nstart;
+ size_t hlen = hend - hstart;
+ auto [max_suffix, period] = detail::critical_factorization(nstart, nend);
+
+ if(detail::iter_compare(nstart, nstart + period, max_suffix)){
+ size_t memory = SIZE_MAX;
+ while(j <= hlen - nlen){
+ i = max(max_suffix, memory) + 1;
+ //right side
+ while(i < nlen && nstart[i] == hstart[i + j]){
+ ++i;
+ }
+ if(i >= nlen){
+ i = max_suffix;
+ //left side
+ while(i > memory && nstart[i] == hstart[i + j]){
+ --i;
+ }
+ if(i <= memory){
+ return hstart + j; //?
+ }
+ j += period;
+ memory = nlen - period - 1;
+ }else{
+ j += (i - max_suffix);
+ memory = SIZE_MAX;
+ }
+ }
+ }else{
+ period = max(max_suffix + 1, nlen - max_suffix - 1) + 1;
+ j = 0;
+ while(j <= hlen - nlen){
+ i = max_suffix + 1;
+ while(i < nlen && nstart[i] == hstart[i + j]){
+ ++i;
+ }
+ if(i >= nlen){
+ i = max_suffix;
+ while(i != SIZE_MAX && nstart[i] == hstart[i + j]){
+ --i;
+ }
+ if(i == SIZE_MAX){
+ return hstart + j; //?
+ }
+ j += period;
+ }else{
+ j += (i - max_suffix);
+ }
+ }
+ }
+ return hend;
+ }
+
+ struct two_way_searcher{
+ template
+ constexpr HIter operator()(const HIter& hstart, const HIter& hend, const NIter& nstart, const NIter& nend)const{
+ return two_way_search(hstart, hend, nstart, nend);
+ }
+ };
+
+}
+
+#endif
diff --git a/include/rexy/cx/basic_string_hash.hpp b/include/rexy/basic_string_hash.hpp
similarity index 87%
rename from include/rexy/cx/basic_string_hash.hpp
rename to include/rexy/basic_string_hash.hpp
index 70275ee..fecfba5 100644
--- a/include/rexy/cx/basic_string_hash.hpp
+++ b/include/rexy/basic_string_hash.hpp
@@ -16,13 +16,13 @@
along with this program. If not, see .
*/
-#ifndef REXY_CX_BASIC_STRING_HASH_HPP
-#define REXY_CX_BASIC_STRING_HASH_HPP
+#ifndef REXY_BASIC_STRING_HASH_HPP
+#define REXY_BASIC_STRING_HASH_HPP
#include "string_hash.hpp"
-#include "../string.hpp"
+#include "string.hpp"
-namespace rexy::cx{
+namespace rexy{
template<>
struct hash : public string_hash{};
diff --git a/include/rexy/binary_base.hpp b/include/rexy/binary_base.hpp
index 323e967..3ccbefc 100644
--- a/include/rexy/binary_base.hpp
+++ b/include/rexy/binary_base.hpp
@@ -26,7 +26,7 @@
#include
#include //reverse_iterator
-#include "cx/utility.hpp" //max
+#include "utility.hpp" //max
#include "steal.hpp"
#include "expression.hpp"
#include "traits.hpp"
diff --git a/include/rexy/binary_base.tpp b/include/rexy/binary_base.tpp
index b228047..4b1648c 100644
--- a/include/rexy/binary_base.tpp
+++ b/include/rexy/binary_base.tpp
@@ -23,12 +23,10 @@
#include //move
#include //memcpy
#include
-#include "cx/utility.hpp" //max
+#include "utility.hpp" //max
#include "steal.hpp"
#include "detail/string_appender.hpp"
-#include "cx/utility.hpp" //strlen
-
#define STOP_STRICT_ALIAS_WARNING(x) (x)
namespace rexy{
@@ -42,7 +40,7 @@ namespace rexy{
constexpr binary_base::binary_base(const binary_base&)noexcept{}
constexpr auto binary_base::release(void)noexcept -> pointer{
- return cx::exchange(m_data, nullptr);
+ return exchange(m_data, nullptr);
}
constexpr auto binary_base::size(void)const -> size_type{
@@ -109,7 +107,7 @@ namespace rexy{
constexpr basic_binary::basic_binary(void)noexcept{}
template
constexpr basic_binary::basic_binary(rexy::steal data)noexcept:
- binary_base(data.value() ? cx::strlen(data.value()) : 0)
+ binary_base(data.value() ? strlen(data.value()) : 0)
{
m_data = data.value();
m_size = m_cap;
@@ -132,7 +130,7 @@ namespace rexy{
template
basic_binary::basic_binary(const_pointer data)
noexcept(noexcept(this->allocate(0))):
- basic_binary(data ? this->allocate(cx::strlen(data)) : nullptr, cx::strlen(data))
+ basic_binary(data ? this->allocate(strlen(data)) : nullptr, strlen(data))
{
if(data)
memcpy(m_data, data, m_cap);
@@ -163,7 +161,7 @@ namespace rexy{
}
template
constexpr basic_binary::basic_binary(basic_binary&& b)noexcept:
- binary_base(cx::exchange(b.m_data, nullptr), b.m_size, b.m_cap){}
+ binary_base(exchange(b.m_data, nullptr), b.m_size, b.m_cap){}
template
basic_binary::basic_binary(const binary_base& b)
noexcept(noexcept(this->allocate(0))):
@@ -188,7 +186,7 @@ namespace rexy{
constexpr basic_binary& basic_binary::operator=(basic_binary&& b)noexcept{
m_size = b.m_size;
m_cap = b.m_cap;
- cx::swap(m_data, b.m_data);
+ swap(m_data, b.m_data);
return *this;
}
template
@@ -231,7 +229,7 @@ namespace rexy{
if(!tmp)
return false;
memcpy(STOP_STRICT_ALIAS_WARNING(tmp).m_data, m_data, m_size);
- cx::swap(m_data, STOP_STRICT_ALIAS_WARNING(tmp).m_data);
+ swap(m_data, STOP_STRICT_ALIAS_WARNING(tmp).m_data);
m_cap = STOP_STRICT_ALIAS_WARNING(tmp).m_cap;
return true;
}
@@ -241,7 +239,7 @@ namespace rexy{
noexcept(this->deallocate(nullptr,0)))
{
if(m_size + len > m_cap)
- resize(cx::max(m_cap*2, m_size+len));
+ resize(max(m_cap*2, m_size+len));
memcpy(m_data+m_size, data, len);
m_size += len;
}
@@ -263,7 +261,7 @@ namespace rexy{
constexpr static_binary::static_binary(const_pointer str, size_type len)noexcept:
binary_base(const_cast(str), len, len){}
constexpr static_binary::static_binary(const_pointer str)noexcept:
- static_binary(str, cx::strlen(str)){}
+ static_binary(str, strlen(str)){}
constexpr static_binary::static_binary(const static_binary& s)noexcept:
static_binary(s.get(), s.size()){}
constexpr static_binary::static_binary(static_binary&& s)noexcept:
@@ -271,7 +269,7 @@ namespace rexy{
constexpr static_binary& static_binary::operator=(const_pointer str)noexcept{
m_data = const_cast(str);
- m_size = cx::strlen(str);
+ m_size = strlen(str);
m_cap = m_size;
return *this;
}
diff --git a/include/rexy/cx/algorithm.hpp b/include/rexy/cx/algorithm.hpp
deleted file mode 100644
index 89bf4a6..0000000
--- a/include/rexy/cx/algorithm.hpp
+++ /dev/null
@@ -1,65 +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_CX_ALGORITHM_HPP
-#define REXY_CX_ALGORITHM_HPP
-
-#include "utility.hpp" //swap
-
-#include
-
-namespace rexy::cx{
-
- namespace detail{
- template
- constexpr Iter qs_partition(Iter left, Iter right, const Compare& cmp)
- noexcept(std::is_nothrow_invocable::value &&
- noexcept(cx::swap(*left,*right)))
- {
- auto range = right - left;
- auto pivot = left + (range / 2);
- auto value = *pivot;
-
- //move pivot value all the way to the right side to preserve it
- cx::swap(*pivot, *right);
- for(auto it = left;it != right;++it){
- if(cmp(*it, value)){
- cx::swap(*left, *it);
- ++left;
- }
- }
- //move pivot value back to proper position
- cx::swap(*left, *right);
- return left;
- }
- }
- template
- constexpr void quicksort(Iter left, Iter right, const Compare& cmp)
- noexcept(noexcept(cx::detail::qs_partition(left, right, cmp)))
- {
- while(left < right){
- auto real_right = right-1;
- auto pivot = detail::qs_partition(left, real_right, cmp);
- quicksort(left, pivot, cmp);
- left = ++pivot;
- }
- }
-
-}
-
-#endif
diff --git a/include/rexy/cx/array.hpp b/include/rexy/cx/array.hpp
index 1f30c59..a821454 100644
--- a/include/rexy/cx/array.hpp
+++ b/include/rexy/cx/array.hpp
@@ -20,7 +20,7 @@
#define REXY_CX_ARRAY_HPP
#include //size_t
-#include "utility.hpp" //swap
+#include "../utility.hpp" //swap
#include "detail/bool_specialize_base.hpp"
#include
@@ -117,10 +117,10 @@ namespace rexy::cx{
}
}
constexpr void swap(array& other)
- noexcept(noexcept(cx::swap(m_elements[0], other.m_elements[0])))
+ noexcept(noexcept(swap(m_elements[0], other.m_elements[0])))
{
for(size_type i = 0;i < max_size();++i){
- cx::swap(m_elements[i], other.m_elements[i]);
+ swap(m_elements[i], other.m_elements[i]);
}
}
};
@@ -216,7 +216,7 @@ namespace rexy::cx{
}
constexpr void swap(array& other)noexcept{
for(size_type i = 0;i < arr_size;++i){
- cx::swap(m_elements[i], other.m_elements[i]);
+ swap(m_elements[i], other.m_elements[i]);
}
}
};
diff --git a/include/rexy/cx/cx_string_hash.hpp b/include/rexy/cx/cx_string_hash.hpp
index 4ae612d..2f1b410 100644
--- a/include/rexy/cx/cx_string_hash.hpp
+++ b/include/rexy/cx/cx_string_hash.hpp
@@ -19,7 +19,7 @@
#ifndef REXY_CX_CX_STRING_HASH_HPP
#define REXY_CX_CX_STRING_HASH_HPP
-#include "string_hash.hpp"
+#include "../string_hash.hpp"
#include "string.hpp"
namespace rexy::cx{
diff --git a/include/rexy/cx/detail/bool_specialize_base.hpp b/include/rexy/cx/detail/bool_specialize_base.hpp
index e599fa7..f3463e4 100644
--- a/include/rexy/cx/detail/bool_specialize_base.hpp
+++ b/include/rexy/cx/detail/bool_specialize_base.hpp
@@ -22,7 +22,7 @@
#include //size_t
#include //move, forward, pair
#include //CHAR_BIT
-#include "../utility.hpp" //swap
+#include "../../utility.hpp" //swap
namespace rexy::cx::detail{
diff --git a/include/rexy/cx/hashmap.hpp b/include/rexy/cx/hashmap.hpp
index e3ace57..a193359 100644
--- a/include/rexy/cx/hashmap.hpp
+++ b/include/rexy/cx/hashmap.hpp
@@ -21,8 +21,8 @@
#include "vector.hpp"
#include "array.hpp"
-#include "algorithm.hpp"
-#include "hash.hpp"
+#include "../algorithm.hpp"
+#include "../hash.hpp"
#include //CHAR_BIT
#include //size_t, ptrdiff_t
@@ -103,7 +103,7 @@ namespace rexy::cx{
}
//sort the buckets based on size, largest first
- cx::quicksort(buckets.begin(), buckets.end(), [](auto&& left, auto&& right) -> bool{
+ quicksort(buckets.begin(), buckets.end(), [](auto&& left, auto&& right) -> bool{
return left.size() > right.size();
});
@@ -199,7 +199,7 @@ namespace rexy::cx{
}
#ifdef REXY_STRING_BASE_HPP
-#include "string_hash.hpp"
+#include "../string_hash.hpp"
#endif
#endif
diff --git a/include/rexy/cx/string.hpp b/include/rexy/cx/string.hpp
index 700b886..2456759 100644
--- a/include/rexy/cx/string.hpp
+++ b/include/rexy/cx/string.hpp
@@ -25,7 +25,7 @@ namespace rexy::cx{
}
#include "../string_base.hpp"
-#include "utility.hpp"
+#include "../utility.hpp"
#include
#include //ptrdiff_t
@@ -67,7 +67,7 @@ namespace rexy::cx{
}
}
constexpr string(const_pointer data)noexcept:
- m_length(cx::strlen(data))
+ m_length(strlen(data))
{
for(size_type i = 0;i < m_length;++i){
m_data[i] = data[i];
@@ -101,7 +101,7 @@ namespace rexy::cx{
~string(void)noexcept = default;
constexpr string& operator=(const_pointer c)noexcept{
- m_length = cx::strlen(c);
+ m_length = strlen(c);
for(size_type i = 0;i < m_length;++i){
m_data[i] = c[i];
}
@@ -160,7 +160,7 @@ namespace rexy::cx{
}
}
constexpr void append(const_pointer data)noexcept{
- append(data, cx::strlen(data));
+ append(data, strlen(data));
}
constexpr void append(const string& s)noexcept{
append(s.get(), s.length());
diff --git a/include/rexy/cx/vector.hpp b/include/rexy/cx/vector.hpp
index 154df41..e68db10 100644
--- a/include/rexy/cx/vector.hpp
+++ b/include/rexy/cx/vector.hpp
@@ -23,7 +23,7 @@
#include //move, forward
#include "detail/bool_specialize_base.hpp"
-#include "utility.hpp" //swap
+#include "../utility.hpp" //swap
#include
@@ -60,7 +60,7 @@ namespace rexy::cx{
for(size_type i = 0;i < min(count, max_elements);++i){
m_elements[i] = value;
}
- m_size = cx::min(count, max_elements);
+ m_size = min(count, max_elements);
}
~vector(void)noexcept = default;
@@ -230,16 +230,16 @@ namespace rexy::cx{
}
}
constexpr void swap(vector& other)
- noexcept(noexcept(cx::swap(m_elements[0], other.m_elements[0])))
+ noexcept(noexcept(swap(m_elements[0], other.m_elements[0])))
{
size_type i = 0;
for(;i < m_size;++i){
- cx::swap(m_elements[i], other.m_elements[i]);
+ swap(m_elements[i], other.m_elements[i]);
}
for(;i < other.m_size;++i){
- cx::swap(m_elements[i], other.m_elements[i]);
+ swap(m_elements[i], other.m_elements[i]);
}
- cx::swap(m_size, other.m_size);
+ swap(m_size, other.m_size);
}
};
@@ -280,7 +280,7 @@ namespace rexy::cx{
for(size_type j = 0;j < bits_count;++j){
m_elements[i][j] = value;
}
- m_size = cx::min(count, max_elements);
+ m_size = min(count, max_elements);
}
~vector(void)noexcept = default;
@@ -422,7 +422,7 @@ namespace rexy::cx{
}
constexpr void resize(size_type count, const value_type& value)noexcept{
if(count > m_size){
- auto actual_count = cx::min(count, max_size());
+ auto actual_count = min(count, max_size());
auto num = actual_count - m_size;
auto it = end();
for(size_type i = 0;i < num;++i){
@@ -446,12 +446,12 @@ namespace rexy::cx{
++other_byte_count;
size_type i = 0;
for(;i < byte_count;++i){
- cx::swap(m_elements[i], other.m_elements[i]);
+ swap(m_elements[i], other.m_elements[i]);
}
for(;i < other_byte_count;++i){
- cx::swap(m_elements[i], other.m_elements[i]);
+ swap(m_elements[i], other.m_elements[i]);
}
- cx::swap(m_size, other.m_size);
+ swap(m_size, other.m_size);
}
};
diff --git a/include/rexy/detail/algorithm.hpp b/include/rexy/detail/algorithm.hpp
new file mode 100644
index 0000000..2f5a10c
--- /dev/null
+++ b/include/rexy/detail/algorithm.hpp
@@ -0,0 +1,86 @@
+#ifndef REXY_DETAIL_ALGORITHM_HPP
+#define REXY_DETAIL_ALGORITHM_HPP
+
+#include "../utility.hpp" //swap
+
+#include //nothrow_invocable
+#include //less, greater
+#include //pair
+#include //iterator_traits
+#include //size_t
+
+namespace rexy::detail{
+
+ template
+ constexpr Iter qs_partition(Iter left, Iter right, const Compare& cmp)
+ noexcept(std::is_nothrow_invocable::value &&
+ noexcept(swap(*left,*right)))
+ {
+ auto range = right - left;
+ auto pivot = left + (range / 2);
+ auto value = *pivot;
+
+ //move pivot value all the way to the right side to preserve it
+ swap(*pivot, *right);
+ for(auto it = left;it != right;++it){
+ if(cmp(*it, value)){
+ swap(*left, *it);
+ ++left;
+ }
+ }
+ //move pivot value back to proper position
+ swap(*left, *right);
+ return left;
+ }
+ template
+ constexpr std::pair max_suffix(const Iter& needle, size_t nlen, const Op& op = Op()){
+ using value_type = typename std::iterator_traits::value_type;
+ size_t max_suffix = -1;
+ size_t j = 0;
+ size_t k = 1;
+ size_t period = 1;
+ value_type a;
+ value_type b;
+
+ while(j + k < nlen){
+ a = needle[j + k];
+ b = needle[max_suffix + k];
+ if(op(a, b)){
+ j += k;
+ k = 1;
+ period = j - max_suffix;
+ }else if(a == b){
+ if(k != period){
+ ++k;
+ }else{
+ j += period;
+ k = 1;
+ }
+ }else{
+ max_suffix = j++;
+ k = period = 1;
+ }
+ }
+ return {max_suffix, period};
+ }
+ template
+ constexpr std::pair critical_factorization(const Iter& nstart, const Iter& nend){
+ auto msuffix = max_suffix(nstart, nend - nstart, std::less{});
+ auto msuffix_rev = max_suffix(nstart, nend - nstart, std::greater{});
+ if(msuffix.first < msuffix_rev.first){
+ return msuffix_rev;
+ }
+ return msuffix;
+ }
+ template
+ constexpr bool iter_compare(const Iter& left, const Iter& right, size_t length){
+ for(size_t i = 0;i < length;++i){
+ if(left[i] != right[i])
+ return false;
+ }
+ return true;
+ }
+
+}
+
+#endif
diff --git a/include/rexy/filerd.hpp b/include/rexy/filerd.hpp
index be85cb0..99f874e 100644
--- a/include/rexy/filerd.hpp
+++ b/include/rexy/filerd.hpp
@@ -24,7 +24,7 @@
#include "string.hpp"
#include "binary.hpp"
-#include "cx/utility.hpp"
+#include "utility.hpp"
#include
namespace rexy{
@@ -40,11 +40,11 @@ namespace rexy{
filerd(const char* f, const char* mode = "r")noexcept;
filerd(const filerd&) = delete;
constexpr filerd(filerd&& f)noexcept:
- m_fp(cx::exchange(f.m_fp, nullptr)){}
+ m_fp(exchange(f.m_fp, nullptr)){}
~filerd(void)noexcept;
filerd& operator=(const filerd&) = delete;
constexpr filerd& operator=(filerd&& f)noexcept{
- cx::swap(m_fp, f.m_fp);
+ swap(m_fp, f.m_fp);
return *this;
}
diff --git a/include/rexy/cx/hash.hpp b/include/rexy/hash.hpp
similarity index 95%
rename from include/rexy/cx/hash.hpp
rename to include/rexy/hash.hpp
index 2a0d8d9..6b92a06 100644
--- a/include/rexy/cx/hash.hpp
+++ b/include/rexy/hash.hpp
@@ -16,12 +16,12 @@
along with this program. If not, see .
*/
-#ifndef REXY_CX_HASH_HPP
-#define REXY_CX_HASH_HPP
+#ifndef REXY_HASH_HPP
+#define REXY_HASH_HPP
#include //CHAR_BIT
-namespace rexy::cx{
+namespace rexy{
template
struct hash{
diff --git a/include/rexy/cx/static_string_hash.hpp b/include/rexy/static_string_hash.hpp
similarity index 87%
rename from include/rexy/cx/static_string_hash.hpp
rename to include/rexy/static_string_hash.hpp
index 983deea..b62e9af 100644
--- a/include/rexy/cx/static_string_hash.hpp
+++ b/include/rexy/static_string_hash.hpp
@@ -16,13 +16,13 @@
along with this program. If not, see .
*/
-#ifndef REXY_CX_STATIC_STRING_HASH_HPP
-#define REXY_CX_STATIC_STRING_HASH_HPP
+#ifndef REXY_STATIC_STRING_HASH_HPP
+#define REXY_STATIC_STRING_HASH_HPP
#include "string_hash.hpp"
-#include "../string_base.hpp"
+#include "string_base.hpp"
-namespace rexy::cx{
+namespace rexy{
template
struct hash> : public string_hash>{};
diff --git a/include/rexy/string_base.hpp b/include/rexy/string_base.hpp
index 66c96a6..d3f655e 100644
--- a/include/rexy/string_base.hpp
+++ b/include/rexy/string_base.hpp
@@ -27,7 +27,7 @@
#include //reverse_iterator
#include "steal.hpp"
-#include "cx/utility.hpp"
+#include "utility.hpp"
#include "traits.hpp"
#include "expression.hpp"
#include "detail/string_appender.hpp"
@@ -200,8 +200,18 @@ 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];}
- //constexpr bool search(const string_base& s)const;
- //constexpr bool search(const_pointer c)const;
+ constexpr const_iterator search(const string_base& s)const;
+ constexpr const_iterator search(const_pointer c)const;
+ constexpr iterator search(const string_base& s);
+ constexpr iterator search(const_pointer c);
+ template
+ constexpr const_iterator search(const string_base& s, const Searcher& searcher)const;
+ template
+ constexpr const_iterator search(const_pointer c, const Searcher& searcher)const;
+ template
+ constexpr iterator search(const string_base& s, const Searcher& searcher);
+ template
+ constexpr iterator search(const_pointer c, const Searcher& searcher);
constexpr bool compare(const string_base& s)const{return *this == s;}
constexpr bool compare(const_pointer c)const{return *this == c;}
@@ -391,11 +401,11 @@ namespace rexy{
template = 0>
constexpr bool operator==(Str1&& left, Str2&& right)noexcept{
- return left.valid() && right.valid() && left.length() == right.length() && !cx::strcmp(left.get(), right.get());
+ return left.valid() && right.valid() && left.length() == right.length() && !strcmp(left.get(), right.get());
}
template = 0>
constexpr bool operator==(Str&& left, typename std::decay_t::const_pointer right)noexcept{
- return left.valid() && right && !cx::strcmp(left.get(), right);
+ return left.valid() && right && !strcmp(left.get(), right);
}
template = 0>
constexpr bool operator!=(Str1&& left, Str2&& right)noexcept{
@@ -463,7 +473,7 @@ namespace{
#include "detail/binary_string_conv.hpp"
#endif
#ifdef REXY_CX_HASH_HPP
-#include "cx/static_string_hash.hpp"
+#include "static_string_hash.hpp"
#endif
#endif
diff --git a/include/rexy/string_base.tpp b/include/rexy/string_base.tpp
index 522ec81..6bebc0d 100644
--- a/include/rexy/string_base.tpp
+++ b/include/rexy/string_base.tpp
@@ -23,13 +23,56 @@
#include //memcpy
#include //strlen, strcpy
-#include "cx/utility.hpp" //max
+#include "utility.hpp" //max
#include "detail/string_appender.hpp"
+#include "algorithm.hpp"
#define STOP_STRICT_ALIAS_WARNING(x) (x)
namespace rexy{
+ template
+ constexpr auto string_base::search(const string_base& s)const -> const_iterator{
+ return two_way_search(cbegin(), cend(), s.begin(), s.end());
+ }
+ template
+ constexpr auto string_base::search(const_pointer c)const -> const_iterator{
+ const auto len = strlen(c);
+ return two_way_search(cbegin(), cend(), c, c + len);
+ }
+ template
+ constexpr auto string_base::search(const string_base& s) -> iterator{
+ return two_way_search(begin(), end(), s.begin(), s.end());
+ }
+ template
+ constexpr auto string_base::search(const_pointer c) -> iterator{
+ const auto len = strlen(c);
+ return two_way_search(begin(), end(), c, c + len);
+ }
+ template
+ template
+ constexpr auto string_base::search(const string_base& s, const Searcher& searcher)const -> const_iterator{
+ return searcher(cbegin(), cend(), s.begin(), s.end());
+ }
+ template
+ template
+ constexpr auto string_base::search(const_pointer c, const Searcher& searcher)const -> const_iterator{
+ const auto len = strlen(c);
+ return searcher(cbegin(), cend(), c, c + len);
+ }
+ template
+ template
+ constexpr auto string_base::search(const string_base& s, const Searcher& searcher) -> iterator{
+ return searcher(begin(), end(), s.begin(), s.end());
+ }
+ template
+ template
+ constexpr auto string_base::search(const_pointer c, const Searcher& searcher) -> iterator{
+ const auto len = strlen(c);
+ return searcher(begin(), end(), c, c + len);
+ }
+
+
//allocate string if longer than small string capacity, copy otherwise
template
void basic_string::_copy_construct_string(const_pointer data, size_type len, size_type cap)
@@ -58,7 +101,7 @@ namespace rexy{
constexpr basic_string::basic_string(void)noexcept{}
template
constexpr basic_string::basic_string(rexy::steal data)noexcept:
- basic_string(data.value(), data.value() ? cx::strlen(data.value()) : 0){}
+ basic_string(data.value(), data.value() ? strlen(data.value()) : 0){}
template
constexpr basic_string::basic_string(rexy::steal data, size_type len)noexcept:
string_base(data.value(), len, len){}
@@ -78,7 +121,7 @@ namespace rexy{
template
basic_string::basic_string(const_pointer data)
noexcept(noexcept(this->allocate(0))):
- basic_string(data, data ? cx::strlen(data) : 0){}
+ basic_string(data, data ? strlen(data) : 0){}
template
basic_string::basic_string(size_type cap)
noexcept(noexcept(this->allocate(0))):
@@ -149,7 +192,7 @@ namespace rexy{
noexcept(noexcept(this->allocate(0)) &&
noexcept(this->deallocate(nullptr,0)))
{
- return _copy_string(c, cx::strlen(c));
+ return _copy_string(c, strlen(c));
}
//Replace managed pointer. Frees existing value
@@ -157,7 +200,7 @@ namespace rexy{
void basic_string::reset(pointer val)
noexcept(noexcept(this->deallocate(nullptr,0)))
{
- reset(val, val ? cx::strlen(val) : 0);
+ reset(val, val ? strlen(val) : 0);
}
template
void basic_string::reset(pointer val, size_type len)
@@ -195,7 +238,7 @@ namespace rexy{
this->set_length(mylen+len);
raw[mylen+len] = 0;
}else{
- auto newsize = cx::max(mylen+len, mycap*2);
+ auto newsize = max(mylen+len, mycap*2);
basic_string tmp(newsize);
tmp.append(raw, mylen);
tmp.append(data, len);
@@ -208,7 +251,7 @@ namespace rexy{
noexcept(this->deallocate(nullptr,0)))
{
if(data)
- append(data, cx::strlen(data));
+ append(data, strlen(data));
}
template
@@ -304,10 +347,10 @@ namespace rexy{
}
template
constexpr static_string::static_string(const_pointer c)noexcept:
- static_string(c, cx::strlen(c)){}
+ static_string(c, strlen(c)){}
template
constexpr static_string& static_string::operator=(const_pointer c)noexcept{
- size_type len = cx::strlen(c);
+ size_type len = strlen(c);
this->set_long_ptr(const_cast(c));
this->set_long_length(len);
this->set_long_capacity(len);
diff --git a/include/rexy/cx/string_hash.hpp b/include/rexy/string_hash.hpp
similarity index 93%
rename from include/rexy/cx/string_hash.hpp
rename to include/rexy/string_hash.hpp
index de1a1e0..b57383c 100644
--- a/include/rexy/cx/string_hash.hpp
+++ b/include/rexy/string_hash.hpp
@@ -16,12 +16,12 @@
along with this program. If not, see .
*/
-#ifndef REXY_CX_STRING_HASH_HPP
-#define REXY_CX_STRING_HASH_HPP
+#ifndef REXY_STRING_HASH_HPP
+#define REXY_STRING_HASH_HPP
#include "hash.hpp"
-namespace rexy::cx{
+namespace rexy{
//jenkns one at a time hash
template
diff --git a/include/rexy/cx/utility.hpp b/include/rexy/utility.hpp
similarity index 92%
rename from include/rexy/cx/utility.hpp
rename to include/rexy/utility.hpp
index ac366da..267f4fb 100644
--- a/include/rexy/cx/utility.hpp
+++ b/include/rexy/utility.hpp
@@ -16,13 +16,13 @@
along with this program. If not, see .
*/
-#ifndef REXY_CX_UTILITY_HPP
-#define REXY_CX_UTILITY_HPP
+#ifndef REXY_UTILITY_HPP
+#define REXY_UTILITY_HPP
#include //forward, move
#include
-namespace rexy::cx{
+namespace rexy{
namespace{
template
@@ -36,18 +36,18 @@ namespace rexy::cx{
}
template
constexpr Iter2 swap_ranges(Iter1 start1, Iter1 end1, Iter2 start2)
- noexcept(noexcept(cx::swap(*start1, *start2)))
+ noexcept(noexcept(swap(*start1, *start2)))
{
while(start1 != end1){
- cx::swap(start1++, start2++);
+ swap(start1++, start2++);
}
return start2;
}
template
constexpr void swap(T (&l)[N], T (&r)[N])
- noexcept(noexcept(cx::swap(*l, *r)))
+ noexcept(noexcept(swap(*l, *r)))
{
- cx::swap_ranges(l, l+N, r);
+ swap_ranges(l, l+N, r);
}
template
diff --git a/src/ensure.cpp b/src/ensure.cpp
index fb21de5..59aa387 100644
--- a/src/ensure.cpp
+++ b/src/ensure.cpp
@@ -15,13 +15,13 @@
#include "rexy/allocator.hpp"
#include "rexy/detail/string_appender.hpp"
-#include "rexy/cx/algorithm.hpp"
+#include "rexy/algorithm.hpp"
#include "rexy/cx/array.hpp"
-#include "rexy/cx/hash.hpp"
+#include "rexy/hash.hpp"
#include "rexy/cx/hashmap.hpp"
-#include "rexy/cx/string_hash.hpp"
+#include "rexy/string_hash.hpp"
#include "rexy/cx/string.hpp"
-#include "rexy/cx/utility.hpp"
+#include "rexy/utility.hpp"
#include "rexy/cx/vector.hpp"
#include "rexy/cx/detail/bool_specialize_base.hpp"
diff --git a/tests/basic_string.cpp b/tests/basic_string.cpp
index 150655f..21c821d 100644
--- a/tests/basic_string.cpp
+++ b/tests/basic_string.cpp
@@ -243,6 +243,14 @@ void check_substring(){
if(strcmp(test2.get(), "is") || test2.length() != 2)
error("substring operation should have resulted in 'is'\n");
}
+void check_string_search(){
+ rexy::string test1 = "this is a test string";
+ rexy::string test2 = "string";
+ auto res = test1.search(test2);
+ if(test1 + 15 != res){
+ error("string search operation did not result in a correct result");
+ }
+}
int main(){
check_empty_construction();
@@ -253,4 +261,5 @@ int main(){
check_short_append();
check_long_append();
check_substring();
+ check_string_search();
}