Joining Elements in Strings
turbo::str_join() - Joining Elements in Strings
Although similar to turbo::str_cat() for some analogous use cases, turbo::str_join() provides a more powerful utility for concatenating a sequence of elements, defining a delimiter string, and formatting the result into a single string.
Ranges are specified by passing containers with std::begin() and std::end() iterators, container-specific begin() and end() iterators, brace-initialized std::initializer_list, or heterogeneous std::tuple objects. The delimiter string is specified as a std::string_view.
Because the default formatter uses the turbo::AlphaNum class, turbo::str_join(), like turbo::str_cat(), works out of the box with collections of strings, integers, floats, doubles, and more.
Examples
std::vector<std::string> v = {"foo", "bar", "baz"};
std::string s = turbo::str_join(v, "-");
// Produces the string "foo-bar-baz"
// Joins the values in the given `std::initializer_list<>` specified using
// brace initialization. This pattern also works with an initializer_list
// of ints or `std::string_view` -- any `AlphaNum`-compatible type.
std::string s = turbo::str_join({"foo", "bar", "baz"}, "-");
// Produces the string "foo-bar-baz"
// Joins a collection of ints. This pattern also works with floats,
// doubles, int64s -- any `turbo::str_cat()`-compatible type.
std::vector<int> v = {1, 2, 3, -4};
std::string s = turbo::str_join(v, "-");
// Produces the string "1-2-3--4"
// Joins a collection of pointer-to-int. By default, pointers are
// dereferenced and the pointee is formatted using the default format for
// that type; such dereferencing occurs for all levels of indirection, so
// this pattern works just as well for `std::vector<int**>` as for
// `std::vector<int*>`.
int x = 1, y = 2, z = 3;
std::vector<int*> v = {&x, &y, &z};
std::string s = turbo::str_join(v, "-");
// Produces the string "1-2-3"
// Dereferencing of `std::unique_ptr<>` is also supported:
std::vector<std::unique_ptr<int>> v;
v.push_back(turbo::make_unique<int>(1));
v.push_back(turbo::make_unique<int>(2));
v.push_back(turbo::make_unique<int>(3));
std::string s = turbo::str_join(v, "-");
// Produces the string "1-2-3"
// Joins a `std::map`, with each key-value pair separated by an equals
// sign. This pattern would also work with, say, a
// `std::vector<std::pair<>>`.
std::map<std::string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
std::string s = turbo::str_join(m, ",", turbo::PairFormatter("="));
// Produces the string "a=1,b=2,c=3"
Join Formatters
turbo::str_join() uses Formatters to format the elements being joined (and defaults to AlphaNumFormatter() if no formatter is specified). A formatter is a function object responsible for formatting its argument into a string and appending it to a given output string. Formatters can be implemented as function objects, lambdas, or ordinary functions. You can provide your own formatter to enable turbo::str_join() to handle arbitrary types.
Here is an example of a custom formatter that formats integers as strings using only std::to_string():
struct MyFormatter {
void operator()(std::string* out, int i) const {
out->append(std::to_string(i));
}
};
You can use the formatter above by passing an instance of it as the final argument to turbo::str_join():
std::vector<int> v = {1, 2, 3, 4};
std::string s = turbo::str_join(v, "-", MyFormatter());
// Produces the string "1-2-3-4"
The following standard formatters are available in the str_join() API:
AlphaNumFormatter()(default)StreamFormatter()Formats its argument using the<<operator.PairFormatter()Formats anstd::pairby placing a given delimiter between the.firstand.secondmembers of the pair.DereferenceFormatter()Formats its argument by dereferencing it, then applying the given formatter. This formatter is useful for formatting containers of pointers to T. This pattern commonly arises when joining repeated fields in protocol buffers.