Generalize Join to work for any container/element.
This is more scalable than explicitly instantiating templates for the
cross product of containers and element types.
Specifically I'm adding this so I can join an unordered_set in adb.
Change-Id: I0055f3390a0ff26a886a0d41bbf0d4fe3d210f9c
diff --git a/include/base/strings.h b/include/base/strings.h
index 5dbc5fb..638f845 100644
--- a/include/base/strings.h
+++ b/include/base/strings.h
@@ -17,6 +17,7 @@
#ifndef BASE_STRINGS_H
#define BASE_STRINGS_H
+#include <sstream>
#include <string>
#include <vector>
@@ -34,9 +35,24 @@
// Trims whitespace off both ends of the given string.
std::string Trim(const std::string& s);
-// Joins a vector of strings into a single string, using the given separator.
-template <typename StringT>
-std::string Join(const std::vector<StringT>& strings, char separator);
+// Joins a container of things into a single string, using the given separator.
+template <typename ContainerT>
+std::string Join(const ContainerT& things, char separator) {
+ if (things.empty()) {
+ return "";
+ }
+
+ std::ostringstream result;
+ result << *things.begin();
+ for (auto it = std::next(things.begin()); it != things.end(); ++it) {
+ result << separator << *it;
+ }
+ return result.str();
+}
+
+// We instantiate the common cases in strings.cpp.
+extern template std::string Join(const std::vector<std::string>&, char);
+extern template std::string Join(const std::vector<const char*>&, char);
// Tests whether 's' starts with 'prefix'.
bool StartsWith(const std::string& s, const char* prefix);