diff options
author | Alex Turbov <i.zaufi@gmail.com> | 2024-07-01 16:29:20 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2024-07-18 14:29:46 (GMT) |
commit | 2e16b58b7c72525f78b8aa1eebb7ccd9a0a24512 (patch) | |
tree | a9ab34ac6a2efc2ff89706381f1f7ff678efa912 | |
parent | ce991188f39c657487bbda88ce450bc9c641248b (diff) | |
download | CMake-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.cxx | 42 | ||||
-rw-r--r-- | Source/cmStringAlgorithms.h | 34 |
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 |