diff --git a/include/rexy/string_base.hpp b/include/rexy/string_base.hpp index d073ac6..565915d 100644 --- a/include/rexy/string_base.hpp +++ b/include/rexy/string_base.hpp @@ -289,6 +289,15 @@ namespace rexy{ template constexpr iterator search(const_pointer c, const Searcher& searcher); + constexpr const_iterator rsearch(basic_string_view sv)const; + constexpr iterator rsearch(basic_string_view sv); + constexpr const_iterator rsearch(const_pointer c)const; + constexpr iterator rsearch(const_pointer c); + template + constexpr const_iterator rsearch(const_pointer c, const Searcher& searcher)const; + template + constexpr iterator rsearch(const_pointer c, const Searcher& searcher); + constexpr bool starts_with(basic_string_view sv)const noexcept; constexpr bool starts_with(value_type v)const noexcept; constexpr bool starts_with(const_pointer str)const noexcept; @@ -327,8 +336,8 @@ namespace rexy{ constexpr reverse_iterator rbegin(void){return reverse_iterator(get_pointer()+length());} constexpr const_reverse_iterator rbegin(void)const{return const_reverse_iterator(get_pointer()+length());} - constexpr reverse_iterator rend(void){return reverse_iterator(get_pointer()-1);} - constexpr const_reverse_iterator rend(void)const{return const_reverse_iterator(get_pointer()-1);} + constexpr reverse_iterator rend(void){return reverse_iterator(get_pointer());} + constexpr const_reverse_iterator rend(void)const{return const_reverse_iterator(get_pointer());} constexpr const_reverse_iterator crbegin(void)const{return rbegin();} constexpr const_reverse_iterator crend(void)const{return rend();} diff --git a/include/rexy/string_base.tpp b/include/rexy/string_base.tpp index 7f46181..a99a031 100644 --- a/include/rexy/string_base.tpp +++ b/include/rexy/string_base.tpp @@ -21,6 +21,7 @@ #include //move, etc #include //is_nothrow_invokable, is_nothrow_constructible +#include //reverse_iterator #include "utility.hpp" //max, memcpy, strlen #include "detail/string_appender.hpp" @@ -86,6 +87,43 @@ namespace rexy{ return searcher(begin(), end(), c, c + len); } + template + constexpr auto string_base::rsearch(basic_string_view sv)const -> const_iterator{ + if(sv.length() > length()){ + return cend(); + } + return two_way_search(crbegin(), crend(), sv.crbegin(), sv.crend()).base(); + } + template + constexpr auto string_base::rsearch(basic_string_view sv) -> iterator{ + if(sv.length() > length()){ + return end(); + } + return two_way_search(rbegin(), rend(), sv.crbegin(), sv.crend()).base() - sv.length(); + } + template + constexpr auto string_base::rsearch(const_pointer c)const -> const_iterator{ + const auto len = rexy::strlen(c); + return two_way_search(crbegin(), crend(), std::reverse_iterator(c + len), std::reverse_iterator(c)).base() - len; + } + template + constexpr auto string_base::rsearch(const_pointer c) -> iterator{ + const auto len = rexy::strlen(c); + return two_way_search(rbegin(), rend(), std::reverse_iterator(c + len), std::reverse_iterator(c)).base() - len; + } + template + template + constexpr auto string_base::rsearch(const_pointer c, const Searcher& searcher)const -> const_iterator{ + const auto len = rexy::strlen(c); + return searcher(crbegin(), crend(), std::reverse_iterator(c + len), std::reverse_iterator(c)).base() - len; + } + template + template + constexpr auto string_base::rsearch(const_pointer c, const Searcher& searcher) -> iterator{ + const auto len = rexy::strlen(c); + return searcher(rbegin(), rend(), std::reverse_iterator(c + len), std::reverse_iterator(c)).base() - len; + } + template constexpr bool string_base::starts_with(basic_string_view sv)const noexcept{ return basic_string_view(data(), length()).starts_with(sv); diff --git a/include/rexy/string_view.hpp b/include/rexy/string_view.hpp index ba77cbc..26ede80 100644 --- a/include/rexy/string_view.hpp +++ b/include/rexy/string_view.hpp @@ -111,7 +111,7 @@ namespace rexy{ constexpr const_iterator cend(void)const{return end();} constexpr const_reverse_iterator rbegin(void)const{return const_reverse_iterator(m_data+m_length);} - constexpr const_reverse_iterator rend(void)const{return const_reverse_iterator(m_data-1);} + constexpr const_reverse_iterator rend(void)const{return const_reverse_iterator(m_data);} constexpr const_reverse_iterator crbegin(void)const{return rbegin();} constexpr const_reverse_iterator crend(void)const{return rend();} diff --git a/tests/basic_string.cpp b/tests/basic_string.cpp index 240114e..4551d32 100644 --- a/tests/basic_string.cpp +++ b/tests/basic_string.cpp @@ -246,11 +246,23 @@ void check_substring(){ } void check_string_search(){ rexy::string test1 = "this is a test string"; - rexy::string test2 = "string"; - auto res = test1.search(test2.create_view()); - if(test1.data() + 15 != res){ - error("string search operation did not result in a correct result\n"); + rexy::string_view test2 = "string"; + auto res = test1.search(test2); + if(test1.begin() + 15 != res){ + error("string search operation 1 did not result in a correct result\n"); } + + test1 = "this string has multiple strings of the word string in it"; + res = test1.search(test2); + if(test1.begin() + 5 != res){ + error("string search operation 2 did not result in a correct result\n"); + } + + res = test1.rsearch(test2); + if(test1.begin() + 45 != res){ + error("string search operation 3 did not result in a correct result\n"); + } + } void check_string_insert(){