str_join.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. //
  2. // Copyright 2017 The Abseil Authors.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // https://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. // -----------------------------------------------------------------------------
  17. // File: str_join.h
  18. // -----------------------------------------------------------------------------
  19. //
  20. // This header file contains functions for joining a range of elements and
  21. // returning the result as a std::string. StrJoin operations are specified by
  22. // passing a range, a separator string to use between the elements joined, and
  23. // an optional Formatter responsible for converting each argument in the range
  24. // to a string. If omitted, a default `AlphaNumFormatter()` is called on the
  25. // elements to be joined, using the same formatting that `absl::StrCat()` uses.
  26. // This package defines a number of default formatters, and you can define your
  27. // own implementations.
  28. //
  29. // Ranges are specified by passing a container with `std::begin()` and
  30. // `std::end()` iterators, container-specific `begin()` and `end()` iterators, a
  31. // brace-initialized `std::initializer_list`, or a `std::tuple` of heterogeneous
  32. // objects. The separator string is specified as an `absl::string_view`.
  33. //
  34. // Because the default formatter uses the `absl::AlphaNum` class,
  35. // `absl::StrJoin()`, like `absl::StrCat()`, will work out-of-the-box on
  36. // collections of strings, ints, floats, doubles, etc.
  37. //
  38. // Example:
  39. //
  40. // std::vector<std::string> v = {"foo", "bar", "baz"};
  41. // std::string s = absl::StrJoin(v, "-");
  42. // EXPECT_EQ("foo-bar-baz", s);
  43. //
  44. // See comments on the `absl::StrJoin()` function for more examples.
  45. #ifndef ABSL_STRINGS_STR_JOIN_H_
  46. #define ABSL_STRINGS_STR_JOIN_H_
  47. #include <cstdio>
  48. #include <cstring>
  49. #include <initializer_list>
  50. #include <iterator>
  51. #include <string>
  52. #include <tuple>
  53. #include <type_traits>
  54. #include <utility>
  55. #include "absl/base/macros.h"
  56. #include "absl/strings/internal/str_join_internal.h"
  57. #include "absl/strings/string_view.h"
  58. namespace absl {
  59. ABSL_NAMESPACE_BEGIN
  60. // -----------------------------------------------------------------------------
  61. // Concept: Formatter
  62. // -----------------------------------------------------------------------------
  63. //
  64. // A Formatter is a function object that is responsible for formatting its
  65. // argument as a string and appending it to a given output std::string.
  66. // Formatters may be implemented as function objects, lambdas, or normal
  67. // functions. You may provide your own Formatter to enable `absl::StrJoin()` to
  68. // work with arbitrary types.
  69. //
  70. // The following is an example of a custom Formatter that simply uses
  71. // `std::to_string()` to format an integer as a std::string.
  72. //
  73. // struct MyFormatter {
  74. // void operator()(std::string* out, int i) const {
  75. // out->append(std::to_string(i));
  76. // }
  77. // };
  78. //
  79. // You would use the above formatter by passing an instance of it as the final
  80. // argument to `absl::StrJoin()`:
  81. //
  82. // std::vector<int> v = {1, 2, 3, 4};
  83. // std::string s = absl::StrJoin(v, "-", MyFormatter());
  84. // EXPECT_EQ("1-2-3-4", s);
  85. //
  86. // The following standard formatters are provided within this file:
  87. //
  88. // - `AlphaNumFormatter()` (the default)
  89. // - `StreamFormatter()`
  90. // - `PairFormatter()`
  91. // - `DereferenceFormatter()`
  92. // AlphaNumFormatter()
  93. //
  94. // Default formatter used if none is specified. Uses `absl::AlphaNum` to convert
  95. // numeric arguments to strings.
  96. inline strings_internal::AlphaNumFormatterImpl AlphaNumFormatter() {
  97. return strings_internal::AlphaNumFormatterImpl();
  98. }
  99. // StreamFormatter()
  100. //
  101. // Formats its argument using the << operator.
  102. inline strings_internal::StreamFormatterImpl StreamFormatter() {
  103. return strings_internal::StreamFormatterImpl();
  104. }
  105. // Function Template: PairFormatter(Formatter, absl::string_view, Formatter)
  106. //
  107. // Formats a `std::pair` by putting a given separator between the pair's
  108. // `.first` and `.second` members. This formatter allows you to specify
  109. // custom Formatters for both the first and second member of each pair.
  110. template <typename FirstFormatter, typename SecondFormatter>
  111. inline strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>
  112. PairFormatter(FirstFormatter f1, absl::string_view sep, SecondFormatter f2) {
  113. return strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>(
  114. std::move(f1), sep, std::move(f2));
  115. }
  116. // Function overload of PairFormatter() for using a default
  117. // `AlphaNumFormatter()` for each Formatter in the pair.
  118. inline strings_internal::PairFormatterImpl<
  119. strings_internal::AlphaNumFormatterImpl,
  120. strings_internal::AlphaNumFormatterImpl>
  121. PairFormatter(absl::string_view sep) {
  122. return PairFormatter(AlphaNumFormatter(), sep, AlphaNumFormatter());
  123. }
  124. // Function Template: DereferenceFormatter(Formatter)
  125. //
  126. // Formats its argument by dereferencing it and then applying the given
  127. // formatter. This formatter is useful for formatting a container of
  128. // pointer-to-T. This pattern often shows up when joining repeated fields in
  129. // protocol buffers.
  130. template <typename Formatter>
  131. strings_internal::DereferenceFormatterImpl<Formatter> DereferenceFormatter(
  132. Formatter&& f) {
  133. return strings_internal::DereferenceFormatterImpl<Formatter>(
  134. std::forward<Formatter>(f));
  135. }
  136. // Function overload of `DererefenceFormatter()` for using a default
  137. // `AlphaNumFormatter()`.
  138. inline strings_internal::DereferenceFormatterImpl<
  139. strings_internal::AlphaNumFormatterImpl>
  140. DereferenceFormatter() {
  141. return strings_internal::DereferenceFormatterImpl<
  142. strings_internal::AlphaNumFormatterImpl>(AlphaNumFormatter());
  143. }
  144. // -----------------------------------------------------------------------------
  145. // StrJoin()
  146. // -----------------------------------------------------------------------------
  147. //
  148. // Joins a range of elements and returns the result as a std::string.
  149. // `absl::StrJoin()` takes a range, a separator string to use between the
  150. // elements joined, and an optional Formatter responsible for converting each
  151. // argument in the range to a string.
  152. //
  153. // If omitted, the default `AlphaNumFormatter()` is called on the elements to be
  154. // joined.
  155. //
  156. // Example 1:
  157. // // Joins a collection of strings. This pattern also works with a collection
  158. // // of `absl::string_view` or even `const char*`.
  159. // std::vector<std::string> v = {"foo", "bar", "baz"};
  160. // std::string s = absl::StrJoin(v, "-");
  161. // EXPECT_EQ("foo-bar-baz", s);
  162. //
  163. // Example 2:
  164. // // Joins the values in the given `std::initializer_list<>` specified using
  165. // // brace initialization. This pattern also works with an initializer_list
  166. // // of ints or `absl::string_view` -- any `AlphaNum`-compatible type.
  167. // std::string s = absl::StrJoin({"foo", "bar", "baz"}, "-");
  168. // EXPECT_EQ("foo-bar-baz", s);
  169. //
  170. // Example 3:
  171. // // Joins a collection of ints. This pattern also works with floats,
  172. // // doubles, int64s -- any `StrCat()`-compatible type.
  173. // std::vector<int> v = {1, 2, 3, -4};
  174. // std::string s = absl::StrJoin(v, "-");
  175. // EXPECT_EQ("1-2-3--4", s);
  176. //
  177. // Example 4:
  178. // // Joins a collection of pointer-to-int. By default, pointers are
  179. // // dereferenced and the pointee is formatted using the default format for
  180. // // that type; such dereferencing occurs for all levels of indirection, so
  181. // // this pattern works just as well for `std::vector<int**>` as for
  182. // // `std::vector<int*>`.
  183. // int x = 1, y = 2, z = 3;
  184. // std::vector<int*> v = {&x, &y, &z};
  185. // std::string s = absl::StrJoin(v, "-");
  186. // EXPECT_EQ("1-2-3", s);
  187. //
  188. // Example 5:
  189. // // Dereferencing of `std::unique_ptr<>` is also supported:
  190. // std::vector<std::unique_ptr<int>> v
  191. // v.emplace_back(new int(1));
  192. // v.emplace_back(new int(2));
  193. // v.emplace_back(new int(3));
  194. // std::string s = absl::StrJoin(v, "-");
  195. // EXPECT_EQ("1-2-3", s);
  196. //
  197. // Example 6:
  198. // // Joins a `std::map`, with each key-value pair separated by an equals
  199. // // sign. This pattern would also work with, say, a
  200. // // `std::vector<std::pair<>>`.
  201. // std::map<std::string, int> m = {
  202. // std::make_pair("a", 1),
  203. // std::make_pair("b", 2),
  204. // std::make_pair("c", 3)};
  205. // std::string s = absl::StrJoin(m, ",", absl::PairFormatter("="));
  206. // EXPECT_EQ("a=1,b=2,c=3", s);
  207. //
  208. // Example 7:
  209. // // These examples show how `absl::StrJoin()` handles a few common edge
  210. // // cases:
  211. // std::vector<std::string> v_empty;
  212. // EXPECT_EQ("", absl::StrJoin(v_empty, "-"));
  213. //
  214. // std::vector<std::string> v_one_item = {"foo"};
  215. // EXPECT_EQ("foo", absl::StrJoin(v_one_item, "-"));
  216. //
  217. // std::vector<std::string> v_empty_string = {""};
  218. // EXPECT_EQ("", absl::StrJoin(v_empty_string, "-"));
  219. //
  220. // std::vector<std::string> v_one_item_empty_string = {"a", ""};
  221. // EXPECT_EQ("a-", absl::StrJoin(v_one_item_empty_string, "-"));
  222. //
  223. // std::vector<std::string> v_two_empty_string = {"", ""};
  224. // EXPECT_EQ("-", absl::StrJoin(v_two_empty_string, "-"));
  225. //
  226. // Example 8:
  227. // // Joins a `std::tuple<T...>` of heterogeneous types, converting each to
  228. // // a std::string using the `absl::AlphaNum` class.
  229. // std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
  230. // EXPECT_EQ("123-abc-0.456", s);
  231. template <typename Iterator, typename Formatter>
  232. std::string StrJoin(Iterator start, Iterator end, absl::string_view sep,
  233. Formatter&& fmt) {
  234. return strings_internal::JoinAlgorithm(start, end, sep, fmt);
  235. }
  236. template <typename Range, typename Formatter>
  237. std::string StrJoin(const Range& range, absl::string_view separator,
  238. Formatter&& fmt) {
  239. return strings_internal::JoinRange(range, separator, fmt);
  240. }
  241. template <typename T, typename Formatter>
  242. std::string StrJoin(std::initializer_list<T> il, absl::string_view separator,
  243. Formatter&& fmt) {
  244. return strings_internal::JoinRange(il, separator, fmt);
  245. }
  246. template <typename... T, typename Formatter>
  247. std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator,
  248. Formatter&& fmt) {
  249. return strings_internal::JoinAlgorithm(value, separator, fmt);
  250. }
  251. template <typename Iterator>
  252. std::string StrJoin(Iterator start, Iterator end, absl::string_view separator) {
  253. return strings_internal::JoinRange(start, end, separator);
  254. }
  255. template <typename Range>
  256. std::string StrJoin(const Range& range, absl::string_view separator) {
  257. return strings_internal::JoinRange(range, separator);
  258. }
  259. template <typename T>
  260. std::string StrJoin(std::initializer_list<T> il,
  261. absl::string_view separator) {
  262. return strings_internal::JoinRange(il, separator);
  263. }
  264. template <typename... T>
  265. std::string StrJoin(const std::tuple<T...>& value,
  266. absl::string_view separator) {
  267. return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter());
  268. }
  269. ABSL_NAMESPACE_END
  270. } // namespace absl
  271. #endif // ABSL_STRINGS_STR_JOIN_H_