diff --git a/sprout/algorithm/tristate_lexicographical_compare.hpp b/sprout/algorithm/tristate_lexicographical_compare.hpp index 9c2f911c..e750defd 100644 --- a/sprout/algorithm/tristate_lexicographical_compare.hpp +++ b/sprout/algorithm/tristate_lexicographical_compare.hpp @@ -130,6 +130,143 @@ namespace sprout { sprout::less<>() ); } + + namespace detail { + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare_2_impl_ra_2( + RandomAccessIterator1 last1, T1 const& delim1, RandomAccessIterator2 last2, T2 const& delim2, Compare comp, + sprout::pair const& found + ) + { + return found.second == last2 || (!comp(*found.second, delim2) && !comp(delim2, *found.second)) + ? (found.first == last1 || (!comp(*found.first, delim1) && !comp(delim1, *found.first)) ? 0 : 1) + : found.first == last1 || (!comp(*found.first, delim1) && !comp(delim1, *found.first)) ? -1 + : comp(*found.first, *found.second) ? -1 + : comp(*found.second, *found.first) ? 1 + : 0 + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + tristate_lexicographical_compare_2_impl_ra_1( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, T1 const& delim1, + RandomAccessIterator2 first2, RandomAccessIterator2 last2, T2 const& delim2, + Compare comp, + typename std::iterator_traits::difference_type pivot, sprout::pair const& found + ) + { + typedef sprout::pair found_type; + return found.first != first1 ? found + : pivot == 0 ? ( + comp(*first1, *first2) || comp(*first2, *first1) || (!comp(*first1, delim1) && !comp(delim1, *first1)) || (!comp(*first2, delim2) && !comp(delim2, *first2)) + ? found_type(first1, first2) : found_type(last1, last2) + ) + : sprout::detail::tristate_lexicographical_compare_2_impl_ra_1( + sprout::next(first1, pivot), last1, delim1, sprout::next(first2, pivot), last2, delim2, comp, + (NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2, + sprout::detail::tristate_lexicographical_compare_2_impl_ra_1( + first1, sprout::next(first1, pivot), delim1, first2, sprout::next(first2, pivot), delim2, comp, + pivot / 2, + found_type(first1, first2) + ) + ) + ; + } + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare_2_impl_ra( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, T1 const& delim1, + RandomAccessIterator2 first2, RandomAccessIterator2 last2, T2 const& delim2, + Compare comp, + typename std::iterator_traits::difference_type size + ) + { + typedef sprout::pair found_type; + return sprout::detail::tristate_lexicographical_compare_2_impl_ra_2( + last1, delim1, last2, delim2, comp, + sprout::detail::tristate_lexicographical_compare_2_impl_ra_1( + first1, sprout::next(first1, size), delim1, first2, sprout::next(first2, size), delim2, comp, + size / 2, found_type(first1, first2) + ) + ); + } + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare_2( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, T1 const& delim1, + RandomAccessIterator2 first2, RandomAccessIterator2 last2, T2 const& delim2, + Compare comp, + std::random_access_iterator_tag* + ) + { + return first2 == last2 || (!comp(*first2, delim2) && !comp(delim2, *first2)) ? (first1 == last1 || (!comp(*first1, delim1) && !comp(delim1, *first1)) ? 0 : 1) + : first1 == last1 || (!comp(*first1, delim1) && !comp(delim1, *first1)) ? -1 + : sprout::detail::tristate_lexicographical_compare_2_impl_ra( + first1, last1, delim1, first2, last2, delim2, comp, + sprout::min(NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1), NS_SSCRISK_CEL_OR_SPROUT::distance(first2, last2)) + ) + ; + } + + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare_2_impl( + InputIterator1 first1, InputIterator1 last1, T1 const& delim1, + InputIterator2 first2, InputIterator2 last2, T2 const& delim2, + Compare comp + ) + { + return first2 == last2 || (!comp(*first2, delim2) && !comp(delim2, *first2)) ? (first1 == last1 || (!comp(*first1, delim1) && !comp(delim1, *first1)) ? 0 : 1) + : first1 == last1 || (!comp(*first1, delim1) && !comp(delim1, *first1)) || comp(*first1, *first2) ? -1 + : comp(*first2, *first1) ? 1 + : sprout::detail::tristate_lexicographical_compare_2_impl(sprout::next(first1), last1, delim1, sprout::next(first2), last2, delim2, comp) + ; + } + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare_2( + InputIterator1 first1, InputIterator1 last1, T1 const& delim1, + InputIterator2 first2, InputIterator2 last2, T2 const& delim2, + Compare comp, + void* + ) + { + return sprout::detail::tristate_lexicographical_compare_2_impl(first1, last1, delim1, first2, last2, delim2, comp); + } + } //namespace detail + + // + // tristate_lexicographical_compare + // + // recursion depth: + // [first1, last1), [first2, last2) are RandomAccessIterator -> O(log N) + // otherwise -> O(N) + // + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare( + InputIterator1 first1, InputIterator1 last1, T1 const& delim1, + InputIterator2 first2, InputIterator2 last2, T2 const& delim2, + Compare comp + ) + { + typedef typename sprout::common_iterator_category::type* category; + return sprout::detail::tristate_lexicographical_compare_2(first1, last1, delim1, first2, last2, delim2, comp, category()); + } + + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare( + InputIterator1 first1, InputIterator1 last1, T1 const& delim1, + InputIterator2 first2, InputIterator2 last2, T2 const& delim2 + ) + { + return sprout::tristate_lexicographical_compare( + first1, last1, delim1, first2, last2, delim2, + sprout::less<>() + ); + } } // namespace sprout #endif // #ifndef SPROUT_ALGORITHM_TRISTATE_LEXICOGRAPHICAL_COMPARE_HPP diff --git a/sprout/cstring/strncmp.hpp b/sprout/cstring/strncmp.hpp index 56bac73a..e2ed314e 100644 --- a/sprout/cstring/strncmp.hpp +++ b/sprout/cstring/strncmp.hpp @@ -5,7 +5,6 @@ #include #include #include -#include #include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT namespace sprout { @@ -13,8 +12,8 @@ namespace sprout { inline SPROUT_CONSTEXPR int strncmp(char const* s1, char const* s2, std::size_t n) { return sprout::tristate_lexicographical_compare( - sprout::as_iterator(s1), sprout::as_iterator(s1, sprout::strlen(s1, n)), - sprout::as_iterator(s2), sprout::as_iterator(s2, sprout::strlen(s2, n)) + sprout::as_iterator(s1), sprout::as_iterator(s1, n), '\0', + sprout::as_iterator(s2), sprout::as_iterator(s2, n), '\0' ); } } // namespace sprout diff --git a/sprout/cwchar/wcsncmp.hpp b/sprout/cwchar/wcsncmp.hpp index ecf7c083..5ea05182 100644 --- a/sprout/cwchar/wcsncmp.hpp +++ b/sprout/cwchar/wcsncmp.hpp @@ -5,7 +5,6 @@ #include #include #include -#include #include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT namespace sprout { @@ -15,8 +14,8 @@ namespace sprout { 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, sprout::wcslen(s1, n)), - sprout::as_iterator(s2), sprout::as_iterator(s2, sprout::wcslen(s2, n)) + sprout::as_iterator(s1), sprout::as_iterator(s1, n), L'\0', + sprout::as_iterator(s2), sprout::as_iterator(s2, n), L'\0' ); } } // namespace sprout diff --git a/sprout/range/algorithm/tristate_lexicographical_compare.hpp b/sprout/range/algorithm/tristate_lexicographical_compare.hpp index b36dae78..825eccd2 100644 --- a/sprout/range/algorithm/tristate_lexicographical_compare.hpp +++ b/sprout/range/algorithm/tristate_lexicographical_compare.hpp @@ -25,6 +25,22 @@ namespace sprout { sprout::begin(range1), sprout::end(range1), sprout::begin(range2), sprout::end(range2), comp ); } + + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare(Range1 const& range1, T1 const& delim1, Range2 const& range2, T2 const& delim2) { + return sprout::tristate_lexicographical_compare( + sprout::begin(range1), sprout::end(range1), delim1, sprout::begin(range2), sprout::end(range2), delim2 + ); + } + + template + inline SPROUT_CONSTEXPR int + tristate_lexicographical_compare(Range1 const& range1, T1 const& delim1, Range2 const& range2, T2 const& delim2, Compare comp) { + return sprout::tristate_lexicographical_compare( + sprout::begin(range1), sprout::end(range1), delim1, sprout::begin(range2), sprout::end(range2), delim2, comp + ); + } } // namespace range } // namespace sprout diff --git a/sprout/string/char_traits.hpp b/sprout/string/char_traits.hpp index 46798a23..b7803143 100644 --- a/sprout/string/char_traits.hpp +++ b/sprout/string/char_traits.hpp @@ -44,13 +44,6 @@ namespace sprout { : found ; } - template - static SPROUT_CONSTEXPR std::size_t len(Iterator s, std::size_t n) { - return NS_SSCRISK_CEL_OR_SPROUT::distance( - s, - NS_SSCRISK_CEL_OR_SPROUT::find(s, s + n, char_type()) - ); - } public: static void assign(char_type& c1, char_type const& c2) SPROUT_NOEXCEPT { impl_type::assign(c1, c2); @@ -63,8 +56,8 @@ namespace sprout { } static SPROUT_CONSTEXPR int compare(char_type const* s1, char_type const* s2, std::size_t n) { return sprout::tristate_lexicographical_compare( - sprout::as_iterator(s1), sprout::as_iterator(s1, len(sprout::as_iterator(s1), n)), - sprout::as_iterator(s2), sprout::as_iterator(s2, len(sprout::as_iterator(s2), n)), + sprout::as_iterator(s1), sprout::as_iterator(s1, n), char_type(), + sprout::as_iterator(s2), sprout::as_iterator(s2, n), char_type(), lt_() ); } @@ -112,24 +105,24 @@ namespace sprout { template static SPROUT_CONSTEXPR int compare(char_type const* s1, ConstIterator s2, std::size_t n) { return sprout::tristate_lexicographical_compare( - sprout::as_iterator(s1), sprout::as_iterator(s1, len(sprout::as_iterator(s1), n)), - s2, s2 + n, + sprout::as_iterator(s1), sprout::as_iterator(s1, n), char_type(), + s2, s2 + n, char_type(), lt_() ); } template static SPROUT_CONSTEXPR int compare(ConstIterator s1, char_type const* s2, std::size_t n) { return sprout::tristate_lexicographical_compare( - s1, s1 + n, - sprout::as_iterator(s2), sprout::as_iterator(s2, len(sprout::as_iterator(s2), n)), + s1, s1 + n, char_type(), + sprout::as_iterator(s2), sprout::as_iterator(s2, n), char_type(), lt_() ); } template static SPROUT_CONSTEXPR int compare(ConstIterator1 s1, ConstIterator2 s2, std::size_t n) { return sprout::tristate_lexicographical_compare( - s1, s1 + n, - s2, s2 + n, + s1, s1 + n, char_type(), + s2, s2 + n, char_type(), lt_() ); }