From 0651bf57d29d0cfe940a1f8cdf060b62e9621c8d Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Mon, 8 Oct 2012 18:01:11 +0900 Subject: [PATCH] add string::rfind --- libs/string/test/string.cpp | 19 ++++++++---- sprout/string/string.hpp | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/libs/string/test/string.cpp b/libs/string/test/string.cpp index 2ed77620..999e52da 100644 --- a/libs/string/test/string.cpp +++ b/libs/string/test/string.cpp @@ -133,12 +133,21 @@ namespace testspr { // find TESTSPR_BOTH_ASSERT(str1.find(str2) == decltype(str1)::npos); - TESTSPR_BOTH_ASSERT(str1.find(to_string("1234")) == 6); + TESTSPR_BOTH_ASSERT(str1.find(to_string("bar")) == 3); TESTSPR_BOTH_ASSERT(str1.find(str2.c_str()) == decltype(str1)::npos); - TESTSPR_BOTH_ASSERT(str1.find("1234") == 6); - TESTSPR_BOTH_ASSERT(str1.find(str2.c_str(), 0, 4) == decltype(str1)::npos); - TESTSPR_BOTH_ASSERT(str1.find("12341234", 0, 4) == 6); - TESTSPR_BOTH_ASSERT(str1.find('1') == 6); + TESTSPR_BOTH_ASSERT(str1.find("bar") == 3); + TESTSPR_BOTH_ASSERT(str1.find(str2.c_str(), 0, 3) == decltype(str1)::npos); + TESTSPR_BOTH_ASSERT(str1.find("barbar", 0, 3) == 3); + TESTSPR_BOTH_ASSERT(str1.find('b') == 3); + + // rfind + TESTSPR_BOTH_ASSERT(str1.rfind(str2) == decltype(str1)::npos); + TESTSPR_BOTH_ASSERT(str1.rfind(to_string("bar")) == 3); + TESTSPR_BOTH_ASSERT(str1.rfind(str2.c_str()) == decltype(str1)::npos); + TESTSPR_BOTH_ASSERT(str1.rfind("bar") == 3); + TESTSPR_BOTH_ASSERT(str1.rfind(str2.c_str(), decltype(str1)::npos, 3) == decltype(str1)::npos); + TESTSPR_BOTH_ASSERT(str1.rfind("barbar", decltype(str1)::npos, 3) == 3); + TESTSPR_BOTH_ASSERT(str1.rfind('b') == 3); // substr { diff --git a/sprout/string/string.hpp b/sprout/string/string.hpp index b0f6f33f..559d983a 100644 --- a/sprout/string/string.hpp +++ b/sprout/string/string.hpp @@ -72,6 +72,30 @@ namespace sprout { : npos ; } + template + static SPROUT_CONSTEXPR size_type + rfind_impl_2(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { + return traits_type::compare(data + pos, s, n) == 0 ? pos + : pos > 0 ? rfind_impl_2(data, len, s, pos - 1, n) + : npos + ; + } + template + static SPROUT_CONSTEXPR size_type + rfind_impl_1(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) { + return n <= len ? rfind_impl_2(data, len, s, NS_SSCRISK_CEL_OR_SPROUT::min(size_type(len - n), pos), n) + : npos + ; + } + static SPROUT_CONSTEXPR size_type + rfind_c_impl(const_iterator data, size_type len, value_type c) { + return len > 0 + ? traits_type::eq(data[len - 1], c) + ? len - 1 + : rfind_c_impl(data, len - 1, c) + : npos + ; + } static SPROUT_CONSTEXPR int compare_impl_2(int compared, size_type n1, size_type n2) { return compared != 0 ? compared @@ -369,6 +393,24 @@ namespace sprout { : npos ; } + SPROUT_CONSTEXPR size_type + rfind(basic_string const& str, size_type pos = npos) const SPROUT_NOEXCEPT { + return rfind_impl_1(begin(), len, str.begin(), pos, str.size()); + } + SPROUT_CONSTEXPR size_type + rfind(value_type const* s, size_type pos, size_type n) const { + return rfind_impl_1(begin(), len, s, pos, n); + } + SPROUT_CONSTEXPR size_type + rfind(value_type const* s, size_type pos = npos) const { + return rfind(s, pos, traits_type::length(s)); + } + SPROUT_CONSTEXPR size_type + rfind(value_type c, size_type pos = npos) const { + return len ? rfind_c_impl(begin(), len - 1 > pos ? pos + 1 : len, c) + : npos + ; + } SPROUT_CONSTEXPR basic_string substr(size_type pos = 0, size_type n = npos) const { return !(size() < pos) @@ -487,6 +529,22 @@ namespace sprout { return find(s, pos, traits_type::length(s)); } template + SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_index_iterator::value, + size_type + >::type + rfind(ConstIterator s, size_type pos, size_type n) const { + return rfind_impl_1(begin(), len, s, pos, n); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_index_iterator::value, + size_type + >::type + rfind(ConstIterator s, size_type pos = npos) const { + return rfind(s, pos, traits_type::length(s)); + } + template SPROUT_CONSTEXPR typename std::enable_if< sprout::is_index_iterator::value, int