str_join.h
Go to the documentation of this file.
00001 //
00002 // Copyright 2017 The Abseil Authors.
00003 //
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //
00008 //      https://www.apache.org/licenses/LICENSE-2.0
00009 //
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
00015 //
00016 // -----------------------------------------------------------------------------
00017 // File: str_join.h
00018 // -----------------------------------------------------------------------------
00019 //
00020 // This header file contains functions for joining a range of elements and
00021 // returning the result as a std::string. StrJoin operations are specified by
00022 // passing a range, a separator string to use between the elements joined, and
00023 // an optional Formatter responsible for converting each argument in the range
00024 // to a string. If omitted, a default `AlphaNumFormatter()` is called on the
00025 // elements to be joined, using the same formatting that `absl::StrCat()` uses.
00026 // This package defines a number of default formatters, and you can define your
00027 // own implementations.
00028 //
00029 // Ranges are specified by passing a container with `std::begin()` and
00030 // `std::end()` iterators, container-specific `begin()` and `end()` iterators, a
00031 // brace-initialized `std::initializer_list`, or a `std::tuple` of heterogeneous
00032 // objects. The separator string is specified as an `absl::string_view`.
00033 //
00034 // Because the default formatter uses the `absl::AlphaNum` class,
00035 // `absl::StrJoin()`, like `absl::StrCat()`, will work out-of-the-box on
00036 // collections of strings, ints, floats, doubles, etc.
00037 //
00038 // Example:
00039 //
00040 //   std::vector<std::string> v = {"foo", "bar", "baz"};
00041 //   std::string s = absl::StrJoin(v, "-");
00042 //   EXPECT_EQ("foo-bar-baz", s);
00043 //
00044 // See comments on the `absl::StrJoin()` function for more examples.
00045 
00046 #ifndef ABSL_STRINGS_STR_JOIN_H_
00047 #define ABSL_STRINGS_STR_JOIN_H_
00048 
00049 #include <cstdio>
00050 #include <cstring>
00051 #include <initializer_list>
00052 #include <iterator>
00053 #include <string>
00054 #include <tuple>
00055 #include <type_traits>
00056 #include <utility>
00057 
00058 #include "absl/base/macros.h"
00059 #include "absl/strings/internal/str_join_internal.h"
00060 #include "absl/strings/string_view.h"
00061 
00062 namespace absl {
00063 
00064 // -----------------------------------------------------------------------------
00065 // Concept: Formatter
00066 // -----------------------------------------------------------------------------
00067 //
00068 // A Formatter is a function object that is responsible for formatting its
00069 // argument as a string and appending it to a given output std::string.
00070 // Formatters may be implemented as function objects, lambdas, or normal
00071 // functions. You may provide your own Formatter to enable `absl::StrJoin()` to
00072 // work with arbitrary types.
00073 //
00074 // The following is an example of a custom Formatter that simply uses
00075 // `std::to_string()` to format an integer as a std::string.
00076 //
00077 //   struct MyFormatter {
00078 //     void operator()(std::string* out, int i) const {
00079 //       out->append(std::to_string(i));
00080 //     }
00081 //   };
00082 //
00083 // You would use the above formatter by passing an instance of it as the final
00084 // argument to `absl::StrJoin()`:
00085 //
00086 //   std::vector<int> v = {1, 2, 3, 4};
00087 //   std::string s = absl::StrJoin(v, "-", MyFormatter());
00088 //   EXPECT_EQ("1-2-3-4", s);
00089 //
00090 // The following standard formatters are provided within this file:
00091 //
00092 // - `AlphaNumFormatter()` (the default)
00093 // - `StreamFormatter()`
00094 // - `PairFormatter()`
00095 // - `DereferenceFormatter()`
00096 
00097 // AlphaNumFormatter()
00098 //
00099 // Default formatter used if none is specified. Uses `absl::AlphaNum` to convert
00100 // numeric arguments to strings.
00101 inline strings_internal::AlphaNumFormatterImpl AlphaNumFormatter() {
00102   return strings_internal::AlphaNumFormatterImpl();
00103 }
00104 
00105 // StreamFormatter()
00106 //
00107 // Formats its argument using the << operator.
00108 inline strings_internal::StreamFormatterImpl StreamFormatter() {
00109   return strings_internal::StreamFormatterImpl();
00110 }
00111 
00112 // Function Template: PairFormatter(Formatter, absl::string_view, Formatter)
00113 //
00114 // Formats a `std::pair` by putting a given separator between the pair's
00115 // `.first` and `.second` members. This formatter allows you to specify
00116 // custom Formatters for both the first and second member of each pair.
00117 template <typename FirstFormatter, typename SecondFormatter>
00118 inline strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>
00119 PairFormatter(FirstFormatter f1, absl::string_view sep, SecondFormatter f2) {
00120   return strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>(
00121       std::move(f1), sep, std::move(f2));
00122 }
00123 
00124 // Function overload of PairFormatter() for using a default
00125 // `AlphaNumFormatter()` for each Formatter in the pair.
00126 inline strings_internal::PairFormatterImpl<
00127     strings_internal::AlphaNumFormatterImpl,
00128     strings_internal::AlphaNumFormatterImpl>
00129 PairFormatter(absl::string_view sep) {
00130   return PairFormatter(AlphaNumFormatter(), sep, AlphaNumFormatter());
00131 }
00132 
00133 // Function Template: DereferenceFormatter(Formatter)
00134 //
00135 // Formats its argument by dereferencing it and then applying the given
00136 // formatter. This formatter is useful for formatting a container of
00137 // pointer-to-T. This pattern often shows up when joining repeated fields in
00138 // protocol buffers.
00139 template <typename Formatter>
00140 strings_internal::DereferenceFormatterImpl<Formatter> DereferenceFormatter(
00141     Formatter&& f) {
00142   return strings_internal::DereferenceFormatterImpl<Formatter>(
00143       std::forward<Formatter>(f));
00144 }
00145 
00146 // Function overload of `DererefenceFormatter()` for using a default
00147 // `AlphaNumFormatter()`.
00148 inline strings_internal::DereferenceFormatterImpl<
00149     strings_internal::AlphaNumFormatterImpl>
00150 DereferenceFormatter() {
00151   return strings_internal::DereferenceFormatterImpl<
00152       strings_internal::AlphaNumFormatterImpl>(AlphaNumFormatter());
00153 }
00154 
00155 // -----------------------------------------------------------------------------
00156 // StrJoin()
00157 // -----------------------------------------------------------------------------
00158 //
00159 // Joins a range of elements and returns the result as a std::string.
00160 // `absl::StrJoin()` takes a range, a separator string to use between the
00161 // elements joined, and an optional Formatter responsible for converting each
00162 // argument in the range to a string.
00163 //
00164 // If omitted, the default `AlphaNumFormatter()` is called on the elements to be
00165 // joined.
00166 //
00167 // Example 1:
00168 //   // Joins a collection of strings. This pattern also works with a collection
00169 //   // of `absl::string_view` or even `const char*`.
00170 //   std::vector<std::string> v = {"foo", "bar", "baz"};
00171 //   std::string s = absl::StrJoin(v, "-");
00172 //   EXPECT_EQ("foo-bar-baz", s);
00173 //
00174 // Example 2:
00175 //   // Joins the values in the given `std::initializer_list<>` specified using
00176 //   // brace initialization. This pattern also works with an initializer_list
00177 //   // of ints or `absl::string_view` -- any `AlphaNum`-compatible type.
00178 //   std::string s = absl::StrJoin({"foo", "bar", "baz"}, "-");
00179 //   EXPECT_EQ("foo-bar-baz", s);
00180 //
00181 // Example 3:
00182 //   // Joins a collection of ints. This pattern also works with floats,
00183 //   // doubles, int64s -- any `StrCat()`-compatible type.
00184 //   std::vector<int> v = {1, 2, 3, -4};
00185 //   std::string s = absl::StrJoin(v, "-");
00186 //   EXPECT_EQ("1-2-3--4", s);
00187 //
00188 // Example 4:
00189 //   // Joins a collection of pointer-to-int. By default, pointers are
00190 //   // dereferenced and the pointee is formatted using the default format for
00191 //   // that type; such dereferencing occurs for all levels of indirection, so
00192 //   // this pattern works just as well for `std::vector<int**>` as for
00193 //   // `std::vector<int*>`.
00194 //   int x = 1, y = 2, z = 3;
00195 //   std::vector<int*> v = {&x, &y, &z};
00196 //   std::string s = absl::StrJoin(v, "-");
00197 //   EXPECT_EQ("1-2-3", s);
00198 //
00199 // Example 5:
00200 //   // Dereferencing of `std::unique_ptr<>` is also supported:
00201 //   std::vector<std::unique_ptr<int>> v
00202 //   v.emplace_back(new int(1));
00203 //   v.emplace_back(new int(2));
00204 //   v.emplace_back(new int(3));
00205 //   std::string s = absl::StrJoin(v, "-");
00206 //   EXPECT_EQ("1-2-3", s);
00207 //
00208 // Example 6:
00209 //   // Joins a `std::map`, with each key-value pair separated by an equals
00210 //   // sign. This pattern would also work with, say, a
00211 //   // `std::vector<std::pair<>>`.
00212 //   std::map<std::string, int> m = {
00213 //       std::make_pair("a", 1),
00214 //       std::make_pair("b", 2),
00215 //       std::make_pair("c", 3)};
00216 //   std::string s = absl::StrJoin(m, ",", absl::PairFormatter("="));
00217 //   EXPECT_EQ("a=1,b=2,c=3", s);
00218 //
00219 // Example 7:
00220 //   // These examples show how `absl::StrJoin()` handles a few common edge
00221 //   // cases:
00222 //   std::vector<std::string> v_empty;
00223 //   EXPECT_EQ("", absl::StrJoin(v_empty, "-"));
00224 //
00225 //   std::vector<std::string> v_one_item = {"foo"};
00226 //   EXPECT_EQ("foo", absl::StrJoin(v_one_item, "-"));
00227 //
00228 //   std::vector<std::string> v_empty_string = {""};
00229 //   EXPECT_EQ("", absl::StrJoin(v_empty_string, "-"));
00230 //
00231 //   std::vector<std::string> v_one_item_empty_string = {"a", ""};
00232 //   EXPECT_EQ("a-", absl::StrJoin(v_one_item_empty_string, "-"));
00233 //
00234 //   std::vector<std::string> v_two_empty_string = {"", ""};
00235 //   EXPECT_EQ("-", absl::StrJoin(v_two_empty_string, "-"));
00236 //
00237 // Example 8:
00238 //   // Joins a `std::tuple<T...>` of heterogeneous types, converting each to
00239 //   // a std::string using the `absl::AlphaNum` class.
00240 //   std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
00241 //   EXPECT_EQ("123-abc-0.456", s);
00242 
00243 template <typename Iterator, typename Formatter>
00244 std::string StrJoin(Iterator start, Iterator end, absl::string_view sep,
00245                     Formatter&& fmt) {
00246   return strings_internal::JoinAlgorithm(start, end, sep, fmt);
00247 }
00248 
00249 template <typename Range, typename Formatter>
00250 std::string StrJoin(const Range& range, absl::string_view separator,
00251                     Formatter&& fmt) {
00252   return strings_internal::JoinRange(range, separator, fmt);
00253 }
00254 
00255 template <typename T, typename Formatter>
00256 std::string StrJoin(std::initializer_list<T> il, absl::string_view separator,
00257                Formatter&& fmt) {
00258   return strings_internal::JoinRange(il, separator, fmt);
00259 }
00260 
00261 template <typename... T, typename Formatter>
00262 std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator,
00263                     Formatter&& fmt) {
00264   return strings_internal::JoinAlgorithm(value, separator, fmt);
00265 }
00266 
00267 template <typename Iterator>
00268 std::string StrJoin(Iterator start, Iterator end, absl::string_view separator) {
00269   return strings_internal::JoinRange(start, end, separator);
00270 }
00271 
00272 template <typename Range>
00273 std::string StrJoin(const Range& range, absl::string_view separator) {
00274   return strings_internal::JoinRange(range, separator);
00275 }
00276 
00277 template <typename T>
00278 std::string StrJoin(std::initializer_list<T> il, absl::string_view separator) {
00279   return strings_internal::JoinRange(il, separator);
00280 }
00281 
00282 template <typename... T>
00283 std::string StrJoin(const std::tuple<T...>& value,
00284                     absl::string_view separator) {
00285   return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter());
00286 }
00287 
00288 }  // namespace absl
00289 
00290 #endif  // ABSL_STRINGS_STR_JOIN_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15