Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:01:16

0001 //
0002 // Copyright 2017 The Abseil Authors.
0003 //
0004 // Licensed under the Apache License, Version 2.0 (the "License");
0005 // you may not use this file except in compliance with the License.
0006 // You may obtain a copy of the License at
0007 //
0008 //      https://www.apache.org/licenses/LICENSE-2.0
0009 //
0010 // Unless required by applicable law or agreed to in writing, software
0011 // distributed under the License is distributed on an "AS IS" BASIS,
0012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013 // See the License for the specific language governing permissions and
0014 // limitations under the License.
0015 //
0016 // -----------------------------------------------------------------------------
0017 // File: str_join.h
0018 // -----------------------------------------------------------------------------
0019 //
0020 // This header file contains functions for joining a range of elements and
0021 // returning the result as a std::string. StrJoin operations are specified by
0022 // passing a range, a separator string to use between the elements joined, and
0023 // an optional Formatter responsible for converting each argument in the range
0024 // to a string. If omitted, a default `AlphaNumFormatter()` is called on the
0025 // elements to be joined, using the same formatting that `absl::StrCat()` uses.
0026 // This package defines a number of default formatters, and you can define your
0027 // own implementations.
0028 //
0029 // Ranges are specified by passing a container with `std::begin()` and
0030 // `std::end()` iterators, container-specific `begin()` and `end()` iterators, a
0031 // brace-initialized `std::initializer_list`, or a `std::tuple` of heterogeneous
0032 // objects. The separator string is specified as an `absl::string_view`.
0033 //
0034 // Because the default formatter uses the `absl::AlphaNum` class,
0035 // `absl::StrJoin()`, like `absl::StrCat()`, will work out-of-the-box on
0036 // collections of strings, ints, floats, doubles, etc.
0037 //
0038 // Example:
0039 //
0040 //   std::vector<std::string> v = {"foo", "bar", "baz"};
0041 //   std::string s = absl::StrJoin(v, "-");
0042 //   EXPECT_EQ("foo-bar-baz", s);
0043 //
0044 // See comments on the `absl::StrJoin()` function for more examples.
0045 
0046 #ifndef ABSL_STRINGS_STR_JOIN_H_
0047 #define ABSL_STRINGS_STR_JOIN_H_
0048 
0049 #include <cstdio>
0050 #include <cstring>
0051 #include <initializer_list>
0052 #include <iterator>
0053 #include <string>
0054 #include <tuple>
0055 #include <type_traits>
0056 #include <utility>
0057 
0058 #include "absl/base/macros.h"
0059 #include "absl/strings/internal/str_join_internal.h"
0060 #include "absl/strings/string_view.h"
0061 
0062 namespace absl {
0063 ABSL_NAMESPACE_BEGIN
0064 
0065 // -----------------------------------------------------------------------------
0066 // Concept: Formatter
0067 // -----------------------------------------------------------------------------
0068 //
0069 // A Formatter is a function object that is responsible for formatting its
0070 // argument as a string and appending it to a given output std::string.
0071 // Formatters may be implemented as function objects, lambdas, or normal
0072 // functions. You may provide your own Formatter to enable `absl::StrJoin()` to
0073 // work with arbitrary types.
0074 //
0075 // The following is an example of a custom Formatter that uses
0076 // `absl::FormatDuration` to join a list of `absl::Duration`s.
0077 //
0078 //   std::vector<absl::Duration> v = {absl::Seconds(1), absl::Milliseconds(10)};
0079 //   std::string s =
0080 //       absl::StrJoin(v, ", ", [](std::string* out, absl::Duration dur) {
0081 //         absl::StrAppend(out, absl::FormatDuration(dur));
0082 //       });
0083 //   EXPECT_EQ(s, "1s, 10ms");
0084 //
0085 // The following standard formatters are provided within this file:
0086 //
0087 // - `AlphaNumFormatter()` (the default)
0088 // - `StreamFormatter()`
0089 // - `PairFormatter()`
0090 // - `DereferenceFormatter()`
0091 
0092 // AlphaNumFormatter()
0093 //
0094 // Default formatter used if none is specified. Uses `absl::AlphaNum` to convert
0095 // numeric arguments to strings.
0096 inline strings_internal::AlphaNumFormatterImpl AlphaNumFormatter() {
0097   return strings_internal::AlphaNumFormatterImpl();
0098 }
0099 
0100 // StreamFormatter()
0101 //
0102 // Formats its argument using the << operator.
0103 inline strings_internal::StreamFormatterImpl StreamFormatter() {
0104   return strings_internal::StreamFormatterImpl();
0105 }
0106 
0107 // Function Template: PairFormatter(Formatter, absl::string_view, Formatter)
0108 //
0109 // Formats a `std::pair` by putting a given separator between the pair's
0110 // `.first` and `.second` members. This formatter allows you to specify
0111 // custom Formatters for both the first and second member of each pair.
0112 template <typename FirstFormatter, typename SecondFormatter>
0113 inline strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>
0114 PairFormatter(FirstFormatter f1, absl::string_view sep, SecondFormatter f2) {
0115   return strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>(
0116       std::move(f1), sep, std::move(f2));
0117 }
0118 
0119 // Function overload of PairFormatter() for using a default
0120 // `AlphaNumFormatter()` for each Formatter in the pair.
0121 inline strings_internal::PairFormatterImpl<
0122     strings_internal::AlphaNumFormatterImpl,
0123     strings_internal::AlphaNumFormatterImpl>
0124 PairFormatter(absl::string_view sep) {
0125   return PairFormatter(AlphaNumFormatter(), sep, AlphaNumFormatter());
0126 }
0127 
0128 // Function Template: DereferenceFormatter(Formatter)
0129 //
0130 // Formats its argument by dereferencing it and then applying the given
0131 // formatter. This formatter is useful for formatting a container of
0132 // pointer-to-T. This pattern often shows up when joining repeated fields in
0133 // protocol buffers.
0134 template <typename Formatter>
0135 strings_internal::DereferenceFormatterImpl<Formatter> DereferenceFormatter(
0136     Formatter&& f) {
0137   return strings_internal::DereferenceFormatterImpl<Formatter>(
0138       std::forward<Formatter>(f));
0139 }
0140 
0141 // Function overload of `DereferenceFormatter()` for using a default
0142 // `AlphaNumFormatter()`.
0143 inline strings_internal::DereferenceFormatterImpl<
0144     strings_internal::AlphaNumFormatterImpl>
0145 DereferenceFormatter() {
0146   return strings_internal::DereferenceFormatterImpl<
0147       strings_internal::AlphaNumFormatterImpl>(AlphaNumFormatter());
0148 }
0149 
0150 // -----------------------------------------------------------------------------
0151 // StrJoin()
0152 // -----------------------------------------------------------------------------
0153 //
0154 // Joins a range of elements and returns the result as a std::string.
0155 // `absl::StrJoin()` takes a range, a separator string to use between the
0156 // elements joined, and an optional Formatter responsible for converting each
0157 // argument in the range to a string.
0158 //
0159 // If omitted, the default `AlphaNumFormatter()` is called on the elements to be
0160 // joined.
0161 //
0162 // Example 1:
0163 //   // Joins a collection of strings. This pattern also works with a collection
0164 //   // of `absl::string_view` or even `const char*`.
0165 //   std::vector<std::string> v = {"foo", "bar", "baz"};
0166 //   std::string s = absl::StrJoin(v, "-");
0167 //   EXPECT_EQ(s, "foo-bar-baz");
0168 //
0169 // Example 2:
0170 //   // Joins the values in the given `std::initializer_list<>` specified using
0171 //   // brace initialization. This pattern also works with an initializer_list
0172 //   // of ints or `absl::string_view` -- any `AlphaNum`-compatible type.
0173 //   std::string s = absl::StrJoin({"foo", "bar", "baz"}, "-");
0174 //   EXPECT_EQs, "foo-bar-baz");
0175 //
0176 // Example 3:
0177 //   // Joins a collection of ints. This pattern also works with floats,
0178 //   // doubles, int64s -- any `StrCat()`-compatible type.
0179 //   std::vector<int> v = {1, 2, 3, -4};
0180 //   std::string s = absl::StrJoin(v, "-");
0181 //   EXPECT_EQ(s, "1-2-3--4");
0182 //
0183 // Example 4:
0184 //   // Joins a collection of pointer-to-int. By default, pointers are
0185 //   // dereferenced and the pointee is formatted using the default format for
0186 //   // that type; such dereferencing occurs for all levels of indirection, so
0187 //   // this pattern works just as well for `std::vector<int**>` as for
0188 //   // `std::vector<int*>`.
0189 //   int x = 1, y = 2, z = 3;
0190 //   std::vector<int*> v = {&x, &y, &z};
0191 //   std::string s = absl::StrJoin(v, "-");
0192 //   EXPECT_EQ(s, "1-2-3");
0193 //
0194 // Example 5:
0195 //   // Dereferencing of `std::unique_ptr<>` is also supported:
0196 //   std::vector<std::unique_ptr<int>> v
0197 //   v.emplace_back(new int(1));
0198 //   v.emplace_back(new int(2));
0199 //   v.emplace_back(new int(3));
0200 //   std::string s = absl::StrJoin(v, "-");
0201 //   EXPECT_EQ(s, "1-2-3");
0202 //
0203 // Example 6:
0204 //   // Joins a `std::map`, with each key-value pair separated by an equals
0205 //   // sign. This pattern would also work with, say, a
0206 //   // `std::vector<std::pair<>>`.
0207 //   std::map<std::string, int> m = {
0208 //       {"a", 1},
0209 //       {"b", 2},
0210 //       {"c", 3}};
0211 //   std::string s = absl::StrJoin(m, ",", absl::PairFormatter("="));
0212 //   EXPECT_EQ(s, "a=1,b=2,c=3");
0213 //
0214 // Example 7:
0215 //   // These examples show how `absl::StrJoin()` handles a few common edge
0216 //   // cases:
0217 //   std::vector<std::string> v_empty;
0218 //   EXPECT_EQ(absl::StrJoin(v_empty, "-"), "");
0219 //
0220 //   std::vector<std::string> v_one_item = {"foo"};
0221 //   EXPECT_EQ(absl::StrJoin(v_one_item, "-"), "foo");
0222 //
0223 //   std::vector<std::string> v_empty_string = {""};
0224 //   EXPECT_EQ(absl::StrJoin(v_empty_string, "-"), "");
0225 //
0226 //   std::vector<std::string> v_one_item_empty_string = {"a", ""};
0227 //   EXPECT_EQ(absl::StrJoin(v_one_item_empty_string, "-"), "a-");
0228 //
0229 //   std::vector<std::string> v_two_empty_string = {"", ""};
0230 //   EXPECT_EQ(absl::StrJoin(v_two_empty_string, "-"), "-");
0231 //
0232 // Example 8:
0233 //   // Joins a `std::tuple<T...>` of heterogeneous types, converting each to
0234 //   // a std::string using the `absl::AlphaNum` class.
0235 //   std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
0236 //   EXPECT_EQ(s, "123-abc-0.456");
0237 
0238 template <typename Iterator, typename Formatter>
0239 std::string StrJoin(Iterator start, Iterator end, absl::string_view sep,
0240                     Formatter&& fmt) {
0241   return strings_internal::JoinAlgorithm(start, end, sep, fmt);
0242 }
0243 
0244 template <typename Range, typename Formatter>
0245 std::string StrJoin(const Range& range, absl::string_view separator,
0246                     Formatter&& fmt) {
0247   return strings_internal::JoinRange(range, separator, fmt);
0248 }
0249 
0250 template <typename T, typename Formatter>
0251 std::string StrJoin(std::initializer_list<T> il, absl::string_view separator,
0252                     Formatter&& fmt) {
0253   return strings_internal::JoinRange(il, separator, fmt);
0254 }
0255 
0256 template <typename... T, typename Formatter>
0257 std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator,
0258                     Formatter&& fmt) {
0259   return strings_internal::JoinAlgorithm(value, separator, fmt);
0260 }
0261 
0262 template <typename Iterator>
0263 std::string StrJoin(Iterator start, Iterator end, absl::string_view separator) {
0264   return strings_internal::JoinRange(start, end, separator);
0265 }
0266 
0267 template <typename Range>
0268 std::string StrJoin(const Range& range, absl::string_view separator) {
0269   return strings_internal::JoinRange(range, separator);
0270 }
0271 
0272 template <typename T>
0273 std::string StrJoin(std::initializer_list<T> il,
0274                     absl::string_view separator) {
0275   return strings_internal::JoinRange(il, separator);
0276 }
0277 
0278 template <typename... T>
0279 std::string StrJoin(const std::tuple<T...>& value,
0280                     absl::string_view separator) {
0281   return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter());
0282 }
0283 
0284 ABSL_NAMESPACE_END
0285 }  // namespace absl
0286 
0287 #endif  // ABSL_STRINGS_STR_JOIN_H_