From 7302bb4484d517a72cdffbd13ec7a9f2324cde01 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Sat, 29 Oct 2016 11:41:53 +0200 Subject: 8.6 --- zen/string_tools.h | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'zen/string_tools.h') diff --git a/zen/string_tools.h b/zen/string_tools.h index 525227d6..9b8e7328 100644 --- a/zen/string_tools.h +++ b/zen/string_tools.h @@ -56,7 +56,8 @@ template S printNumber(const T& format, const Num& //string to string conversion: converts string-like type into char-compatible target string class template T copyStringTo(S&& str); - +//case-sensitive comparison +template int cmpString(const S& lhs, const T& rhs); @@ -233,7 +234,7 @@ std::vector split(const S& str, const T& delimiter) const size_t delimLen = strLength(delimiter); if (delimLen == 0) - return { str }; + return { str }; else { const auto* const delimFirst = strBegin(delimiter); @@ -241,8 +242,8 @@ std::vector split(const S& str, const T& delimiter) const auto* blockStart = strBegin(str); const auto* const strLast = blockStart + strLength(str); - - std::vector output; + + std::vector output; for (;;) { @@ -251,7 +252,7 @@ std::vector split(const S& str, const T& delimiter) output.emplace_back(blockStart, blockEnd - blockStart); if (blockEnd == strLast) //clients expect: if delimiter not found, return str - return output; + return output; blockStart = blockEnd + delimLen; } } @@ -263,11 +264,11 @@ namespace impl ZEN_INIT_DETECT_MEMBER(append); //either call operator+=(S(str, len)) or append(str, len) -template inline -typename EnableIf::value>::Type stringAppend(S& str, const Char* other, size_t len) { str.append(other, len); } +template inline +typename EnableIf::value>::Type stringAppend(S& str, InputIterator first, InputIterator last) { str.append(first, last); } -template inline -typename EnableIf::value>::Type stringAppend(S& str, const Char* other, size_t len) { str += S(other, len); } +template inline +typename EnableIf::value>::Type stringAppend(S& str, InputIterator first, InputIterator last) { str += S(first, last); } } @@ -289,20 +290,20 @@ S replaceCpy(const S& str, const T& oldTerm, const U& newTerm, bool replaceAll) const auto* const oldBegin = strBegin(oldTerm); const auto* const oldEnd = oldBegin + oldLen; - //optimize "oldTerm not found" + //optimize "oldTerm not found": return ref-counted copy const auto* strMatch = std::search(strPos, strEnd, oldBegin, oldEnd); if (strMatch == strEnd) return str; - const size_t newLen = strLength(newTerm); const auto* const newBegin = strBegin(newTerm); + const auto* const newEnd = newBegin + strLength(newTerm); S output; for (;;) { - impl::stringAppend(output, strPos, strMatch - strPos); - impl::stringAppend(output, newBegin, newLen); + impl::stringAppend(output, strPos, strMatch); + impl::stringAppend(output, newBegin, newEnd); strPos = strMatch + oldLen; @@ -314,7 +315,7 @@ S replaceCpy(const S& str, const T& oldTerm, const U& newTerm, bool replaceAll) if (strMatch == strEnd) break; } - impl::stringAppend(output, strPos, strEnd - strPos); + impl::stringAppend(output, strPos, strEnd); return output; } @@ -380,6 +381,28 @@ template inline T copyStringTo(S&& str) { return impl::CopyStringToString, T>().copy(std::forward(str)); } +template inline +int cmpString(const S& lhs, const T& rhs) +{ + const size_t lenL = strLength(lhs); + const size_t lenR = strLength(rhs); + + const auto* strPosL = strBegin(lhs); + const auto* strPosR = strBegin(rhs); + + const auto* const strPosLLast = strPosL + std::min(lenL, lenR); + + while (strPosL != strPosLLast) + { + const auto charL = static_cast(*strPosL++); //unsigned char-comparison is the convention! + const auto charR = static_cast(*strPosR++); + if (charL != charR) + return static_cast(charL) - static_cast(charR); + } + return static_cast(lenL) - static_cast(lenR); +} + + namespace impl { template inline @@ -635,7 +658,6 @@ Num stringTo(const S& str) return impl::stringTo(str, TypeTag()); } - } #endif //STRING_TOOLS_H_213458973046 -- cgit