File indexing completed on 2025-09-17 08:02:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <format>
0012 #include <ranges>
0013
0014 namespace Acts {
0015
0016
0017
0018
0019
0020
0021 template <std::ranges::range R>
0022 requires std::convertible_to<std::ranges::range_value_t<R>, std::string_view>
0023 std::string joinStrings(R&& strings, std::string_view delimiter) {
0024 std::string result;
0025 bool first = true;
0026
0027 for (auto&& item :
0028 strings | std::views::transform(
0029 [](const auto& s) -> std::string_view { return s; })) {
0030 if (!first) {
0031 result += delimiter;
0032 }
0033 result += item;
0034 first = false;
0035 }
0036
0037 return result;
0038 }
0039
0040 namespace detail {
0041
0042 template <typename T, typename>
0043 concept formattable = requires(T t) { std::format("{}", t); };
0044 }
0045
0046
0047
0048
0049
0050
0051
0052 template <std::ranges::range R>
0053 requires detail::formattable<std::ranges::range_value_t<R>, char>
0054 std::string joinStrings(
0055 R&& values, std::string_view delimiter,
0056 std::format_string<const std::ranges::range_value_t<R>&> format) {
0057 std::string result;
0058 bool first = true;
0059
0060 for (const auto& value : values) {
0061 if (!first) {
0062 result += delimiter;
0063 }
0064 result += std::format(format, value);
0065 first = false;
0066 }
0067
0068 return result;
0069 }
0070
0071
0072
0073
0074
0075
0076
0077
0078 template <std::ranges::range R>
0079 requires(
0080 detail::formattable<std::ranges::range_value_t<R>, char> &&
0081 !std::convertible_to<std::ranges::range_value_t<R>, std::string_view>)
0082 std::string joinStrings(R&& values, std::string_view delimiter) {
0083 std::string result;
0084 bool first = true;
0085
0086 for (const auto& value : values) {
0087 if (!first) {
0088 result += delimiter;
0089 }
0090 result += std::format("{}", value);
0091 first = false;
0092 }
0093
0094 return result;
0095 }
0096
0097 }