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>
|
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();}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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();}
|
||||||
|
|
||||||
|
|||||||
@ -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(){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user