summaryrefslogtreecommitdiffstats
path: root/Source/cmStringAlgorithms.cxx
diff options
context:
space:
mode:
authorOleksandr Koval <oleksandr.koval.dev@gmail.com>2020-09-03 20:25:37 (GMT)
committerOleksandr Koval <oleksandr.koval.dev@gmail.com>2020-09-03 20:25:37 (GMT)
commit38928ee3ee40179ec4ad295c72cf5aaa213f617e (patch)
tree3201e3a0c612cbf6dab0bf9ca44e87c688ae21ec /Source/cmStringAlgorithms.cxx
parentca5babfd7a1da8e32f927ad086fdd91c2b09853b (diff)
downloadCMake-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.cxx50
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);
+}