blob: 5123e8b88c64eb7c2108eeed0e60a4bec5ebecb4 [file]
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_STRINGS_JOIN_STRING_INTERNAL_H_
#define BASE_STRINGS_JOIN_STRING_INTERNAL_H_
#include <algorithm>
#include <string>
#include "base/check_op.h"
namespace base::strings_internal {
// Generic version for all JoinString overloads. |list_type| must be a sequence
// (base::span or std::initializer_list) of strings/StringPieces (std::string,
// std::u16string, std::string_view or std::u16string_view). |CharT| is either
// char or char16_t.
template <typename list_type,
typename T,
typename CharT = typename T::value_type>
constexpr std::basic_string<CharT> JoinStringT(list_type parts, T sep) {
if (std::empty(parts)) {
return std::basic_string<CharT>();
}
// Pre-allocate the eventual size of the string. Start with the size of all of
// the separators (note that this *assumes* parts.size() > 0).
// The counter is initialized with separator sizes.
const size_t total_size = std::ranges::fold_left(
parts, (std::size(parts) - 1) * sep.size(),
[](size_t acc, const auto& part) { return acc + std::size(part); });
std::basic_string<CharT> result;
result.reserve(total_size);
bool first = true;
for (const auto& part : parts) {
if (!first) {
result.append(sep);
}
result.append(part);
first = false;
}
// Sanity-check that we pre-allocated correctly.
DCHECK_EQ(total_size, result.size());
return result;
}
} // namespace base::strings_internal
#endif // BASE_STRINGS_JOIN_STRING_INTERNAL_H_