add string::find_first_of, find_last_of

This commit is contained in:
bolero-MURAKAMI 2012-10-08 21:29:35 +09:00
parent 0651bf57d2
commit 9dd1fefa59
3 changed files with 123 additions and 3 deletions

View file

@ -149,6 +149,24 @@ namespace testspr {
TESTSPR_BOTH_ASSERT(str1.rfind("barbar", decltype(str1)::npos, 3) == 3);
TESTSPR_BOTH_ASSERT(str1.rfind('b') == 3);
// find_first_of
TESTSPR_BOTH_ASSERT(str1.find_first_of(to_string("vwxyz")) == decltype(str1)::npos);
TESTSPR_BOTH_ASSERT(str1.find_first_of(to_string("rab")) == 3);
TESTSPR_BOTH_ASSERT(str1.find_first_of("vwxyz") == decltype(str1)::npos);
TESTSPR_BOTH_ASSERT(str1.find_first_of("rab") == 3);
TESTSPR_BOTH_ASSERT(str1.find_first_of("vwxyz", 0, 3) == decltype(str1)::npos);
TESTSPR_BOTH_ASSERT(str1.find_first_of("rabrab", 0, 3) == 3);
TESTSPR_BOTH_ASSERT(str1.find_first_of('b') == 3);
// find_last_of
TESTSPR_BOTH_ASSERT(str1.find_last_of(to_string("vwxyz")) == decltype(str1)::npos);
TESTSPR_BOTH_ASSERT(str1.find_last_of(to_string("rab")) == 5);
TESTSPR_BOTH_ASSERT(str1.find_last_of("vwxyz") == decltype(str1)::npos);
TESTSPR_BOTH_ASSERT(str1.find_last_of("rab") == 5);
TESTSPR_BOTH_ASSERT(str1.find_last_of("vwxyz", decltype(str1)::npos, 3) == decltype(str1)::npos);
TESTSPR_BOTH_ASSERT(str1.find_last_of("rabrab", decltype(str1)::npos, 3) == 5);
TESTSPR_BOTH_ASSERT(str1.find_last_of('r') == 5);
// substr
{
SPROUT_STATIC_CONSTEXPR auto str3 = str1.substr();

View file

@ -105,7 +105,7 @@ namespace sprout {
}
template<typename ConstIterator>
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
return !n ? s + 1
return !n ? s
: eq(*s, a) ? s
: find(s + 1, n - 1, a)
;
@ -141,10 +141,23 @@ namespace sprout {
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::state_type state_type;
public:
static SPROUT_CONSTEXPR char_type const* find(char_type const* s, std::size_t n, char_type const& a) {
return !n ? s
: traits_type::eq(*s, a) ? s
: find(s + 1, n - 1, a)
;
}
static SPROUT_CONSTEXPR bool is_found(char_type const* found, char_type const* last) {
return found;
return found != last;
}
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
template<typename ConstIterator>
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
return !n ? s
: traits_type::eq(*s, a) ? s
: find(s + 1, n - 1, a)
;
}
template<typename ConstIterator>
static SPROUT_CONSTEXPR bool is_found(ConstIterator found, ConstIterator last) {
return found != last;

View file

@ -96,6 +96,31 @@ namespace sprout {
: npos
;
}
template<typename ConstIterator>
static SPROUT_CONSTEXPR size_type
find_first_of_impl_1(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) {
return n && pos < len
? traits_helper_type::is_found(traits_helper_type::find(s, n, data[pos]), s + n)
? pos
: find_first_of_impl_1(data, len, s, pos + 1, n)
: npos
;
}
template<typename ConstIterator>
static SPROUT_CONSTEXPR size_type
find_last_of_impl_2(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) {
return traits_helper_type::is_found(traits_helper_type::find(s, n, data[len]), s + n) ? len
: len != 0 ? find_last_of_impl_2(data, len - 1, s, pos, n)
: npos
;
}
template<typename ConstIterator>
static SPROUT_CONSTEXPR size_type
find_last_of_impl_1(const_iterator data, size_type len, ConstIterator s, size_type pos, size_type n) {
return len && n ? find_last_of_impl_2(data, len - 1 > pos ? pos : len, s, pos, n)
: npos
;
}
static SPROUT_CONSTEXPR int
compare_impl_2(int compared, size_type n1, size_type n2) {
return compared != 0 ? compared
@ -389,7 +414,7 @@ namespace sprout {
}
SPROUT_CONSTEXPR size_type
find(value_type c, size_type pos = 0) const {
return pos < len ? find_c_impl(traits_type::find(begin() + pos, len - pos, c), begin(), end())
return pos < len ? find_c_impl(traits_helper_type::find(begin() + pos, len - pos, c), begin(), end())
: npos
;
}
@ -411,6 +436,38 @@ namespace sprout {
: npos
;
}
SPROUT_CONSTEXPR size_type
find_first_of(basic_string const& str, size_type pos = 0) const SPROUT_NOEXCEPT {
return find_first_of_impl_1(begin(), len, str.begin(), pos, str.size());
}
SPROUT_CONSTEXPR size_type
find_first_of(value_type const* s, size_type pos, size_type n) const {
return find_first_of_impl_1(begin(), len, s, pos, n);
}
SPROUT_CONSTEXPR size_type
find_first_of(value_type const* s, size_type pos = 0) const {
return find_first_of(s, pos, traits_type::length(s));
}
SPROUT_CONSTEXPR size_type
find_first_of(value_type c, size_type pos = 0) const {
return find(c, pos);
}
SPROUT_CONSTEXPR size_type
find_last_of(basic_string const& str, size_type pos = npos) const SPROUT_NOEXCEPT {
return find_last_of_impl_1(begin(), len, str.begin(), pos, str.size());
}
SPROUT_CONSTEXPR size_type
find_last_of(value_type const* s, size_type pos, size_type n) const {
return find_last_of_impl_1(begin(), len, s, pos, n);
}
SPROUT_CONSTEXPR size_type
find_last_of(value_type const* s, size_type pos = npos) const {
return find_last_of(s, pos, traits_type::length(s));
}
SPROUT_CONSTEXPR size_type
find_last_of(value_type c, size_type pos = npos) const {
return rfind(c, pos);
}
SPROUT_CONSTEXPR basic_string
substr(size_type pos = 0, size_type n = npos) const {
return !(size() < pos)
@ -545,6 +602,38 @@ namespace sprout {
return rfind(s, pos, traits_type::length(s));
}
template<typename ConstIterator>
SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_index_iterator<ConstIterator>::value,
size_type
>::type
find_first_of(ConstIterator s, size_type pos, size_type n) const {
return find_first_of_impl_1(begin(), len, s, pos, n);
}
template<typename ConstIterator>
SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_index_iterator<ConstIterator>::value,
size_type
>::type
find_first_of(ConstIterator s, size_type pos = 0) const {
return find_first_of(s, pos, traits_type::length(s));
}
template<typename ConstIterator>
SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_index_iterator<ConstIterator>::value,
size_type
>::type
find_last_of(ConstIterator s, size_type pos, size_type n) const {
return find_last_of_impl_1(begin(), len, s, pos, n);
}
template<typename ConstIterator>
SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_index_iterator<ConstIterator>::value,
size_type
>::type
find_last_of(ConstIterator s, size_type pos = 0) const {
return find_last_of(s, pos, traits_type::length(s));
}
template<typename ConstIterator>
SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_index_iterator<ConstIterator>::value,
int