Add rsearch to basic_string to find last match in buffer
This commit is contained in:
parent
cdd51a6e3a
commit
61987d937b
@ -289,6 +289,15 @@ namespace rexy{
|
||||
template<class 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(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();}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
#include <utility> //move, etc
|
||||
#include <type_traits> //is_nothrow_invokable, is_nothrow_constructible
|
||||
#include <iterator> //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<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>
|
||||
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);
|
||||
|
||||
@ -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();}
|
||||
|
||||
|
||||
@ -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(){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user