From ff7045647330f5dc21725a42456091207f3eecd5 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 20 Dec 2017 12:34:46 -0800 Subject: Changes imported from Abseil "staging" branch: - 20f4e7133d695e9a05e13ebdfd4d78da310b42b5 Remove the warning supressions -Wno-documentation and by Derek Mauro - e1bde85c0571673b1e7a88b9d45a393606ba7e6c Changed the optimized version of strings_internal::JoinAl... by Abseil Team - 746e6716b4c15be61547670d68d25a1c850d3954 Add missing absl:: qualification. by Alex Strelnikov - 4e5c18c488cbd49ca72b02911cf22d830d5a7f16 Internals change: Remove the ability to pass a custom met... by Greg Falcon - 65d58107a5730d4b6468bbffc72bea2f980af826 Moved most common character case (ascii printable) out of... by Abseil Team - f031331cc55a3d57b9110e12c7cbe50ac3e2a04f Add missing copyright headers to a few source files. by Greg Falcon - 6035a77af6fa951c536b42df4c710d16d1817aec Enable libstdc++'s memcmp optimization in absl::equal for... by Abseil Team - 73a665a4a10781e5d89f75a876ece7ad859f4116 Fix minor spelling error "hexidecimal". by Abseil Team GitOrigin-RevId: 20f4e7133d695e9a05e13ebdfd4d78da310b42b5 Change-Id: Id8c18ebd331d096935052a6ab259ebe0e2ef13ae --- absl/strings/internal/str_join_internal.h | 57 ++++++++++++++----------------- 1 file changed, 26 insertions(+), 31 deletions(-) (limited to 'absl/strings/internal/str_join_internal.h') diff --git a/absl/strings/internal/str_join_internal.h b/absl/strings/internal/str_join_internal.h index e73f1dde..c5fdc287 100644 --- a/absl/strings/internal/str_join_internal.h +++ b/absl/strings/internal/str_join_internal.h @@ -31,13 +31,15 @@ #ifndef ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_ #define ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_ -#include +#include #include #include #include +#include #include #include "absl/strings/internal/ostringstream.h" +#include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/str_cat.h" namespace absl { @@ -202,28 +204,9 @@ std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s, return result; } -// No-op placeholder for input iterators which can not be iterated over. -template -size_t GetResultSize(Iterator, Iterator, size_t, std::input_iterator_tag) { - return 0; -} - -// Calculates space to reserve, if the iterator supports multiple passes. -template -size_t GetResultSize(Iterator it, Iterator end, size_t separator_size, - std::forward_iterator_tag) { - assert(it != end); - size_t length = it->size(); - while (++it != end) { - length += separator_size; - length += it->size(); - } - return length; -} - -// A joining algorithm that's optimized for an iterator range of std::string-like -// objects that do not need any additional formatting. This is to optimize the -// common case of joining, say, a std::vector or a +// A joining algorithm that's optimized for a forward iterator range of +// std::string-like objects that do not need any additional formatting. This is to +// optimize the common case of joining, say, a std::vector or a // std::vector. // // This is an overload of the previous JoinAlgorithm() function. Here the @@ -236,20 +219,32 @@ size_t GetResultSize(Iterator it, Iterator end, size_t separator_size, // std::string to avoid the need to resize while appending. To do this, the iterator // range will be traversed twice: once to calculate the total needed size, and // then again to copy the elements and delimiters to the output std::string. -template +template ::iterator_category, + std::forward_iterator_tag>::value>::type> std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s, NoFormatter) { std::string result; if (start != end) { - typename std::iterator_traits::iterator_category iterator_tag; - result.reserve(GetResultSize(start, end, s.size(), iterator_tag)); + // Sums size + size_t result_size = start->size(); + for (Iterator it = start; ++it != end;) { + result_size += s.size(); + result_size += it->size(); + } + + STLStringResizeUninitialized(&result, result_size); // Joins strings - absl::string_view sep("", 0); - for (Iterator it = start; it != end; ++it) { - result.append(sep.data(), sep.size()); - result.append(it->data(), it->size()); - sep = s; + char* result_buf = &*result.begin(); + memcpy(result_buf, start->data(), start->size()); + result_buf += start->size(); + for (Iterator it = start; ++it != end;) { + memcpy(result_buf, s.data(), s.size()); + result_buf += s.size(); + memcpy(result_buf, it->data(), it->size()); + result_buf += it->size(); } } -- cgit v1.2.3