diff --git a/sprout/algorithm/search.hpp b/sprout/algorithm/search.hpp index 648f307e..093e21f4 100644 --- a/sprout/algorithm/search.hpp +++ b/sprout/algorithm/search.hpp @@ -56,7 +56,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::pair - search_impl_check(sprout::pair const& current, ForwardIterator1 last1, ForwardIterator1 searched) { + search_impl_fork(sprout::pair const& current, ForwardIterator1 last1, ForwardIterator1 searched) { typedef sprout::pair 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 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) ) diff --git a/sprout/algorithm/tristate_lexicographical_compare.hpp b/sprout/algorithm/tristate_lexicographical_compare.hpp index 8ceea0c3..0956e117 100644 --- a/sprout/algorithm/tristate_lexicographical_compare.hpp +++ b/sprout/algorithm/tristate_lexicographical_compare.hpp @@ -87,7 +87,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::pair tristate_lexicographical_compare_impl_1( - sprout::pair current, + sprout::pair const& current, InputIterator1 last1, InputIterator2 last2, Compare comp, typename std::iterator_traits::difference_type n ) @@ -109,7 +109,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::pair tristate_lexicographical_compare_impl( - sprout::pair current, + sprout::pair const& current, InputIterator1 last1, InputIterator2 last2, Compare comp, typename std::iterator_traits::difference_type n ) @@ -252,7 +252,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::pair tristate_lexicographical_compare_impl_1( - sprout::pair current, + sprout::pair const& current, InputIterator1 last1, T1 const& delim1, InputIterator2 last2, T2 const& delim2, Compare comp, typename std::iterator_traits::difference_type n ) @@ -276,7 +276,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR sprout::pair tristate_lexicographical_compare_impl( - sprout::pair current, + sprout::pair const& current, InputIterator1 last1, T1 const& delim1, InputIterator2 last2, T2 const& delim2, Compare comp, typename std::iterator_traits::difference_type n ) diff --git a/sprout/cstring/strchr.hpp b/sprout/cstring/strchr.hpp index b243877f..be629a80 100644 --- a/sprout/cstring/strchr.hpp +++ b/sprout/cstring/strchr.hpp @@ -1,24 +1,92 @@ #ifndef SPROUT_CSTRING_STRCHR_HPP #define SPROUT_CSTRING_STRCHR_HPP -#include +#include +#include #include +#include +#include +#include +#include namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::pair + strchr_impl_1( + sprout::pair const& current, + T const& value, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair 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 + inline SPROUT_CONSTEXPR sprout::pair + strchr_impl( + sprout::pair const& current, + T const& value, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair type; + return current.second || !*current.first ? current + : sprout::detail::strchr_impl( + sprout::detail::strchr_impl_1( + current, + value, n + ), + value, n * 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR InputIterator + strchr(InputIterator first, T const& value) { + typedef sprout::pair type; + return sprout::detail::strchr_impl(type(first, false), value, 1).first; + } + + } // namespace detail // 7.21.5.2 strchr 関数 + // + // recursion depth: + // O(log N) + // inline SPROUT_CONSTEXPR char const* strchr(char const* s, int c) { - return *s == static_cast(c) ? s - : !*s ? nullptr - : sprout::strchr(s + 1, c) - ; + return sprout::detail::str_find_check( + sprout::detail::strchr(s, static_cast(c)), + static_cast(c) + ); } - inline SPROUT_CONSTEXPR char* strchr(char* s, int c) { - return const_cast(sprout::strchr(const_cast(s), c)); + return sprout::detail::str_find_check( + sprout::detail::strchr(s, static_cast(c)), + static_cast(c) + ); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + Elem* + >::type + strchr(Elem* s, typename std::decay::type c) { + return sprout::detail::str_find_check( + sprout::detail::strchr(s, c), + c + ); } } // namespace sprout diff --git a/sprout/cstring/strcmp.hpp b/sprout/cstring/strcmp.hpp index 6c248fdc..48cc9703 100644 --- a/sprout/cstring/strcmp.hpp +++ b/sprout/cstring/strcmp.hpp @@ -1,20 +1,91 @@ #ifndef SPROUT_CSTRING_STRCMP_HPP #define SPROUT_CSTRING_STRCMP_HPP +#include +#include #include +#include +#include +#include +#include namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR int + strcmp_impl_check(sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR sprout::tuples::tuple + strcmp_impl_1( + sprout::tuples::tuple const& current, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR sprout::tuples::tuple + strcmp_impl( + sprout::tuples::tuple const& current, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR int + strcmp(InputIterator1 first1, InputIterator2 first2) + { + typedef sprout::tuples::tuple type; + return sprout::detail::strcmp_impl_check( + sprout::detail::strcmp_impl(type(first1, first2, 0), 1) + ); + } + } // namespace detail // 7.21.4.2 strcmp 関数 + // + // 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(*s1) - static_cast(*s2) - ; + return sprout::detail::strcmp(s1, s2); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + int + >::type + strcmp(Elem* s1, Elem* s2) { + return sprout::detail::strcmp(s1, s2); } } // namespace sprout diff --git a/sprout/cstring/strcoll.hpp b/sprout/cstring/strcoll.hpp index eeb20e6d..344922a7 100644 --- a/sprout/cstring/strcoll.hpp +++ b/sprout/cstring/strcoll.hpp @@ -1,17 +1,30 @@ #ifndef SPROUT_CSTRING_STRCOLL_HPP #define SPROUT_CSTRING_STRCOLL_HPP +#include #include +#include #include namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) - // 7.21.4.3 strcoll 関数 + // + // recursion depth: + // O(log(N1+N2)) + // inline SPROUT_CONSTEXPR int strcoll(char const* s1, char const* s2) { return sprout::strcmp(s1, s2); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + int + >::type + strcoll(Elem* s1, Elem* s2) { + return sprout::strcmp(s1, s2); + } } // namespace sprout #endif // #ifndef SPROUT_CSTRING_STRCOLL_HPP diff --git a/sprout/cstring/strcspn.hpp b/sprout/cstring/strcspn.hpp index cbb620b2..8a5cf43c 100644 --- a/sprout/cstring/strcspn.hpp +++ b/sprout/cstring/strcspn.hpp @@ -2,16 +2,80 @@ #define SPROUT_CSTRING_STRCSPN_HPP #include +#include +#include #include +#include +#include +#include #include namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple + strcspn_impl_1( + sprout::tuples::tuple const& current, + ForwardIterator2 first2, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR sprout::tuples::tuple + strcspn_impl( + sprout::tuples::tuple const& current, + ForwardIterator2 first2, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR std::size_t + strcspn(InputIterator1 first1, ForwardIterator2 first2) { + typedef sprout::tuples::tuple type; + return sprout::tuples::get<1>(sprout::detail::strcspn_impl(type(first1, 0, false), first2, 1)); + } + } // namespace detail + // 7.21.5.3 strcspn 関数 + // + // 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 + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + std::size_t + >::type + strcspn(Elem* s1, Elem* s2) { + return sprout::detail::strcspn(s1, s2); } } // namespace sprout diff --git a/sprout/cstring/strlen.hpp b/sprout/cstring/strlen.hpp index 9d9a4ca6..5923d8b4 100644 --- a/sprout/cstring/strlen.hpp +++ b/sprout/cstring/strlen.hpp @@ -2,20 +2,71 @@ #define SPROUT_CSTRING_STRLEN_HPP #include +#include +#include #include -#include #include +#include +#include +#include #include namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::pair + strlen_impl_1( + sprout::pair const& current, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair 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 + inline SPROUT_CONSTEXPR sprout::pair + strlen_impl( + sprout::pair const& current, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair type; + return !*current.first ? current + : sprout::detail::strlen_impl( + sprout::detail::strlen_impl_1( + current, + n + ), + n * 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR std::size_t + strlen(InputIterator first) { + typedef sprout::pair type; + return sprout::detail::strlen_impl(type(first, 0), 1).second; + } + } // namespace detail + // 7.21.6.3 strlen 関数 + // + // 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 + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + std::size_t + >::type + strlen(Elem* s) { + return sprout::detail::strlen(s); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + std::size_t + >::type + strlen(Elem* s, std::size_t n) { + typedef typename std::decay::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 diff --git a/sprout/cstring/strncmp.hpp b/sprout/cstring/strncmp.hpp index b213f823..e1d4dbdf 100644 --- a/sprout/cstring/strncmp.hpp +++ b/sprout/cstring/strncmp.hpp @@ -2,12 +2,18 @@ #define SPROUT_CSTRING_STRNCMP_HPP #include +#include #include #include +#include #include namespace sprout { // 7.21.4.4 strncmp 関数 + // + // 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 + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + int + >::type + strncmp(Elem* s1, Elem* s2, std::size_t n) { + typedef typename std::decay::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 diff --git a/sprout/cstring/strpbrk.hpp b/sprout/cstring/strpbrk.hpp index d51592ac..dc86263e 100644 --- a/sprout/cstring/strpbrk.hpp +++ b/sprout/cstring/strpbrk.hpp @@ -1,25 +1,93 @@ #ifndef SPROUT_CSTRING_STRPBRK_HPP #define SPROUT_CSTRING_STRPBRK_HPP -#include +#include +#include #include +#include +#include +#include #include +#include namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::pair + strpbrk_impl_1( + sprout::pair current, + ForwardIterator2 first2, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair 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 + inline SPROUT_CONSTEXPR sprout::pair + strpbrk_impl( + sprout::pair current, + ForwardIterator2 first2, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair type; + return current.second || !*current.first ? current + : sprout::detail::strpbrk_impl( + sprout::detail::strpbrk_impl_1( + current, + first2, n + ), + first2, n * 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR InputIterator1 + strpbrk(InputIterator1 first1, ForwardIterator2 first2) { + typedef sprout::pair type; + return sprout::detail::strpbrk_impl(type(first1, false), first2, 1).first; + } + } // namespace detail // 7.21.5.4 strpbrk 関数 + // + // 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(sprout::strpbrk(const_cast(s1), s2)); + return sprout::detail::str_find_check( + sprout::detail::strpbrk(s1, s2) + ); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + Elem* + >::type + strpbrk(Elem* s1, typename std::remove_const::type const* s2) { + return sprout::detail::str_find_check( + sprout::detail::strpbrk(s1, s2) + ); } } // namespace sprout diff --git a/sprout/cstring/strrchr.hpp b/sprout/cstring/strrchr.hpp index 54c58601..1d67fb38 100644 --- a/sprout/cstring/strrchr.hpp +++ b/sprout/cstring/strrchr.hpp @@ -1,24 +1,94 @@ #ifndef SPROUT_CSTRING_STRRCHR_HPP #define SPROUT_CSTRING_STRRCHR_HPP -#include +#include +#include #include +#include +#include +#include namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR ForwardIterator + strrchr_impl_check(sprout::pair const& found, T const& value) { + return *found.second == value ? found.second + : !value ? found.first + : ForwardIterator() + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + strrchr_impl_1( + sprout::pair const& current, + T const& value, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair 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 + inline SPROUT_CONSTEXPR sprout::pair + strrchr_impl( + sprout::pair const& current, + T const& value, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair type; + return !*current.first ? current + : sprout::detail::strrchr_impl( + sprout::detail::strrchr_impl_1( + current, + value, n + ), + value, n * 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR ForwardIterator + strrchr(ForwardIterator first, T const& value) { + typedef sprout::pair type; + return sprout::detail::strrchr_impl_check( + sprout::detail::strrchr_impl(type(first, first), value, 1), + value + ); + } + } // namespace detail // 7.21.5.5 strrchr 関数 + // + // recursion depth: + // O(log N) + // inline SPROUT_CONSTEXPR char const* strrchr(char const* s, int c) { - return *s == static_cast(c) && (!*s || !sprout::strrchr(s + 1, c))? s - : !*s ? nullptr - : sprout::strrchr(s + 1, c) - ; + return sprout::detail::strrchr(s, static_cast(c)); } - inline SPROUT_CONSTEXPR char* strrchr(char* s, int c) { - return const_cast(sprout::strrchr(const_cast(s), c)); + return sprout::detail::strrchr(s, static_cast(c)); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + Elem* + >::type + strrchr(Elem* s, typename std::decay::type c) { + return sprout::detail::strrchr(s, c); } } // namespace sprout diff --git a/sprout/cstring/strspn.hpp b/sprout/cstring/strspn.hpp index ab2a061b..3e75926c 100644 --- a/sprout/cstring/strspn.hpp +++ b/sprout/cstring/strspn.hpp @@ -2,16 +2,80 @@ #define SPROUT_CSTRING_STRSPN_HPP #include +#include +#include #include +#include +#include +#include #include namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple + strspn_impl_1( + sprout::tuples::tuple const& current, + ForwardIterator2 first2, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR sprout::tuples::tuple + strspn_impl( + sprout::tuples::tuple const& current, + ForwardIterator2 first2, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR std::size_t + strspn(InputIterator1 first1, ForwardIterator2 first2) { + typedef sprout::tuples::tuple type; + return sprout::tuples::get<1>(sprout::detail::strspn_impl(type(first1, 0, false), first2, 1)); + } + } // namespace detail + // 7.21.5.6 strspn 関数 + // + // 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 + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + std::size_t + >::type + strspn(Elem* s1, Elem* s2) { + return sprout::detail::strspn(s1, s2); } } // namespace sprout diff --git a/sprout/cstring/strstr.hpp b/sprout/cstring/strstr.hpp index 1e91ea04..95225fbf 100644 --- a/sprout/cstring/strstr.hpp +++ b/sprout/cstring/strstr.hpp @@ -1,24 +1,154 @@ #ifndef SPROUT_CSTRING_STRSTR_HPP #define SPROUT_CSTRING_STRSTR_HPP +#include +#include #include +#include +#include +#include +#include +#include namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple + strstr_one_impl_1( + sprout::tuples::tuple const& current, + ForwardIterator1 first1_, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR sprout::tuples::tuple + strstr_one_impl( + sprout::tuples::tuple const& current, + ForwardIterator1 first1_, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple 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 + inline SPROUT_CONSTEXPR ForwardIterator1 + strstr_one(ForwardIterator1 first1, ForwardIterator2 first2) { + typedef sprout::tuples::tuple type; + return sprout::tuples::get<0>(sprout::detail::strstr_one_impl(type(first1, first2, false), first1, 1)); + } + + template + inline SPROUT_CONSTEXPR sprout::pair + strstr_impl_fork(sprout::pair const& current, ForwardIterator searched) { + typedef sprout::pair type; + return searched == current.first || !*searched ? type(searched, true) + : type(sprout::next(current.first), false) + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + strstr_impl_1( + sprout::pair const& current, + ForwardIterator2 first2, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair 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 + inline SPROUT_CONSTEXPR sprout::pair + strstr_impl( + sprout::pair const& current, + ForwardIterator2 first2, + typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair type; + return current.second || !*current.first ? current + : sprout::detail::strstr_impl( + sprout::detail::strstr_impl_1( + current, + first2, n + ), + first2, n * 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR ForwardIterator1 + strstr(ForwardIterator1 first1, ForwardIterator2 first2) { + typedef sprout::pair type; + return !*first2 ? first1 + : sprout::detail::strstr_impl(type(first1, false), first2, 1).first + ; + } + } // namespace detail // 7.21.5.7 strstr 関数 + // + // 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(sprout::strstr(const_cast(s1), s2)); + return sprout::detail::str_find_check( + sprout::detail::strstr(s1, s2) + ); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_char_type::value, + Elem* + >::type + strstr(Elem* s1, typename std::remove_const::type const* s2) { + return sprout::detail::str_find_check( + sprout::detail::strstr(s1, s2) + ); } } // namespace sprout diff --git a/sprout/cwchar/wcschr.hpp b/sprout/cwchar/wcschr.hpp index 118c556e..b6ea28fa 100644 --- a/sprout/cwchar/wcschr.hpp +++ b/sprout/cwchar/wcschr.hpp @@ -3,21 +3,22 @@ #include #include +#include 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(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(sprout::wcschr(const_cast(s), c)); + wcschr(wchar_t* s, wchar_t c) { + return sprout::strchr(s, c); } } // namespace sprout diff --git a/sprout/cwchar/wcscmp.hpp b/sprout/cwchar/wcscmp.hpp index 96baded0..0eba5c0b 100644 --- a/sprout/cwchar/wcscmp.hpp +++ b/sprout/cwchar/wcscmp.hpp @@ -2,21 +2,18 @@ #define SPROUT_CWCHAR_WCSCMP_HPP #include +#include 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 diff --git a/sprout/cwchar/wcscoll.hpp b/sprout/cwchar/wcscoll.hpp index 45b6f338..9e6134a6 100644 --- a/sprout/cwchar/wcscoll.hpp +++ b/sprout/cwchar/wcscoll.hpp @@ -2,17 +2,18 @@ #define SPROUT_CWCHAR_WCSCOLL_HPP #include -#include +#include 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 diff --git a/sprout/cwchar/wcscspn.hpp b/sprout/cwchar/wcscspn.hpp index fe68b86e..a1f7f384 100644 --- a/sprout/cwchar/wcscspn.hpp +++ b/sprout/cwchar/wcscspn.hpp @@ -3,17 +3,18 @@ #include #include -#include +#include 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 diff --git a/sprout/cwchar/wcslen.hpp b/sprout/cwchar/wcslen.hpp index ce6440f3..c2a7211e 100644 --- a/sprout/cwchar/wcslen.hpp +++ b/sprout/cwchar/wcslen.hpp @@ -3,27 +3,22 @@ #include #include -#include -#include -#include +#include 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 diff --git a/sprout/cwchar/wcsncmp.hpp b/sprout/cwchar/wcsncmp.hpp index 1973ab39..f214448d 100644 --- a/sprout/cwchar/wcsncmp.hpp +++ b/sprout/cwchar/wcsncmp.hpp @@ -3,19 +3,18 @@ #include #include -#include -#include +#include 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 diff --git a/sprout/cwchar/wcspbrk.hpp b/sprout/cwchar/wcspbrk.hpp index 6ac95b1a..408d8f63 100644 --- a/sprout/cwchar/wcspbrk.hpp +++ b/sprout/cwchar/wcspbrk.hpp @@ -3,25 +3,22 @@ #include #include -#include +#include 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(sprout::wcspbrk(const_cast(s1), s2)); + return sprout::strpbrk(s1, s2); } } // namespace sprout diff --git a/sprout/cwchar/wcsrchr.hpp b/sprout/cwchar/wcsrchr.hpp index e5561e5f..b63097fd 100644 --- a/sprout/cwchar/wcsrchr.hpp +++ b/sprout/cwchar/wcsrchr.hpp @@ -3,24 +3,22 @@ #include #include +#include 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(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(sprout::wcsrchr(const_cast(s), c)); + wcsrchr(wchar_t* s, wchar_t c) { + return sprout::strrchr(s, c); } } // namespace sprout diff --git a/sprout/cwchar/wcsspn.hpp b/sprout/cwchar/wcsspn.hpp index a636e3d0..cd43e62a 100644 --- a/sprout/cwchar/wcsspn.hpp +++ b/sprout/cwchar/wcsspn.hpp @@ -3,17 +3,18 @@ #include #include -#include +#include 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 diff --git a/sprout/cwchar/wcsstr.hpp b/sprout/cwchar/wcsstr.hpp index add4f69c..1b97efca 100644 --- a/sprout/cwchar/wcsstr.hpp +++ b/sprout/cwchar/wcsstr.hpp @@ -2,22 +2,22 @@ #define SPROUT_CWCHAR_WCSSTR_HPP #include +#include 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(sprout::wcsstr(const_cast(s1), s2)); + return sprout::strstr(s1, s2); } } // namespace sprout diff --git a/sprout/detail/algorithm/search_one.hpp b/sprout/detail/algorithm/search_one.hpp index ac035102..45f6d0b0 100644 --- a/sprout/detail/algorithm/search_one.hpp +++ b/sprout/detail/algorithm/search_one.hpp @@ -89,9 +89,7 @@ namespace sprout { ) { typedef sprout::tuples::tuple 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)); } // diff --git a/sprout/detail/str.hpp b/sprout/detail/str.hpp new file mode 100644 index 00000000..cb3ee8ef --- /dev/null +++ b/sprout/detail/str.hpp @@ -0,0 +1,26 @@ +#ifndef SPROUT_DETAIL_STR_HPP +#define SPROUT_DETAIL_STR_HPP + +#include + +namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR InputIterator + str_find_check(InputIterator found) { + return !*found ? InputIterator() + : found + ; + } + + template + 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 diff --git a/sprout/string/char_traits.hpp b/sprout/string/char_traits.hpp index 617b1b0a..f2bfccef 100644 --- a/sprout/string/char_traits.hpp +++ b/sprout/string/char_traits.hpp @@ -10,6 +10,7 @@ #include #include #include +#include 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 static SPROUT_CONSTEXPR std::size_t length(ConstIterator s) { - return !*s ? 0 - : 1 + length(s + 1) - ; + return sprout::detail::strlen(s); } template static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {