summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Turbov <i.zaufi@gmail.com>2024-07-01 16:29:20 (GMT)
committerBrad King <brad.king@kitware.com>2024-07-18 14:29:46 (GMT)
commit2e16b58b7c72525f78b8aa1eebb7ccd9a0a24512 (patch)
treea9ab34ac6a2efc2ff89706381f1f7ff678efa912
parentce991188f39c657487bbda88ce450bc9c641248b (diff)
downloadCMake-2e16b58b7c72525f78b8aa1eebb7ccd9a0a24512.zip
CMake-2e16b58b7c72525f78b8aa1eebb7ccd9a0a24512.tar.gz
CMake-2e16b58b7c72525f78b8aa1eebb7ccd9a0a24512.tar.bz2
cmStringAlgorithms: Move generic strings join function to public API
Move `cmJoinImpl` from `cmStringAlgorithms.cxx` to the `cmStringAlgorithms.h` as `cmJoinStrings`. Two existing overloads are not suitable for reverse iterators due to the hardcoded type of the first parameter. The signature is similar to the generic (template) `cmJoin`. With `enable_if` "magic", `cmJoinString` could be renamed to `cmJoin` in the future. Also, replace `getJoinedLength` with `std::accumulate`.
-rw-r--r--Source/cmStringAlgorithms.cxx42
-rw-r--r--Source/cmStringAlgorithms.h34
2 files changed, 36 insertions, 40 deletions
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index e352d8d..332bd8d 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -7,7 +7,6 @@
#include <cstddef> // IWYU pragma: keep
#include <cstdio>
#include <cstdlib>
-#include <iterator>
std::string cmTrimWhitespace(cm::string_view str)
{
@@ -239,51 +238,14 @@ bool cmStrToULongLong(std::string const& str, unsigned long long* value)
return cmStrToULongLong(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);
+ return cmJoinStrings(rng, separator, initial);
}
std::string cmJoin(cmStringRange const& rng, cm::string_view separator,
cm::string_view initial)
{
- return cmJoinImpl(rng, separator, initial);
+ return cmJoinStrings(rng, separator, initial);
}
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 55a1e46..3d7f9b0 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -7,6 +7,8 @@
#include <cctype>
#include <cstring>
#include <initializer_list>
+#include <iterator>
+#include <numeric>
#include <sstream>
#include <string>
#include <utility>
@@ -77,6 +79,38 @@ std::string cmJoin(Range const& rng, cm::string_view separator)
return os.str();
}
+/** Generic function to join strings range with separator
+ * and initial leading string into a single string.
+ */
+template <typename Range>
+std::string cmJoinStrings(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(
+ std::accumulate(std::begin(rng), std::end(rng),
+ initial.size() + (rng.size() - 1) * separator.size(),
+ [](std::size_t sum, const std::string& item) {
+ return sum + item.size();
+ }));
+ 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;
+}
+
/**
* Faster overloads for std::string ranges.
* If @a initial is provided, it prepends the resulted string without