00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_
00032 #define ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_
00033
00034 #include <cstring>
00035 #include <iterator>
00036 #include <memory>
00037 #include <string>
00038 #include <type_traits>
00039 #include <utility>
00040
00041 #include "absl/strings/internal/ostringstream.h"
00042 #include "absl/strings/internal/resize_uninitialized.h"
00043 #include "absl/strings/str_cat.h"
00044
00045 namespace absl {
00046 namespace strings_internal {
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 struct AlphaNumFormatterImpl {
00058
00059
00060 template <typename T>
00061 void operator()(std::string* out, const T& t) const {
00062 StrAppend(out, AlphaNum(t));
00063 }
00064
00065 void operator()(std::string* out, const AlphaNum& t) const {
00066 StrAppend(out, t);
00067 }
00068 };
00069
00070
00071
00072
00073
00074 struct NoFormatter : public AlphaNumFormatterImpl {};
00075
00076
00077 class StreamFormatterImpl {
00078 public:
00079
00080
00081 template <typename T>
00082 void operator()(std::string* out, const T& t) {
00083
00084
00085 if (strm_) {
00086 strm_->clear();
00087 strm_->str(out);
00088 } else {
00089 strm_.reset(new strings_internal::OStringStream(out));
00090 }
00091 *strm_ << t;
00092 }
00093
00094 private:
00095 std::unique_ptr<strings_internal::OStringStream> strm_;
00096 };
00097
00098
00099
00100 template <typename F1, typename F2>
00101 class PairFormatterImpl {
00102 public:
00103 PairFormatterImpl(F1 f1, absl::string_view sep, F2 f2)
00104 : f1_(std::move(f1)), sep_(sep), f2_(std::move(f2)) {}
00105
00106 template <typename T>
00107 void operator()(std::string* out, const T& p) {
00108 f1_(out, p.first);
00109 out->append(sep_);
00110 f2_(out, p.second);
00111 }
00112
00113 template <typename T>
00114 void operator()(std::string* out, const T& p) const {
00115 f1_(out, p.first);
00116 out->append(sep_);
00117 f2_(out, p.second);
00118 }
00119
00120 private:
00121 F1 f1_;
00122 std::string sep_;
00123 F2 f2_;
00124 };
00125
00126
00127
00128
00129 template <typename Formatter>
00130 class DereferenceFormatterImpl {
00131 public:
00132 DereferenceFormatterImpl() : f_() {}
00133 explicit DereferenceFormatterImpl(Formatter&& f)
00134 : f_(std::forward<Formatter>(f)) {}
00135
00136 template <typename T>
00137 void operator()(std::string* out, const T& t) {
00138 f_(out, *t);
00139 }
00140
00141 template <typename T>
00142 void operator()(std::string* out, const T& t) const {
00143 f_(out, *t);
00144 }
00145
00146 private:
00147 Formatter f_;
00148 };
00149
00150
00151
00152
00153
00154
00155
00156
00157 template <typename ValueType>
00158 struct DefaultFormatter {
00159 typedef AlphaNumFormatterImpl Type;
00160 };
00161 template <>
00162 struct DefaultFormatter<const char*> {
00163 typedef AlphaNumFormatterImpl Type;
00164 };
00165 template <>
00166 struct DefaultFormatter<char*> {
00167 typedef AlphaNumFormatterImpl Type;
00168 };
00169 template <>
00170 struct DefaultFormatter<std::string> {
00171 typedef NoFormatter Type;
00172 };
00173 template <>
00174 struct DefaultFormatter<absl::string_view> {
00175 typedef NoFormatter Type;
00176 };
00177 template <typename ValueType>
00178 struct DefaultFormatter<ValueType*> {
00179 typedef DereferenceFormatterImpl<typename DefaultFormatter<ValueType>::Type>
00180 Type;
00181 };
00182
00183 template <typename ValueType>
00184 struct DefaultFormatter<std::unique_ptr<ValueType>>
00185 : public DefaultFormatter<ValueType*> {};
00186
00187
00188
00189
00190
00191
00192
00193
00194 template <typename Iterator, typename Formatter>
00195 std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s,
00196 Formatter&& f) {
00197 std::string result;
00198 absl::string_view sep("");
00199 for (Iterator it = start; it != end; ++it) {
00200 result.append(sep.data(), sep.size());
00201 f(&result, *it);
00202 sep = s;
00203 }
00204 return result;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 template <typename Iterator,
00223 typename = typename std::enable_if<std::is_convertible<
00224 typename std::iterator_traits<Iterator>::iterator_category,
00225 std::forward_iterator_tag>::value>::type>
00226 std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s,
00227 NoFormatter) {
00228 std::string result;
00229 if (start != end) {
00230
00231 size_t result_size = start->size();
00232 for (Iterator it = start; ++it != end;) {
00233 result_size += s.size();
00234 result_size += it->size();
00235 }
00236
00237 if (result_size > 0) {
00238 STLStringResizeUninitialized(&result, result_size);
00239
00240
00241 char* result_buf = &*result.begin();
00242 memcpy(result_buf, start->data(), start->size());
00243 result_buf += start->size();
00244 for (Iterator it = start; ++it != end;) {
00245 memcpy(result_buf, s.data(), s.size());
00246 result_buf += s.size();
00247 memcpy(result_buf, it->data(), it->size());
00248 result_buf += it->size();
00249 }
00250 }
00251 }
00252
00253 return result;
00254 }
00255
00256
00257
00258
00259
00260
00261 template <size_t I, size_t N>
00262 struct JoinTupleLoop {
00263 template <typename Tup, typename Formatter>
00264 void operator()(std::string* out, const Tup& tup, absl::string_view sep,
00265 Formatter&& fmt) {
00266 if (I > 0) out->append(sep.data(), sep.size());
00267 fmt(out, std::get<I>(tup));
00268 JoinTupleLoop<I + 1, N>()(out, tup, sep, fmt);
00269 }
00270 };
00271 template <size_t N>
00272 struct JoinTupleLoop<N, N> {
00273 template <typename Tup, typename Formatter>
00274 void operator()(std::string*, const Tup&, absl::string_view, Formatter&&) {}
00275 };
00276
00277 template <typename... T, typename Formatter>
00278 std::string JoinAlgorithm(const std::tuple<T...>& tup, absl::string_view sep,
00279 Formatter&& fmt) {
00280 std::string result;
00281 JoinTupleLoop<0, sizeof...(T)>()(&result, tup, sep, fmt);
00282 return result;
00283 }
00284
00285 template <typename Iterator>
00286 std::string JoinRange(Iterator first, Iterator last,
00287 absl::string_view separator) {
00288
00289 typedef typename std::iterator_traits<Iterator>::value_type ValueType;
00290 typedef typename DefaultFormatter<ValueType>::Type Formatter;
00291 return JoinAlgorithm(first, last, separator, Formatter());
00292 }
00293
00294 template <typename Range, typename Formatter>
00295 std::string JoinRange(const Range& range, absl::string_view separator,
00296 Formatter&& fmt) {
00297 using std::begin;
00298 using std::end;
00299 return JoinAlgorithm(begin(range), end(range), separator, fmt);
00300 }
00301
00302 template <typename Range>
00303 std::string JoinRange(const Range& range, absl::string_view separator) {
00304 using std::begin;
00305 using std::end;
00306 return JoinRange(begin(range), end(range), separator);
00307 }
00308
00309 }
00310 }
00311
00312 #endif // ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_