aboutsummaryrefslogtreecommitdiff
path: root/absl/strings
diff options
context:
space:
mode:
authorDerek Mauro <dmauro@google.com>2024-05-13 12:26:04 -0700
committerCopybara-Service <copybara-worker@google.com>2024-05-13 12:27:02 -0700
commit73841853760d6f86f5fe0372f17b2456874b6399 (patch)
treeb1385f6b107afa8a5f134420079be9885da3810e /absl/strings
parent692d9e568301b2c01a35b8da3c9915cef4055a4f (diff)
downloadabseil-73841853760d6f86f5fe0372f17b2456874b6399.tar.gz
abseil-73841853760d6f86f5fe0372f17b2456874b6399.tar.bz2
abseil-73841853760d6f86f5fe0372f17b2456874b6399.zip
Add a `string_view` overload to `absl::StrJoin`
This allows users to pass a collection of string-like objects in an `initializer_list` without having to convert everything to the same type first. `initializer_list` has the requirement that everything is copied in to the list. For strings hitting the `string_view` overload avoids unnecessary copies. This may be a breaking change if `absl::StrJoin` has an explicit template parameter, for example `absl::StrJoin<std::string>({foo, "bar"});`. In this case, remove the explicit template parameter. PiperOrigin-RevId: 633295575 Change-Id: Ie5f0860f409f639a27a58949842ec961e0b3bdeb
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/str_join.h21
-rw-r--r--absl/strings/str_join_test.cc36
2 files changed, 53 insertions, 4 deletions
diff --git a/absl/strings/str_join.h b/absl/strings/str_join.h
index 6a92c0f5..badc944a 100644
--- a/absl/strings/str_join.h
+++ b/absl/strings/str_join.h
@@ -247,12 +247,20 @@ std::string StrJoin(const Range& range, absl::string_view separator,
return strings_internal::JoinRange(range, separator, fmt);
}
-template <typename T, typename Formatter>
+template <typename T, typename Formatter,
+ typename = typename std::enable_if<
+ !std::is_convertible<T, absl::string_view>::value>::type>
std::string StrJoin(std::initializer_list<T> il, absl::string_view separator,
Formatter&& fmt) {
return strings_internal::JoinRange(il, separator, fmt);
}
+template <typename Formatter>
+inline std::string StrJoin(std::initializer_list<absl::string_view> il,
+ absl::string_view separator, Formatter&& fmt) {
+ return strings_internal::JoinRange(il, separator, fmt);
+}
+
template <typename... T, typename Formatter>
std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator,
Formatter&& fmt) {
@@ -269,9 +277,14 @@ std::string StrJoin(const Range& range, absl::string_view separator) {
return strings_internal::JoinRange(range, separator);
}
-template <typename T>
-std::string StrJoin(std::initializer_list<T> il,
- absl::string_view separator) {
+template <typename T, typename = typename std::enable_if<!std::is_convertible<
+ T, absl::string_view>::value>::type>
+std::string StrJoin(std::initializer_list<T> il, absl::string_view separator) {
+ return strings_internal::JoinRange(il, separator);
+}
+
+inline std::string StrJoin(std::initializer_list<absl::string_view> il,
+ absl::string_view separator) {
return strings_internal::JoinRange(il, separator);
}
diff --git a/absl/strings/str_join_test.cc b/absl/strings/str_join_test.cc
index 449f95be..cd52e11d 100644
--- a/absl/strings/str_join_test.cc
+++ b/absl/strings/str_join_test.cc
@@ -428,6 +428,42 @@ TEST(StrJoin, InitializerList) {
}
}
+TEST(StrJoin, StringViewInitializerList) {
+ {
+ // Tests initializer_list of string_views
+ std::string b = "b";
+ EXPECT_EQ("a-b-c", absl::StrJoin({"a", b, "c"}, "-"));
+ }
+ {
+ // Tests initializer_list of string_views with a non-default formatter
+ TestingParenFormatter f;
+ std::string b = "b";
+ EXPECT_EQ("(a)-(b)-(c)", absl::StrJoin({"a", b, "c"}, "-", f));
+ }
+
+ class NoCopy {
+ public:
+ explicit NoCopy(absl::string_view view) : view_(view) {}
+ NoCopy(const NoCopy&) = delete;
+ operator absl::string_view() { return view_; } // NOLINT
+ private:
+ absl::string_view view_;
+ };
+ {
+ // Tests initializer_list of string_views preferred over initializer_list<T>
+ // for T that is implicitly convertible to string_view
+ EXPECT_EQ("a-b-c",
+ absl::StrJoin({NoCopy("a"), NoCopy("b"), NoCopy("c")}, "-"));
+ }
+ {
+ // Tests initializer_list of string_views preferred over initializer_list<T>
+ // for T that is implicitly convertible to string_view
+ TestingParenFormatter f;
+ EXPECT_EQ("(a)-(b)-(c)",
+ absl::StrJoin({NoCopy("a"), NoCopy("b"), NoCopy("c")}, "-", f));
+ }
+}
+
TEST(StrJoin, Tuple) {
EXPECT_EQ("", absl::StrJoin(std::make_tuple(), "-"));
EXPECT_EQ("hello", absl::StrJoin(std::make_tuple("hello"), "-"));