diff options
Diffstat (limited to 'absl/strings')
-rw-r--r-- | absl/strings/escaping.cc | 110 | ||||
-rw-r--r-- | absl/strings/escaping.h | 2 | ||||
-rw-r--r-- | absl/strings/internal/str_join_internal.h | 57 | ||||
-rw-r--r-- | absl/strings/numbers.cc | 14 | ||||
-rw-r--r-- | absl/strings/numbers_test.cc | 14 |
5 files changed, 110 insertions, 87 deletions
diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index abe9e0aaacd9..fbc9f756315f 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -366,31 +366,31 @@ std::string CEscapeInternal(absl::string_view src, bool use_hex, bool utf8_safe) return dest; } +/* clang-format off */ +constexpr char c_escaped_len[256] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // \t, \n, \r + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // ", ' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // '0'..'9' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A'..'O' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 'P'..'Z', '\' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a'..'o' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, // 'p'..'z', DEL + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +}; +/* clang-format on */ + // Calculates the length of the C-style escaped version of 'src'. // Assumes that non-printable characters are escaped using octal sequences, and // that UTF-8 bytes are not handled specially. inline size_t CEscapedLength(absl::string_view src) { - /* clang-format off */ - constexpr char c_escaped_len[256] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // \t, \n, \r - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // ", ' - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // '0'..'9' - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A'..'O' - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 'P'..'Z', '\' - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a'..'o' - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, // 'p'..'z', DEL - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - }; - /* clang-format on */ - size_t escaped_len = 0; for (unsigned char c : src) escaped_len += c_escaped_len[c]; return escaped_len; @@ -409,41 +409,41 @@ void CEscapeAndAppendInternal(absl::string_view src, std::string* dest) { char* append_ptr = &(*dest)[cur_dest_len]; for (unsigned char c : src) { - switch (c) { - case '\n': - *append_ptr++ = '\\'; - *append_ptr++ = 'n'; - break; - case '\r': - *append_ptr++ = '\\'; - *append_ptr++ = 'r'; - break; - case '\t': - *append_ptr++ = '\\'; - *append_ptr++ = 't'; - break; - case '\"': - *append_ptr++ = '\\'; - *append_ptr++ = '\"'; - break; - case '\'': - *append_ptr++ = '\\'; - *append_ptr++ = '\''; - break; - case '\\': - *append_ptr++ = '\\'; - *append_ptr++ = '\\'; - break; - default: - if (!absl::ascii_isprint(c)) { + int char_len = c_escaped_len[c]; + if (char_len == 1) { + *append_ptr++ = c; + } else if (char_len == 2) { + switch (c) { + case '\n': *append_ptr++ = '\\'; - *append_ptr++ = '0' + c / 64; - *append_ptr++ = '0' + (c % 64) / 8; - *append_ptr++ = '0' + c % 8; - } else { - *append_ptr++ = c; - } - break; + *append_ptr++ = 'n'; + break; + case '\r': + *append_ptr++ = '\\'; + *append_ptr++ = 'r'; + break; + case '\t': + *append_ptr++ = '\\'; + *append_ptr++ = 't'; + break; + case '\"': + *append_ptr++ = '\\'; + *append_ptr++ = '\"'; + break; + case '\'': + *append_ptr++ = '\\'; + *append_ptr++ = '\''; + break; + case '\\': + *append_ptr++ = '\\'; + *append_ptr++ = '\\'; + break; + } + } else { + *append_ptr++ = '\\'; + *append_ptr++ = '0' + c / 64; + *append_ptr++ = '0' + (c % 64) / 8; + *append_ptr++ = '0' + c % 8; } } } diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h index 23444a987495..86f63aad7dc0 100644 --- a/absl/strings/escaping.h +++ b/absl/strings/escaping.h @@ -113,7 +113,7 @@ std::string Utf8SafeCEscape(absl::string_view src); // Utf8SafeCHexEscape() // // Escapes a 'src' std::string using C-style escape sequences, escaping bytes as -// hexidecimal sequences, and passing through UTF-8 characters without +// hexadecimal sequences, and passing through UTF-8 characters without // conversion. std::string Utf8SafeCHexEscape(absl::string_view src); diff --git a/absl/strings/internal/str_join_internal.h b/absl/strings/internal/str_join_internal.h index e73f1dde403d..c5fdc287cbab 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 <cassert> +#include <cstring> #include <iterator> #include <memory> #include <string> +#include <type_traits> #include <utility> #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 <typename Iterator> -size_t GetResultSize(Iterator, Iterator, size_t, std::input_iterator_tag) { - return 0; -} - -// Calculates space to reserve, if the iterator supports multiple passes. -template <typename Iterator> -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<std::string> 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<std::string> or a // std::vector<absl::string_view>. // // 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 <typename Iterator> +template <typename Iterator, + typename = typename std::enable_if<std::is_convertible< + typename std::iterator_traits<Iterator>::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>::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(); } } diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index 31f07c72c949..b4140b3605bc 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -1,3 +1,17 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // This file contains std::string processing functions related to // numeric values. diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index a705255c706d..5bb39ca9b5a9 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -1,3 +1,17 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // This file tests std::string processing functions related to numeric values. #include "absl/strings/numbers.h" |