diff options
author | Oleksandr Koval <oleksandr.koval.dev@gmail.com> | 2020-09-03 20:25:37 (GMT) |
---|---|---|
committer | Oleksandr Koval <oleksandr.koval.dev@gmail.com> | 2020-09-03 20:25:37 (GMT) |
commit | 38928ee3ee40179ec4ad295c72cf5aaa213f617e (patch) | |
tree | 3201e3a0c612cbf6dab0bf9ca44e87c688ae21ec /Source/cmStringAlgorithms.cxx | |
parent | ca5babfd7a1da8e32f927ad086fdd91c2b09853b (diff) | |
download | CMake-38928ee3ee40179ec4ad295c72cf5aaa213f617e.zip CMake-38928ee3ee40179ec4ad295c72cf5aaa213f617e.tar.gz CMake-38928ee3ee40179ec4ad295c72cf5aaa213f617e.tar.bz2 |
cmStringAlgorithms: Add faster cmJoin overloads for strings
cmJoin() is often used with std::string ranges. Generic implementation
uses std::ostringstream which is not optimal. With strings we can avoid
operator<<() and make much faster implementation. Additional 'initial'
argument is useful for cmStringCommand.cxx:HandleAppendCommand().
Diffstat (limited to 'Source/cmStringAlgorithms.cxx')
-rw-r--r-- | Source/cmStringAlgorithms.cxx | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx index 71d28a4..e0af281 100644 --- a/Source/cmStringAlgorithms.cxx +++ b/Source/cmStringAlgorithms.cxx @@ -7,6 +7,7 @@ #include <cstddef> // IWYU pragma: keep #include <cstdio> #include <cstdlib> +#include <iterator> std::string cmTrimWhitespace(cm::string_view str) { @@ -323,3 +324,52 @@ bool cmStrToULong(std::string const& str, unsigned long* value) { return cmStrToULong(str.c_str(), value); } + +template <typename Range> +std::size_t getJoinedLength(Range const& rng, cm::string_view separator) +{ + std::size_t rangeLength{}; + for (auto const& item : rng) { + rangeLength += item.size(); + } + + auto const separatorsLength = (rng.size() - 1) * separator.size(); + + return rangeLength + separatorsLength; +} + +template <typename Range> +std::string cmJoinImpl(Range const& rng, cm::string_view separator, + cm::string_view initial) +{ + if (rng.empty()) { + return { std::begin(initial), std::end(initial) }; + } + + std::string result; + result.reserve(initial.size() + getJoinedLength(rng, separator)); + result.append(std::begin(initial), std::end(initial)); + + auto begin = std::begin(rng); + auto end = std::end(rng); + result += *begin; + + for (++begin; begin != end; ++begin) { + result.append(std::begin(separator), std::end(separator)); + result += *begin; + } + + return result; +} + +std::string cmJoin(std::vector<std::string> const& rng, + cm::string_view separator, cm::string_view initial) +{ + return cmJoinImpl(rng, separator, initial); +} + +std::string cmJoin(cmStringRange const& rng, cm::string_view separator, + cm::string_view initial) +{ + return cmJoinImpl(rng, separator, initial); +} |