summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-09-08 15:17:22 (GMT)
committerKitware Robot <kwrobot@kitware.com>2020-09-08 15:17:29 (GMT)
commit0bd964096859944ae28506fc8c0789df252865a6 (patch)
tree4bbab3b3ec07c4a659bf8c300c06602a57c8ff5b /Source
parent679b5512bdf8640012d216d67b7c670298d48599 (diff)
parent38928ee3ee40179ec4ad295c72cf5aaa213f617e (diff)
downloadCMake-0bd964096859944ae28506fc8c0789df252865a6.zip
CMake-0bd964096859944ae28506fc8c0789df252865a6.tar.gz
CMake-0bd964096859944ae28506fc8c0789df252865a6.tar.bz2
Merge topic 'optimize-cmJoin'
38928ee3ee cmStringAlgorithms: Add faster cmJoin overloads for strings Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !5185
Diffstat (limited to 'Source')
-rw-r--r--Source/cmStringAlgorithms.cxx50
-rw-r--r--Source/cmStringAlgorithms.h11
-rw-r--r--Source/cmStringCommand.cxx12
3 files changed, 69 insertions, 4 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);
+}
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 6508069..f3c262b 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -80,6 +80,17 @@ std::string cmJoin(Range const& rng, cm::string_view separator)
return os.str();
}
+/**
+ * Faster overloads for std::string ranges.
+ * If @a initial is provided, it prepends the resulted string without
+ * @a separator between them.
+ */
+std::string cmJoin(std::vector<std::string> const& rng,
+ cm::string_view separator, cm::string_view initial = {});
+
+std::string cmJoin(cmStringRange const& rng, cm::string_view separator,
+ cm::string_view initial = {});
+
/** Extract tokens that are separated by any of the characters in @a sep. */
std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep);
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 653b383..4000a7d 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -11,6 +11,7 @@
#include <memory>
#include <cm/iterator>
+#include <cm/string_view>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
@@ -534,11 +535,14 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
return true;
}
- const std::string& variable = args[1];
+ auto const& variableName = args[1];
+
+ cm::string_view oldView{ status.GetMakefile().GetSafeDefinition(
+ variableName) };
+
+ auto const newValue = cmJoin(cmMakeRange(args).advance(2), {}, oldView);
+ status.GetMakefile().AddDefinition(variableName, newValue);
- std::string value = status.GetMakefile().GetSafeDefinition(variable);
- value += cmJoin(cmMakeRange(args).advance(2), std::string());
- status.GetMakefile().AddDefinition(variable, value);
return true;
}