Add rsearch to basic_string to find last match in buffer

This commit is contained in:
rexy712 2022-06-23 15:39:35 -07:00
parent cdd51a6e3a
commit 61987d937b
4 changed files with 66 additions and 7 deletions

View File

@ -289,6 +289,15 @@ namespace rexy{
template<class Searcher> template<class Searcher>
constexpr iterator search(const_pointer c, const Searcher& searcher); constexpr iterator search(const_pointer c, const Searcher& searcher);
constexpr const_iterator rsearch(basic_string_view<value_type> sv)const;
constexpr iterator rsearch(basic_string_view<value_type> sv);
constexpr const_iterator rsearch(const_pointer c)const;
constexpr iterator rsearch(const_pointer c);
template<class Searcher>
constexpr const_iterator rsearch(const_pointer c, const Searcher& searcher)const;
template<class Searcher>
constexpr iterator rsearch(const_pointer c, const Searcher& searcher);
constexpr bool starts_with(basic_string_view<value_type> sv)const noexcept; constexpr bool starts_with(basic_string_view<value_type> sv)const noexcept;
constexpr bool starts_with(value_type v)const noexcept; constexpr bool starts_with(value_type v)const noexcept;
constexpr bool starts_with(const_pointer str)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 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 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 reverse_iterator rend(void){return reverse_iterator(get_pointer());}
constexpr const_reverse_iterator rend(void)const{return const_reverse_iterator(get_pointer()-1);} 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 crbegin(void)const{return rbegin();}
constexpr const_reverse_iterator crend(void)const{return rend();} constexpr const_reverse_iterator crend(void)const{return rend();}

View File

@ -21,6 +21,7 @@
#include <utility> //move, etc #include <utility> //move, etc
#include <type_traits> //is_nothrow_invokable, is_nothrow_constructible #include <type_traits> //is_nothrow_invokable, is_nothrow_constructible
#include <iterator> //reverse_iterator
#include "utility.hpp" //max, memcpy, strlen #include "utility.hpp" //max, memcpy, strlen
#include "detail/string_appender.hpp" #include "detail/string_appender.hpp"
@ -86,6 +87,43 @@ namespace rexy{
return searcher(begin(), end(), c, c + len); return searcher(begin(), end(), c, c + len);
} }
template<class Char>
constexpr auto string_base<Char>::rsearch(basic_string_view<value_type> sv)const -> const_iterator{
if(sv.length() > length()){
return cend();
}
return two_way_search(crbegin(), crend(), sv.crbegin(), sv.crend()).base();
}
template<class Char>
constexpr auto string_base<Char>::rsearch(basic_string_view<value_type> sv) -> iterator{
if(sv.length() > length()){
return end();
}
return two_way_search(rbegin(), rend(), sv.crbegin(), sv.crend()).base() - sv.length();
}
template<class Char>
constexpr auto string_base<Char>::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<class Char>
constexpr auto string_base<Char>::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<class Char>
template<class Searcher>
constexpr auto string_base<Char>::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<class Char>
template<class Searcher>
constexpr auto string_base<Char>::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<class Char> template<class Char>
constexpr bool string_base<Char>::starts_with(basic_string_view<value_type> sv)const noexcept{ constexpr bool string_base<Char>::starts_with(basic_string_view<value_type> sv)const noexcept{
return basic_string_view<value_type>(data(), length()).starts_with(sv); return basic_string_view<value_type>(data(), length()).starts_with(sv);

View File

@ -111,7 +111,7 @@ namespace rexy{
constexpr const_iterator cend(void)const{return end();} 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 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 crbegin(void)const{return rbegin();}
constexpr const_reverse_iterator crend(void)const{return rend();} constexpr const_reverse_iterator crend(void)const{return rend();}

View File

@ -246,11 +246,23 @@ void check_substring(){
} }
void check_string_search(){ void check_string_search(){
rexy::string test1 = "this is a test string"; rexy::string test1 = "this is a test string";
rexy::string test2 = "string"; rexy::string_view test2 = "string";
auto res = test1.search(test2.create_view()); auto res = test1.search(test2);
if(test1.data() + 15 != res){ if(test1.begin() + 15 != res){
error("string search operation did not result in a correct result\n"); 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(){ void check_string_insert(){