From 61c02fdd7a55f42b621f419fd5bda24dba877b1e Mon Sep 17 00:00:00 2001 From: Beman Date: Sun, 12 Jul 2015 17:01:57 -0400 Subject: [PATCH] rfind working. --- include/boost/utility/string_view.hpp | 18 +++++++--- test/string_view_test3.cpp | 52 ++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/include/boost/utility/string_view.hpp b/include/boost/utility/string_view.hpp index 9944641..0ac0c5b 100644 --- a/include/boost/utility/string_view.hpp +++ b/include/boost/utility/string_view.hpp @@ -227,11 +227,19 @@ namespace boost { { return find(basic_string_view(s), pos); } // rfind - size_type rfind(basic_string_view s, size_type pos = npos) - const BOOST_NOEXCEPT { - const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (), - s.crbegin (), s.crend (), traits::eq ); - return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); + size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT { + if (len_ < s.len_) + return npos; + if (pos > len_ - s.len_) + pos = len_ - s.len_; + if (s.len_ == 0u) // an empty string is always found + return pos; + for (const charT* cur = ptr_ + pos;; --cur) { + if (traits::compare(cur, s.ptr_, s.len_) == 0) + return cur - ptr_; + if (cur == ptr_) + return npos; + }; } size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT { return rfind(basic_string_view(&c, 1), pos); } diff --git a/test/string_view_test3.cpp b/test/string_view_test3.cpp index ea6b510..679cf0f 100644 --- a/test/string_view_test3.cpp +++ b/test/string_view_test3.cpp @@ -35,7 +35,6 @@ namespace BOOST_TEST_EQ(sv3.find(sv2), s3.find(s2)); BOOST_TEST_EQ(sv1.find(sv3, 7), s1.find(s3, 7)); BOOST_TEST_EQ(sv1.find(sv3, 5), s1.find(s3, 5)); - //std::cout << s1.find(s3, 5) << std::endl; BOOST_TEST_EQ(sv1.find(sv2), s1.find(s2)); for (std::string::size_type i = 0; i <= 8; ++i) @@ -70,6 +69,56 @@ namespace BOOST_TEST_EQ(sv1.find("abc", i), s1.find("abc", i)); } + void rfind_test() + { + // rfind - test two modified and two new signatures + std::string s1("ababcab"); + boost::string_view sv1(s1); + std::string s2("ab"); + boost::string_view sv2(s2); + std::string s3; + boost::string_view sv3(s3); + + // first signature + BOOST_TEST_EQ(sv3.rfind(sv3), s3.rfind(s3)); + BOOST_TEST_EQ(sv2.rfind(sv3), s2.rfind(s3)); + BOOST_TEST_EQ(sv3.rfind(sv2), s3.rfind(s2)); + BOOST_TEST_EQ(sv1.rfind(sv3, 7), s1.rfind(s3, 7)); + BOOST_TEST_EQ(sv1.rfind(sv3, 5), s1.rfind(s3, 5)); + + BOOST_TEST_EQ(sv1.rfind(sv2), s1.rfind(s2)); + for (std::string::size_type i = s1.size(); i <= s1.size(); --i) + { + // std::cout << i << ": " << sv1.rfind(sv2, i) << " " << s1.rfind(s2, i) << std::endl; + BOOST_TEST_EQ(sv1.rfind(sv2, i), s1.rfind(s2, i)); + } + for (std::string::size_type i = 0; i <= 8; ++i) + { + //std::cout << i << std::endl; + BOOST_TEST_EQ(sv1.rfind(sv3, i), s1.rfind(s3, i)); + } + + // second signature + for (std::string::size_type i = 0; i <= 8; ++i) + { + //std::cout << i << std::endl; + BOOST_TEST_EQ(sv1.rfind('b', i), s1.rfind('b', i)); + } + + // third signature + for (std::string::size_type i = 0; i <= 8; ++i) + for (std::string::size_type j = 0; j <= 4; ++j) + { + //std::cout << i << " " << j << std::endl; + BOOST_TEST_EQ(sv1.rfind("abc", i, j), s1.rfind("abc", i, j)); + } + + // fourth signature + BOOST_TEST_EQ(sv1.rfind("abc"), s1.rfind("abc")); + for (std::string::size_type i = 0; i <= 8; ++i) + BOOST_TEST_EQ(sv1.rfind("abc", i), s1.rfind("abc", i)); + } + } // unnamed namespace int cpp_main(int argc, char* argv[]) @@ -82,6 +131,7 @@ int cpp_main(int argc, char* argv[]) // compare, five new signatures find_test(); + rfind_test(); return boost::report_errors(); }