mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
fix recursion depth: cstring algorithm
This commit is contained in:
parent
f26032dce8
commit
b51b14efa9
25 changed files with 792 additions and 142 deletions
|
@ -56,7 +56,7 @@ namespace sprout {
|
|||
|
||||
template<typename ForwardIterator1>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<ForwardIterator1, bool>
|
||||
search_impl_check(sprout::pair<ForwardIterator1, bool> const& current, ForwardIterator1 last1, ForwardIterator1 searched) {
|
||||
search_impl_fork(sprout::pair<ForwardIterator1, bool> const& current, ForwardIterator1 last1, ForwardIterator1 searched) {
|
||||
typedef sprout::pair<ForwardIterator1, bool> type;
|
||||
return searched == current.first || searched == last1 ? type(searched, true)
|
||||
: type(sprout::next(current.first), false)
|
||||
|
@ -72,7 +72,7 @@ namespace sprout {
|
|||
{
|
||||
typedef sprout::pair<ForwardIterator1, bool> type;
|
||||
return current.second || current.first == last1 ? current
|
||||
: n == 1 ? sprout::detail::search_impl_check(
|
||||
: n == 1 ? sprout::detail::search_impl_fork(
|
||||
current, last1,
|
||||
sprout::detail::search_one(current.first, last1, first2, last2, pred)
|
||||
)
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace sprout {
|
|||
template<typename InputIterator1, typename InputIterator2, typename Compare>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
|
||||
tristate_lexicographical_compare_impl_1(
|
||||
sprout::pair<InputIterator1, InputIterator2> current,
|
||||
sprout::pair<InputIterator1, InputIterator2> const& current,
|
||||
InputIterator1 last1, InputIterator2 last2, Compare comp,
|
||||
typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
|
@ -109,7 +109,7 @@ namespace sprout {
|
|||
template<typename InputIterator1, typename InputIterator2, typename Compare>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
|
||||
tristate_lexicographical_compare_impl(
|
||||
sprout::pair<InputIterator1, InputIterator2> current,
|
||||
sprout::pair<InputIterator1, InputIterator2> const& current,
|
||||
InputIterator1 last1, InputIterator2 last2, Compare comp,
|
||||
typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
|
@ -252,7 +252,7 @@ namespace sprout {
|
|||
template<typename InputIterator1, typename T1, typename InputIterator2, typename T2, typename Compare>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
|
||||
tristate_lexicographical_compare_impl_1(
|
||||
sprout::pair<InputIterator1, InputIterator2> current,
|
||||
sprout::pair<InputIterator1, InputIterator2> const& current,
|
||||
InputIterator1 last1, T1 const& delim1, InputIterator2 last2, T2 const& delim2, Compare comp,
|
||||
typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
|
@ -276,7 +276,7 @@ namespace sprout {
|
|||
template<typename InputIterator1, typename T1, typename InputIterator2, typename T2, typename Compare>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
|
||||
tristate_lexicographical_compare_impl(
|
||||
sprout::pair<InputIterator1, InputIterator2> current,
|
||||
sprout::pair<InputIterator1, InputIterator2> const& current,
|
||||
InputIterator1 last1, T1 const& delim1, InputIterator2 last2, T2 const& delim2, Compare comp,
|
||||
typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
|
|
|
@ -1,24 +1,92 @@
|
|||
#ifndef SPROUT_CSTRING_STRCHR_HPP
|
||||
#define SPROUT_CSTRING_STRCHR_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/utility/pair.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
#include <sprout/detail/str.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
namespace detail {
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator, bool>
|
||||
strchr_impl_1(
|
||||
sprout::pair<InputIterator, bool> const& current,
|
||||
T const& value, typename std::iterator_traits<InputIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<InputIterator, bool> type;
|
||||
return current.second || !*current.first ? current
|
||||
: n == 1 ? *current.first == value ? type(current.first, true) : type(sprout::next(current.first), false)
|
||||
: sprout::detail::strchr_impl_1(
|
||||
sprout::detail::strchr_impl_1(
|
||||
current,
|
||||
value, n / 2
|
||||
),
|
||||
value, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator, bool>
|
||||
strchr_impl(
|
||||
sprout::pair<InputIterator, bool> const& current,
|
||||
T const& value, typename std::iterator_traits<InputIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<InputIterator, bool> type;
|
||||
return current.second || !*current.first ? current
|
||||
: sprout::detail::strchr_impl(
|
||||
sprout::detail::strchr_impl_1(
|
||||
current,
|
||||
value, n
|
||||
),
|
||||
value, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR InputIterator
|
||||
strchr(InputIterator first, T const& value) {
|
||||
typedef sprout::pair<InputIterator, bool> type;
|
||||
return sprout::detail::strchr_impl(type(first, false), value, 1).first;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// 7.21.5.2 strchr ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
inline SPROUT_CONSTEXPR char const*
|
||||
strchr(char const* s, int c) {
|
||||
return *s == static_cast<char>(c) ? s
|
||||
: !*s ? nullptr
|
||||
: sprout::strchr(s + 1, c)
|
||||
;
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strchr(s, static_cast<char>(c)),
|
||||
static_cast<char>(c)
|
||||
);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR char*
|
||||
strchr(char* s, int c) {
|
||||
return const_cast<char*>(sprout::strchr(const_cast<char const*>(s), c));
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strchr(s, static_cast<char>(c)),
|
||||
static_cast<char>(c)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
Elem*
|
||||
>::type
|
||||
strchr(Elem* s, typename std::decay<Elem>::type c) {
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strchr(s, c),
|
||||
c
|
||||
);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -1,20 +1,91 @@
|
|||
#ifndef SPROUT_CSTRING_STRCMP_HPP
|
||||
#define SPROUT_CSTRING_STRCMP_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/utility/pair.hpp>
|
||||
#include <sprout/tuple/tuple.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
namespace detail {
|
||||
template<typename InputIterator1, typename InputIterator2>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
strcmp_impl_check(sprout::tuples::tuple<InputIterator1, InputIterator2, int> const& found) {
|
||||
return !*sprout::tuples::get<1>(found) ? (!*sprout::tuples::get<0>(found) ? 0 : 1)
|
||||
: !*sprout::tuples::get<0>(found) ? -1
|
||||
: sprout::tuples::get<2>(found)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename InputIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator1, InputIterator2, int>
|
||||
strcmp_impl_1(
|
||||
sprout::tuples::tuple<InputIterator1, InputIterator2, int> const& current,
|
||||
typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, InputIterator2, int> type;
|
||||
return sprout::tuples::get<2>(current) || !*sprout::tuples::get<1>(current) || !*sprout::tuples::get<0>(current) ? current
|
||||
: n == 1 ? (*sprout::tuples::get<0>(current)) < (*sprout::tuples::get<1>(current)) ? type(sprout::tuples::get<0>(current), sprout::tuples::get<1>(current), -1)
|
||||
: (*sprout::tuples::get<1>(current)) < (*sprout::tuples::get<0>(current)) ? type(sprout::tuples::get<0>(current), sprout::tuples::get<1>(current), 1)
|
||||
: type(sprout::next(sprout::tuples::get<0>(current)), sprout::next(sprout::tuples::get<1>(current)), 0)
|
||||
: sprout::detail::strcmp_impl_1(
|
||||
sprout::detail::strcmp_impl_1(
|
||||
current,
|
||||
n / 2
|
||||
),
|
||||
n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename InputIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator1, InputIterator2, int>
|
||||
strcmp_impl(
|
||||
sprout::tuples::tuple<InputIterator1, InputIterator2, int> const& current,
|
||||
typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, InputIterator2, int> type;
|
||||
return sprout::tuples::get<2>(current) || !*sprout::tuples::get<1>(current) || !*sprout::tuples::get<0>(current) ? current
|
||||
: sprout::detail::strcmp_impl(
|
||||
sprout::detail::strcmp_impl_1(
|
||||
current,
|
||||
n
|
||||
),
|
||||
n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename InputIterator2>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
strcmp(InputIterator1 first1, InputIterator2 first2)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, InputIterator2, int> type;
|
||||
return sprout::detail::strcmp_impl_check(
|
||||
sprout::detail::strcmp_impl(type(first1, first2, 0), 1)
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// 7.21.4.2 strcmp ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR int
|
||||
strcmp(char const* s1, char const* s2) {
|
||||
return !*s1 && !*s2 ? 0
|
||||
: !*s1 ? -1
|
||||
: !*s2 ? 1
|
||||
: *s1 == *s2 ? sprout::strcmp(s1 + 1, s2 + 1)
|
||||
: static_cast<unsigned char>(*s1) - static_cast<unsigned char>(*s2)
|
||||
;
|
||||
return sprout::detail::strcmp(s1, s2);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
int
|
||||
>::type
|
||||
strcmp(Elem* s1, Elem* s2) {
|
||||
return sprout::detail::strcmp(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
#ifndef SPROUT_CSTRING_STRCOLL_HPP
|
||||
#define SPROUT_CSTRING_STRCOLL_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
#include <sprout/cstring/strcmp.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
|
||||
// 7.21.4.3 strcoll ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR int
|
||||
strcoll(char const* s1, char const* s2) {
|
||||
return sprout::strcmp(s1, s2);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
int
|
||||
>::type
|
||||
strcoll(Elem* s1, Elem* s2) {
|
||||
return sprout::strcmp(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CSTRING_STRCOLL_HPP
|
||||
|
|
|
@ -2,16 +2,80 @@
|
|||
#define SPROUT_CSTRING_STRCSPN_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/tuple/tuple.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
#include <sprout/cstring/strchr.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator1, std::size_t, bool>
|
||||
strcspn_impl_1(
|
||||
sprout::tuples::tuple<InputIterator1, std::size_t, bool> const& current,
|
||||
ForwardIterator2 first2, typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, std::size_t, bool> type;
|
||||
return sprout::tuples::get<2>(current) || !*sprout::tuples::get<0>(current) ? current
|
||||
: n == 1 ? !*sprout::detail::strchr(first2, *sprout::tuples::get<0>(current))
|
||||
? type(sprout::next(sprout::tuples::get<0>(current)), sprout::tuples::get<1>(current) + 1, false)
|
||||
: type(sprout::tuples::get<0>(current), sprout::tuples::get<1>(current), true)
|
||||
: sprout::detail::strcspn_impl_1(
|
||||
sprout::detail::strcspn_impl_1(
|
||||
current,
|
||||
first2, n / 2
|
||||
),
|
||||
first2, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator1, std::size_t, bool>
|
||||
strcspn_impl(
|
||||
sprout::tuples::tuple<InputIterator1, std::size_t, bool> const& current,
|
||||
ForwardIterator2 first2, typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, std::size_t, bool> type;
|
||||
return sprout::tuples::get<2>(current) || !*sprout::tuples::get<0>(current) ? current
|
||||
: sprout::detail::strcspn_impl(
|
||||
sprout::detail::strcspn_impl_1(
|
||||
current,
|
||||
first2, n
|
||||
),
|
||||
first2, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
strcspn(InputIterator1 first1, ForwardIterator2 first2) {
|
||||
typedef sprout::tuples::tuple<InputIterator1, std::size_t, bool> type;
|
||||
return sprout::tuples::get<1>(sprout::detail::strcspn_impl(type(first1, 0, false), first2, 1));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// 7.21.5.3 strcspn ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
strcspn(char const* s1, char const* s2) {
|
||||
return !*s1 || sprout::strchr(s2, *s1) ? 0
|
||||
: 1 + sprout::strcspn(s1 + 1, s2)
|
||||
;
|
||||
return sprout::detail::strcspn(s1, s2);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
std::size_t
|
||||
>::type
|
||||
strcspn(Elem* s1, Elem* s2) {
|
||||
return sprout::detail::strcspn(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -2,20 +2,71 @@
|
|||
#define SPROUT_CSTRING_STRLEN_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/ptr_index_iterator.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/ptr_index_iterator.hpp>
|
||||
#include <sprout/utility/pair.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
#include <sprout/algorithm/find.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator, std::size_t>
|
||||
strlen_impl_1(
|
||||
sprout::pair<InputIterator, std::size_t> const& current,
|
||||
typename std::iterator_traits<InputIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<InputIterator, std::size_t> type;
|
||||
return !*current.first ? current
|
||||
: n == 1 ? type(sprout::next(current.first), current.second + 1)
|
||||
: sprout::detail::strlen_impl_1(
|
||||
sprout::detail::strlen_impl_1(
|
||||
current,
|
||||
n / 2
|
||||
),
|
||||
n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator, std::size_t>
|
||||
strlen_impl(
|
||||
sprout::pair<InputIterator, std::size_t> const& current,
|
||||
typename std::iterator_traits<InputIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<InputIterator, std::size_t> type;
|
||||
return !*current.first ? current
|
||||
: sprout::detail::strlen_impl(
|
||||
sprout::detail::strlen_impl_1(
|
||||
current,
|
||||
n
|
||||
),
|
||||
n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
strlen(InputIterator first) {
|
||||
typedef sprout::pair<InputIterator, std::size_t> type;
|
||||
return sprout::detail::strlen_impl(type(first, 0), 1).second;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// 7.21.6.3 strlen ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
strlen(char const* s) {
|
||||
return !*s ? 0
|
||||
: 1 + sprout::strlen(s + 1)
|
||||
;
|
||||
return sprout::detail::strlen(s);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
strlen(char const* s, std::size_t n) {
|
||||
return sprout::distance(
|
||||
|
@ -23,6 +74,27 @@ namespace sprout {
|
|||
sprout::find(sprout::as_iterator(s), sprout::as_iterator(s, n), '\0')
|
||||
);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
std::size_t
|
||||
>::type
|
||||
strlen(Elem* s) {
|
||||
return sprout::detail::strlen(s);
|
||||
}
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
std::size_t
|
||||
>::type
|
||||
strlen(Elem* s, std::size_t n) {
|
||||
typedef typename std::decay<Elem>::type type;
|
||||
return sprout::distance(
|
||||
sprout::as_iterator(s),
|
||||
sprout::find(sprout::as_iterator(s), sprout::as_iterator(s, n), type())
|
||||
);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CSTRING_STRLEN_HPP
|
||||
|
|
|
@ -2,12 +2,18 @@
|
|||
#define SPROUT_CSTRING_STRNCMP_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/ptr_index_iterator.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
#include <sprout/algorithm/tristate_lexicographical_compare.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// 7.21.4.4 strncmp ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR int
|
||||
strncmp(char const* s1, char const* s2, std::size_t n) {
|
||||
return sprout::tristate_lexicographical_compare(
|
||||
|
@ -15,6 +21,19 @@ namespace sprout {
|
|||
sprout::as_iterator(s2), sprout::as_iterator(s2, n), '\0'
|
||||
);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
int
|
||||
>::type
|
||||
strncmp(Elem* s1, Elem* s2, std::size_t n) {
|
||||
typedef typename std::decay<Elem>::type type;
|
||||
return sprout::tristate_lexicographical_compare(
|
||||
sprout::as_iterator(s1), sprout::as_iterator(s1, n), type(),
|
||||
sprout::as_iterator(s2), sprout::as_iterator(s2, n), type()
|
||||
);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CSTRING_STRNCMP_HPP
|
||||
|
|
|
@ -1,25 +1,93 @@
|
|||
#ifndef SPROUT_CSTRING_STRPBRK_HPP
|
||||
#define SPROUT_CSTRING_STRPBRK_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/utility/pair.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
#include <sprout/cstring/strchr.hpp>
|
||||
#include <sprout/detail/str.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
namespace detail {
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, bool>
|
||||
strpbrk_impl_1(
|
||||
sprout::pair<InputIterator1, bool> current,
|
||||
ForwardIterator2 first2,
|
||||
typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<InputIterator1, bool> type;
|
||||
return current.second || !*current.first ? current
|
||||
: n == 1 ? sprout::strchr(first2, *current.first)
|
||||
? type(current.first, true)
|
||||
: type(sprout::next(current.first), false)
|
||||
: sprout::detail::strpbrk_impl_1(
|
||||
sprout::detail::strpbrk_impl_1(
|
||||
current,
|
||||
first2, n / 2
|
||||
),
|
||||
first2, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, bool>
|
||||
strpbrk_impl(
|
||||
sprout::pair<InputIterator1, bool> current,
|
||||
ForwardIterator2 first2,
|
||||
typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<InputIterator1, bool> type;
|
||||
return current.second || !*current.first ? current
|
||||
: sprout::detail::strpbrk_impl(
|
||||
sprout::detail::strpbrk_impl_1(
|
||||
current,
|
||||
first2, n
|
||||
),
|
||||
first2, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR InputIterator1
|
||||
strpbrk(InputIterator1 first1, ForwardIterator2 first2) {
|
||||
typedef sprout::pair<InputIterator1, bool> type;
|
||||
return sprout::detail::strpbrk_impl(type(first1, false), first2, 1).first;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// 7.21.5.4 strpbrk ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR char const*
|
||||
strpbrk(char const* s1, char const* s2) {
|
||||
return !*s1 ? nullptr
|
||||
: sprout::strchr(s2, *s1) ? s1
|
||||
: sprout::strpbrk(s1 + 1, s2)
|
||||
;
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strpbrk(s1, s2)
|
||||
);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR char*
|
||||
strpbrk(char* s1, char const* s2) {
|
||||
return const_cast<char*>(sprout::strpbrk(const_cast<char const*>(s1), s2));
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strpbrk(s1, s2)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
Elem*
|
||||
>::type
|
||||
strpbrk(Elem* s1, typename std::remove_const<Elem>::type const* s2) {
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strpbrk(s1, s2)
|
||||
);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -1,24 +1,94 @@
|
|||
#ifndef SPROUT_CSTRING_STRRCHR_HPP
|
||||
#define SPROUT_CSTRING_STRRCHR_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/utility/pair.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
namespace detail {
|
||||
template<typename ForwardIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR ForwardIterator
|
||||
strrchr_impl_check(sprout::pair<ForwardIterator, ForwardIterator> const& found, T const& value) {
|
||||
return *found.second == value ? found.second
|
||||
: !value ? found.first
|
||||
: ForwardIterator()
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<ForwardIterator, ForwardIterator>
|
||||
strrchr_impl_1(
|
||||
sprout::pair<ForwardIterator, ForwardIterator> const& current,
|
||||
T const& value,
|
||||
typename std::iterator_traits<ForwardIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<ForwardIterator, ForwardIterator> type;
|
||||
return !*current.first ? current
|
||||
: n == 1 ? *current.first == value ? type(sprout::next(current.first), current.first) : type(sprout::next(current.first), current.second)
|
||||
: sprout::detail::strrchr_impl_1(
|
||||
sprout::detail::strrchr_impl_1(
|
||||
current,
|
||||
value, n / 2
|
||||
),
|
||||
value, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<ForwardIterator, ForwardIterator>
|
||||
strrchr_impl(
|
||||
sprout::pair<ForwardIterator, ForwardIterator> const& current,
|
||||
T const& value,
|
||||
typename std::iterator_traits<ForwardIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<ForwardIterator, ForwardIterator> type;
|
||||
return !*current.first ? current
|
||||
: sprout::detail::strrchr_impl(
|
||||
sprout::detail::strrchr_impl_1(
|
||||
current,
|
||||
value, n
|
||||
),
|
||||
value, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR ForwardIterator
|
||||
strrchr(ForwardIterator first, T const& value) {
|
||||
typedef sprout::pair<ForwardIterator, ForwardIterator> type;
|
||||
return sprout::detail::strrchr_impl_check(
|
||||
sprout::detail::strrchr_impl(type(first, first), value, 1),
|
||||
value
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// 7.21.5.5 strrchr ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
inline SPROUT_CONSTEXPR char const*
|
||||
strrchr(char const* s, int c) {
|
||||
return *s == static_cast<char>(c) && (!*s || !sprout::strrchr(s + 1, c))? s
|
||||
: !*s ? nullptr
|
||||
: sprout::strrchr(s + 1, c)
|
||||
;
|
||||
return sprout::detail::strrchr(s, static_cast<char>(c));
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR char*
|
||||
strrchr(char* s, int c) {
|
||||
return const_cast<char*>(sprout::strrchr(const_cast<char const*>(s), c));
|
||||
return sprout::detail::strrchr(s, static_cast<char>(c));
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
Elem*
|
||||
>::type
|
||||
strrchr(Elem* s, typename std::decay<Elem>::type c) {
|
||||
return sprout::detail::strrchr(s, c);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -2,16 +2,80 @@
|
|||
#define SPROUT_CSTRING_STRSPN_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/tuple/tuple.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
#include <sprout/cstring/strchr.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator1, std::size_t, bool>
|
||||
strspn_impl_1(
|
||||
sprout::tuples::tuple<InputIterator1, std::size_t, bool> const& current,
|
||||
ForwardIterator2 first2, typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, std::size_t, bool> type;
|
||||
return sprout::tuples::get<2>(current) || !*sprout::tuples::get<0>(current) ? current
|
||||
: n == 1 ? *sprout::detail::strchr(first2, *sprout::tuples::get<0>(current))
|
||||
? type(sprout::next(sprout::tuples::get<0>(current)), sprout::tuples::get<1>(current) + 1, false)
|
||||
: type(sprout::tuples::get<0>(current), sprout::tuples::get<1>(current), true)
|
||||
: sprout::detail::strspn_impl_1(
|
||||
sprout::detail::strspn_impl_1(
|
||||
current,
|
||||
first2, n / 2
|
||||
),
|
||||
first2, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator1, std::size_t, bool>
|
||||
strspn_impl(
|
||||
sprout::tuples::tuple<InputIterator1, std::size_t, bool> const& current,
|
||||
ForwardIterator2 first2, typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, std::size_t, bool> type;
|
||||
return sprout::tuples::get<2>(current) || !*sprout::tuples::get<0>(current) ? current
|
||||
: sprout::detail::strspn_impl(
|
||||
sprout::detail::strspn_impl_1(
|
||||
current,
|
||||
first2, n
|
||||
),
|
||||
first2, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
strspn(InputIterator1 first1, ForwardIterator2 first2) {
|
||||
typedef sprout::tuples::tuple<InputIterator1, std::size_t, bool> type;
|
||||
return sprout::tuples::get<1>(sprout::detail::strspn_impl(type(first1, 0, false), first2, 1));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// 7.21.5.6 strspn ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
strspn(char const* s1, char const* s2) {
|
||||
return !*s1 || !sprout::strchr(s2, *s1) ? 0
|
||||
: 1 + sprout::strspn(s1 + 1, s2)
|
||||
;
|
||||
return sprout::detail::strspn(s1, s2);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
std::size_t
|
||||
>::type
|
||||
strspn(Elem* s1, Elem* s2) {
|
||||
return sprout::detail::strspn(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -1,24 +1,154 @@
|
|||
#ifndef SPROUT_CSTRING_STRSTR_HPP
|
||||
#define SPROUT_CSTRING_STRSTR_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/utility/pair.hpp>
|
||||
#include <sprout/tuple/tuple.hpp>
|
||||
#include <sprout/type_traits/is_char_type.hpp>
|
||||
#include <sprout/detail/str.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
namespace detail {
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool>
|
||||
strstr_one_impl_1(
|
||||
sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> const& current,
|
||||
ForwardIterator1 first1_, typename std::iterator_traits<ForwardIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> type;
|
||||
return sprout::tuples::get<2>(current) ? current
|
||||
: !*sprout::tuples::get<1>(current) ? type(first1_, sprout::tuples::get<1>(current), true)
|
||||
: !*sprout::tuples::get<0>(current) ? type(sprout::tuples::get<0>(current), sprout::tuples::get<1>(current), true)
|
||||
: n == 1 ? !(*sprout::tuples::get<0>(current) == *sprout::tuples::get<1>(current))
|
||||
? type(sprout::next(sprout::tuples::get<0>(current)), sprout::tuples::get<1>(current), true)
|
||||
: type(sprout::next(sprout::tuples::get<0>(current)), sprout::next(sprout::tuples::get<1>(current)), false)
|
||||
: sprout::detail::strstr_one_impl_1(
|
||||
sprout::detail::strstr_one_impl_1(
|
||||
current,
|
||||
first1_, n / 2
|
||||
),
|
||||
first1_, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool>
|
||||
strstr_one_impl(
|
||||
sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> const& current,
|
||||
ForwardIterator1 first1_, typename std::iterator_traits<ForwardIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> type;
|
||||
return sprout::tuples::get<2>(current) ? current
|
||||
: !*sprout::tuples::get<1>(current) ? type(first1_, sprout::tuples::get<1>(current), true)
|
||||
: !*sprout::tuples::get<0>(current) ? type(sprout::tuples::get<0>(current), sprout::tuples::get<1>(current), true)
|
||||
: sprout::detail::strstr_one_impl(
|
||||
sprout::detail::strstr_one_impl_1(
|
||||
current,
|
||||
first1_, n
|
||||
),
|
||||
first1_, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR ForwardIterator1
|
||||
strstr_one(ForwardIterator1 first1, ForwardIterator2 first2) {
|
||||
typedef sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> type;
|
||||
return sprout::tuples::get<0>(sprout::detail::strstr_one_impl(type(first1, first2, false), first1, 1));
|
||||
}
|
||||
|
||||
template<typename ForwardIterator>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<ForwardIterator, bool>
|
||||
strstr_impl_fork(sprout::pair<ForwardIterator, bool> const& current, ForwardIterator searched) {
|
||||
typedef sprout::pair<ForwardIterator, bool> type;
|
||||
return searched == current.first || !*searched ? type(searched, true)
|
||||
: type(sprout::next(current.first), false)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<ForwardIterator1, bool>
|
||||
strstr_impl_1(
|
||||
sprout::pair<ForwardIterator1, bool> const& current,
|
||||
ForwardIterator2 first2,
|
||||
typename std::iterator_traits<ForwardIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<ForwardIterator1, bool> type;
|
||||
return current.second || !*current.first ? current
|
||||
: n == 1 ? sprout::detail::strstr_impl_fork(
|
||||
current,
|
||||
sprout::detail::strstr_one(current.first, first2)
|
||||
)
|
||||
: sprout::detail::strstr_impl_1(
|
||||
sprout::detail::strstr_impl_1(
|
||||
current,
|
||||
first2, n / 2
|
||||
),
|
||||
first2, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<ForwardIterator1, bool>
|
||||
strstr_impl(
|
||||
sprout::pair<ForwardIterator1, bool> const& current,
|
||||
ForwardIterator2 first2,
|
||||
typename std::iterator_traits<ForwardIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<ForwardIterator1, bool> type;
|
||||
return current.second || !*current.first ? current
|
||||
: sprout::detail::strstr_impl(
|
||||
sprout::detail::strstr_impl_1(
|
||||
current,
|
||||
first2, n
|
||||
),
|
||||
first2, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR ForwardIterator1
|
||||
strstr(ForwardIterator1 first1, ForwardIterator2 first2) {
|
||||
typedef sprout::pair<ForwardIterator1, bool> type;
|
||||
return !*first2 ? first1
|
||||
: sprout::detail::strstr_impl(type(first1, false), first2, 1).first
|
||||
;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// 7.21.5.7 strstr ŠÖ<C5A0>”
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR char const*
|
||||
strstr(char const* s1, char const* s2) {
|
||||
return !*s2 ? s1
|
||||
: !*s1 ? nullptr
|
||||
: *s1 == *s2 && sprout::strstr(s1 + 1, s2 + 1) ? s1
|
||||
: sprout::strstr(s1 + 1, s2)
|
||||
;
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strstr(s1, s2)
|
||||
);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR char*
|
||||
strstr(char* s1, char const* s2) {
|
||||
return const_cast<char*>(sprout::strstr(const_cast<char const*>(s1), s2));
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strstr(s1, s2)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_char_type<Elem>::value,
|
||||
Elem*
|
||||
>::type
|
||||
strstr(Elem* s1, typename std::remove_const<Elem>::type const* s2) {
|
||||
return sprout::detail::str_find_check(
|
||||
sprout::detail::strstr(s1, s2)
|
||||
);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -3,21 +3,22 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstring/strchr.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
|
||||
//
|
||||
// wcschr
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
inline SPROUT_CONSTEXPR wchar_t const*
|
||||
wcschr(wchar_t const* s, int c) {
|
||||
return *s == static_cast<wchar_t>(c) ? s
|
||||
: !*s ? nullptr
|
||||
: sprout::wcschr(s + 1, c)
|
||||
;
|
||||
wcschr(wchar_t const* s, wchar_t c) {
|
||||
return sprout::strchr(s, c);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR wchar_t*
|
||||
wcschr(wchar_t* s, int c) {
|
||||
return const_cast<wchar_t*>(sprout::wcschr(const_cast<wchar_t const*>(s), c));
|
||||
wcschr(wchar_t* s, wchar_t c) {
|
||||
return sprout::strchr(s, c);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -2,21 +2,18 @@
|
|||
#define SPROUT_CWCHAR_WCSCMP_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstring/strcmp.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
|
||||
//
|
||||
// wcscmp
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR int
|
||||
wcscmp(wchar_t const* s1, wchar_t const* s2) {
|
||||
return !*s1 && !*s2 ? 0
|
||||
: !*s1 ? -1
|
||||
: !*s2 ? 1
|
||||
: *s1 == *s2 ? sprout::wcscmp(s1 + 1, s2 + 1)
|
||||
: *s1 - *s2
|
||||
;
|
||||
return sprout::strcmp(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -2,17 +2,18 @@
|
|||
#define SPROUT_CWCHAR_WCSCOLL_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cwchar/wcscmp.hpp>
|
||||
#include <sprout/cstring/strcoll.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
|
||||
//
|
||||
// wcscoll
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR int
|
||||
wcscoll(wchar_t const* s1, wchar_t const* s2) {
|
||||
return sprout::wcscmp(s1, s2);
|
||||
return sprout::strcoll(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -3,17 +3,18 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cwchar/wcschr.hpp>
|
||||
#include <sprout/cstring/strcspn.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// wcscspn
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
wcscspn(wchar_t const* s1, wchar_t const* s2) {
|
||||
return !*s1 || sprout::wcschr(s2, *s1) ? 0
|
||||
: 1 + sprout::wcscspn(s1 + 1, s2)
|
||||
;
|
||||
return sprout::strcspn(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -3,27 +3,22 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/ptr_index_iterator.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/find.hpp>
|
||||
#include <sprout/cstring/strlen.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// wcslen
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
wcslen(wchar_t const* s) {
|
||||
return !*s ? 0
|
||||
: 1 + sprout::wcslen(s + 1)
|
||||
;
|
||||
return sprout::strlen(s);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
wcslen(wchar_t const* s, std::size_t n) {
|
||||
return sprout::distance(
|
||||
sprout::as_iterator(s),
|
||||
sprout::find(sprout::as_iterator(s), sprout::as_iterator(s, n), L'\0')
|
||||
);
|
||||
return sprout::strlen(s, n);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -3,19 +3,18 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/ptr_index_iterator.hpp>
|
||||
#include <sprout/algorithm/tristate_lexicographical_compare.hpp>
|
||||
#include <sprout/cstring/strncmp.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// wcsncmp
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR int
|
||||
wcsncmp(wchar_t const* s1, wchar_t const* s2, std::size_t n) {
|
||||
return sprout::tristate_lexicographical_compare(
|
||||
sprout::as_iterator(s1), sprout::as_iterator(s1, n), L'\0',
|
||||
sprout::as_iterator(s2), sprout::as_iterator(s2, n), L'\0'
|
||||
);
|
||||
return sprout::strncmp(s1, s2, n);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -3,25 +3,22 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cwchar/wcschr.hpp>
|
||||
#include <sprout/cstring/strpbrk.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
|
||||
//
|
||||
// wcspbrk
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR wchar_t const*
|
||||
wcspbrk(wchar_t const* s1, wchar_t const* s2) {
|
||||
return !*s1 ? nullptr
|
||||
: sprout::wcschr(s2, *s1) ? s1
|
||||
: sprout::wcspbrk(s1 + 1, s2)
|
||||
;
|
||||
return sprout::strpbrk(s1, s2);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR wchar_t*
|
||||
wcspbrk(wchar_t* s1, wchar_t const* s2) {
|
||||
return const_cast<wchar_t*>(sprout::wcspbrk(const_cast<wchar_t const*>(s1), s2));
|
||||
return sprout::strpbrk(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -3,24 +3,22 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstring/strrchr.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
|
||||
//
|
||||
// wcsrchr
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
inline SPROUT_CONSTEXPR wchar_t const*
|
||||
wcsrchr(wchar_t const* s, int c) {
|
||||
return *s == static_cast<wchar_t>(c) && (!*s || !sprout::wcsrchr(s + 1, c))? s
|
||||
: !*s ? nullptr
|
||||
: sprout::wcsrchr(s + 1, c)
|
||||
;
|
||||
wcsrchr(wchar_t const* s, wchar_t c) {
|
||||
return sprout::strrchr(s, c);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR wchar_t*
|
||||
wcsrchr(wchar_t* s, int c) {
|
||||
return const_cast<wchar_t*>(sprout::wcsrchr(const_cast<wchar_t const*>(s), c));
|
||||
wcsrchr(wchar_t* s, wchar_t c) {
|
||||
return sprout::strrchr(s, c);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -3,17 +3,18 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cwchar/wcschr.hpp>
|
||||
#include <sprout/cstring/strspn.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// wcsspn
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
wcsspn(wchar_t const* s1, wchar_t const* s2) {
|
||||
return !*s1 || !sprout::wcschr(s2, *s1) ? 0
|
||||
: 1 + sprout::wcsspn(s1 + 1, s2)
|
||||
;
|
||||
return sprout::strspn(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -2,22 +2,22 @@
|
|||
#define SPROUT_CWCHAR_WCSSTR_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/cstring/strstr.hpp>
|
||||
|
||||
namespace sprout {
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
|
||||
//
|
||||
// wcsstr
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log(N1+N2))
|
||||
//
|
||||
inline SPROUT_CONSTEXPR wchar_t const*
|
||||
wcsstr(wchar_t const* s1, wchar_t const* s2) {
|
||||
return !*s2 ? s1
|
||||
: !*s1 ? nullptr
|
||||
: *s1 == *s2 && sprout::wcsstr(s1 + 1, s2 + 1) ? s1
|
||||
: sprout::wcsstr(s1 + 1, s2)
|
||||
;
|
||||
return sprout::strstr(s1, s2);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR wchar_t*
|
||||
wcsstr(wchar_t* s1, wchar_t const* s2) {
|
||||
return const_cast<wchar_t*>(sprout::wcsstr(const_cast<wchar_t const*>(s1), s2));
|
||||
return sprout::strstr(s1, s2);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -89,9 +89,7 @@ namespace sprout {
|
|||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> type;
|
||||
return sprout::tuples::get<0>(
|
||||
sprout::detail::search_one_impl(type(first1, first2, false), last1, last2, pred, first1, 1)
|
||||
);
|
||||
return sprout::tuples::get<0>(sprout::detail::search_one_impl(type(first1, first2, false), last1, last2, pred, first1, 1));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
26
sprout/detail/str.hpp
Normal file
26
sprout/detail/str.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef SPROUT_DETAIL_STR_HPP
|
||||
#define SPROUT_DETAIL_STR_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR InputIterator
|
||||
str_find_check(InputIterator found) {
|
||||
return !*found ? InputIterator()
|
||||
: found
|
||||
;
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR InputIterator
|
||||
str_find_check(InputIterator found, T const& value) {
|
||||
return !(*found == value) && !*found ? InputIterator()
|
||||
: found
|
||||
;
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_DETAIL_STR_HPP
|
|
@ -10,6 +10,7 @@
|
|||
#include <sprout/algorithm/find_if.hpp>
|
||||
#include <sprout/algorithm/tristate_lexicographical_compare.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/cstring/strlen.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
|
@ -62,9 +63,7 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
static SPROUT_CONSTEXPR std::size_t length(char_type const* s) {
|
||||
return !*s ? 0
|
||||
: 1 + length(s + 1)
|
||||
;
|
||||
return sprout::detail::strlen(s);
|
||||
}
|
||||
static SPROUT_CONSTEXPR char_type const* find(char_type const* s, std::size_t n, char_type const& a) {
|
||||
return find_impl(
|
||||
|
@ -128,9 +127,7 @@ namespace sprout {
|
|||
}
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR std::size_t length(ConstIterator s) {
|
||||
return !*s ? 0
|
||||
: 1 + length(s + 1)
|
||||
;
|
||||
return sprout::detail::strlen(s);
|
||||
}
|
||||
template<typename ConstIterator>
|
||||
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
|
||||
|
|
Loading…
Reference in a new issue