diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/restricted/abseil-cpp-tstring/y_absl/strings | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/abseil-cpp-tstring/y_absl/strings')
64 files changed, 3036 insertions, 3036 deletions
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ascii.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ascii.cc index 959d6c27ff..0d977146ab 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ascii.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ascii.cc @@ -15,7 +15,7 @@ #include "y_absl/strings/ascii.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace ascii_internal { // # Table generated by this Python code (bit 0x02 is currently unused): @@ -57,7 +57,7 @@ namespace ascii_internal { // of these bits is tightly coupled to this implementation, the individual bits // are not named. Note that bitfields for all characters above ASCII 127 are // zero-initialized. -ABSL_DLL const unsigned char kPropertyBits[256] = { +ABSL_DLL const unsigned char kPropertyBits[256] = { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00 0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x10 @@ -79,7 +79,7 @@ ABSL_DLL const unsigned char kPropertyBits[256] = { // Array of characters for the ascii_tolower() function. For values 'A' // through 'Z', return the lower-case character; otherwise, return the // identity of the passed character. -ABSL_DLL const char kToLower[256] = { +ABSL_DLL const char kToLower[256] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', @@ -117,7 +117,7 @@ ABSL_DLL const char kToLower[256] = { // Array of characters for the ascii_toupper() function. For values 'a' // through 'z', return the upper-case character; otherwise, return the // identity of the passed character. -ABSL_DLL const char kToUpper[256] = { +ABSL_DLL const char kToUpper[256] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', @@ -196,5 +196,5 @@ void RemoveExtraAsciiWhitespace(TString* str) { str->erase(output_it - &(*str)[0]); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ascii.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ascii.h index bc04710d8c..2b64d8dbc2 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ascii.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ascii.h @@ -53,24 +53,24 @@ #define ABSL_STRINGS_ASCII_H_ #include <algorithm> -#include <util/generic/string.h> +#include <util/generic/string.h> #include "y_absl/base/attributes.h" -#include "y_absl/base/config.h" +#include "y_absl/base/config.h" #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace ascii_internal { // Declaration for an array of bitfields holding character information. -ABSL_DLL extern const unsigned char kPropertyBits[256]; +ABSL_DLL extern const unsigned char kPropertyBits[256]; // Declaration for the array of characters to upper-case characters. -ABSL_DLL extern const char kToUpper[256]; +ABSL_DLL extern const char kToUpper[256]; // Declaration for the array of characters to lower-case characters. -ABSL_DLL extern const char kToLower[256]; +ABSL_DLL extern const char kToLower[256]; } // namespace ascii_internal @@ -236,7 +236,7 @@ inline void StripAsciiWhitespace(TString* str) { // Removes leading, trailing, and consecutive internal whitespace. void RemoveExtraAsciiWhitespace(TString*); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_ASCII_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.cc index 9515ca24dd..0fb2b4b0a5 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.cc @@ -57,7 +57,7 @@ // narrower mantissas. namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { template <typename FloatType> @@ -980,5 +980,5 @@ const int16_t kPower10ExponentTable[] = { }; } // namespace -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.h index 1a115aa251..c87da48d06 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.h @@ -17,10 +17,10 @@ #include <system_error> // NOLINT(build/c++11) -#include "y_absl/base/config.h" - +#include "y_absl/base/config.h" + namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Workalike compatibilty version of std::chars_format from C++17. // @@ -114,7 +114,7 @@ inline chars_format& operator^=(chars_format& lhs, chars_format rhs) { return lhs; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_CHARCONV_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.cc index 0de4ea1b3c..7c3f0df49b 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.cc @@ -1,82 +1,82 @@ -// Copyright 2020 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 -// -// https://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. - -#include "y_absl/strings/cord.h" - -#include <algorithm> +// Copyright 2020 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 +// +// https://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. + +#include "y_absl/strings/cord.h" + +#include <algorithm> #include <atomic> -#include <cstddef> -#include <cstdio> -#include <cstdlib> -#include <iomanip> +#include <cstddef> +#include <cstdio> +#include <cstdlib> +#include <iomanip> #include <iostream> -#include <limits> -#include <ostream> -#include <sstream> -#include <type_traits> -#include <unordered_set> -#include <vector> - -#include "y_absl/base/casts.h" -#include "y_absl/base/internal/raw_logging.h" +#include <limits> +#include <ostream> +#include <sstream> +#include <type_traits> +#include <unordered_set> +#include <vector> + +#include "y_absl/base/casts.h" +#include "y_absl/base/internal/raw_logging.h" #include "y_absl/base/macros.h" -#include "y_absl/base/port.h" -#include "y_absl/container/fixed_array.h" -#include "y_absl/container/inlined_vector.h" -#include "y_absl/strings/escaping.h" -#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/base/port.h" +#include "y_absl/container/fixed_array.h" +#include "y_absl/container/inlined_vector.h" +#include "y_absl/strings/escaping.h" +#include "y_absl/strings/internal/cord_internal.h" #include "y_absl/strings/internal/cord_rep_btree.h" #include "y_absl/strings/internal/cord_rep_flat.h" #include "y_absl/strings/internal/cordz_statistics.h" #include "y_absl/strings/internal/cordz_update_scope.h" #include "y_absl/strings/internal/cordz_update_tracker.h" -#include "y_absl/strings/internal/resize_uninitialized.h" -#include "y_absl/strings/str_cat.h" -#include "y_absl/strings/str_format.h" -#include "y_absl/strings/str_join.h" -#include "y_absl/strings/string_view.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN - -using ::y_absl::cord_internal::CordRep; +#include "y_absl/strings/internal/resize_uninitialized.h" +#include "y_absl/strings/str_cat.h" +#include "y_absl/strings/str_format.h" +#include "y_absl/strings/str_join.h" +#include "y_absl/strings/string_view.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN + +using ::y_absl::cord_internal::CordRep; using ::y_absl::cord_internal::CordRepBtree; -using ::y_absl::cord_internal::CordRepConcat; -using ::y_absl::cord_internal::CordRepExternal; +using ::y_absl::cord_internal::CordRepConcat; +using ::y_absl::cord_internal::CordRepExternal; using ::y_absl::cord_internal::CordRepFlat; -using ::y_absl::cord_internal::CordRepSubstring; +using ::y_absl::cord_internal::CordRepSubstring; using ::y_absl::cord_internal::CordzUpdateTracker; using ::y_absl::cord_internal::InlineData; using ::y_absl::cord_internal::kMaxFlatLength; using ::y_absl::cord_internal::kMinFlatLength; - + using ::y_absl::cord_internal::kInlinedVectorSize; using ::y_absl::cord_internal::kMaxBytesToCopy; - -constexpr uint64_t Fibonacci(unsigned char n, uint64_t a = 0, uint64_t b = 1) { - return n == 0 ? a : Fibonacci(n - 1, b, a + b); -} - -static_assert(Fibonacci(63) == 6557470319842, - "Fibonacci values computed incorrectly"); - -// Minimum length required for a given depth tree -- a tree is considered -// balanced if -// length(t) >= min_length[depth(t)] -// The root node depth is allowed to become twice as large to reduce rebalancing -// for larger strings (see IsRootBalanced). -static constexpr uint64_t min_length[] = { + +constexpr uint64_t Fibonacci(unsigned char n, uint64_t a = 0, uint64_t b = 1) { + return n == 0 ? a : Fibonacci(n - 1, b, a + b); +} + +static_assert(Fibonacci(63) == 6557470319842, + "Fibonacci values computed incorrectly"); + +// Minimum length required for a given depth tree -- a tree is considered +// balanced if +// length(t) >= min_length[depth(t)] +// The root node depth is allowed to become twice as large to reduce rebalancing +// for larger strings (see IsRootBalanced). +static constexpr uint64_t min_length[] = { Fibonacci(2), Fibonacci(3), Fibonacci(4), Fibonacci(5), Fibonacci(6), Fibonacci(7), Fibonacci(8), Fibonacci(9), Fibonacci(10), Fibonacci(11), Fibonacci(12), Fibonacci(13), @@ -89,121 +89,121 @@ static constexpr uint64_t min_length[] = { Fibonacci(38), Fibonacci(39), Fibonacci(40), Fibonacci(41), Fibonacci(42), Fibonacci(43), Fibonacci(44), Fibonacci(45), Fibonacci(46), Fibonacci(47), - 0xffffffffffffffffull, // Avoid overflow -}; - -static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); - + 0xffffffffffffffffull, // Avoid overflow +}; + +static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); + static inline bool btree_enabled() { return cord_internal::cord_btree_enabled.load( std::memory_order_relaxed); } - -static inline bool IsRootBalanced(CordRep* node) { + +static inline bool IsRootBalanced(CordRep* node) { if (!node->IsConcat()) { - return true; - } else if (node->concat()->depth() <= 15) { - return true; - } else if (node->concat()->depth() > kMinLengthSize) { - return false; - } else { - // Allow depth to become twice as large as implied by fibonacci rule to - // reduce rebalancing for larger strings. - return (node->length >= min_length[node->concat()->depth() / 2]); - } -} - -static CordRep* Rebalance(CordRep* node); + return true; + } else if (node->concat()->depth() <= 15) { + return true; + } else if (node->concat()->depth() > kMinLengthSize) { + return false; + } else { + // Allow depth to become twice as large as implied by fibonacci rule to + // reduce rebalancing for larger strings. + return (node->length >= min_length[node->concat()->depth() / 2]); + } +} + +static CordRep* Rebalance(CordRep* node); static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, int indent = 0); -static bool VerifyNode(CordRep* root, CordRep* start_node, - bool full_validation); - -static inline CordRep* VerifyTree(CordRep* node) { - // Verification is expensive, so only do it in debug mode. - // Even in debug mode we normally do only light validation. - // If you are debugging Cord itself, you should define the - // macro EXTRA_CORD_VALIDATION, e.g. by adding - // --copt=-DEXTRA_CORD_VALIDATION to the blaze line. -#ifdef EXTRA_CORD_VALIDATION - assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/true)); -#else // EXTRA_CORD_VALIDATION - assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/false)); -#endif // EXTRA_CORD_VALIDATION - static_cast<void>(&VerifyNode); - - return node; -} - -// Return the depth of a node -static int Depth(const CordRep* rep) { +static bool VerifyNode(CordRep* root, CordRep* start_node, + bool full_validation); + +static inline CordRep* VerifyTree(CordRep* node) { + // Verification is expensive, so only do it in debug mode. + // Even in debug mode we normally do only light validation. + // If you are debugging Cord itself, you should define the + // macro EXTRA_CORD_VALIDATION, e.g. by adding + // --copt=-DEXTRA_CORD_VALIDATION to the blaze line. +#ifdef EXTRA_CORD_VALIDATION + assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/true)); +#else // EXTRA_CORD_VALIDATION + assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/false)); +#endif // EXTRA_CORD_VALIDATION + static_cast<void>(&VerifyNode); + + return node; +} + +// Return the depth of a node +static int Depth(const CordRep* rep) { if (rep->IsConcat()) { - return rep->concat()->depth(); - } else { - return 0; - } -} - -static void SetConcatChildren(CordRepConcat* concat, CordRep* left, - CordRep* right) { - concat->left = left; - concat->right = right; - - concat->length = left->length + right->length; - concat->set_depth(1 + std::max(Depth(left), Depth(right))); -} - -// Create a concatenation of the specified nodes. -// Does not change the refcounts of "left" and "right". -// The returned node has a refcount of 1. -static CordRep* RawConcat(CordRep* left, CordRep* right) { - // Avoid making degenerate concat nodes (one child is empty) + return rep->concat()->depth(); + } else { + return 0; + } +} + +static void SetConcatChildren(CordRepConcat* concat, CordRep* left, + CordRep* right) { + concat->left = left; + concat->right = right; + + concat->length = left->length + right->length; + concat->set_depth(1 + std::max(Depth(left), Depth(right))); +} + +// Create a concatenation of the specified nodes. +// Does not change the refcounts of "left" and "right". +// The returned node has a refcount of 1. +static CordRep* RawConcat(CordRep* left, CordRep* right) { + // Avoid making degenerate concat nodes (one child is empty) if (left == nullptr) return right; if (right == nullptr) return left; if (left->length == 0) { CordRep::Unref(left); - return right; - } + return right; + } if (right->length == 0) { CordRep::Unref(right); - return left; - } - - CordRepConcat* rep = new CordRepConcat(); + return left; + } + + CordRepConcat* rep = new CordRepConcat(); rep->tag = cord_internal::CONCAT; - SetConcatChildren(rep, left, right); - - return rep; -} - -static CordRep* Concat(CordRep* left, CordRep* right) { - CordRep* rep = RawConcat(left, right); - if (rep != nullptr && !IsRootBalanced(rep)) { - rep = Rebalance(rep); - } - return VerifyTree(rep); -} - -// Make a balanced tree out of an array of leaf nodes. -static CordRep* MakeBalancedTree(CordRep** reps, size_t n) { - // Make repeated passes over the array, merging adjacent pairs - // until we are left with just a single node. - while (n > 1) { - size_t dst = 0; - for (size_t src = 0; src < n; src += 2) { - if (src + 1 < n) { - reps[dst] = Concat(reps[src], reps[src + 1]); - } else { - reps[dst] = reps[src]; - } - dst++; - } - n = dst; - } - - return reps[0]; -} - + SetConcatChildren(rep, left, right); + + return rep; +} + +static CordRep* Concat(CordRep* left, CordRep* right) { + CordRep* rep = RawConcat(left, right); + if (rep != nullptr && !IsRootBalanced(rep)) { + rep = Rebalance(rep); + } + return VerifyTree(rep); +} + +// Make a balanced tree out of an array of leaf nodes. +static CordRep* MakeBalancedTree(CordRep** reps, size_t n) { + // Make repeated passes over the array, merging adjacent pairs + // until we are left with just a single node. + while (n > 1) { + size_t dst = 0; + for (size_t src = 0; src < n; src += 2) { + if (src + 1 < n) { + reps[dst] = Concat(reps[src], reps[src + 1]); + } else { + reps[dst] = reps[src]; + } + dst++; + } + n = dst; + } + + return reps[0]; +} + static CordRepFlat* CreateFlat(const char* data, size_t length, size_t alloc_hint) { CordRepFlat* flat = CordRepFlat::New(length + alloc_hint); @@ -217,63 +217,63 @@ static CordRepFlat* CreateFlat(const char* data, size_t length, static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) { if (length <= kMaxFlatLength) { return CreateFlat(data, length, alloc_hint); - } + } CordRepFlat* flat = CreateFlat(data, kMaxFlatLength, 0); data += kMaxFlatLength; length -= kMaxFlatLength; auto* root = CordRepBtree::Create(flat); return CordRepBtree::Append(root, {data, length}, alloc_hint); -} - -// Create a new tree out of the specified array. -// The returned node has a refcount of 1. +} + +// Create a new tree out of the specified array. +// The returned node has a refcount of 1. static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) { - if (length == 0) return nullptr; + if (length == 0) return nullptr; if (btree_enabled()) { return NewBtree(data, length, alloc_hint); } - y_absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1); - size_t n = 0; - do { - const size_t len = std::min(length, kMaxFlatLength); + y_absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1); + size_t n = 0; + do { + const size_t len = std::min(length, kMaxFlatLength); CordRepFlat* rep = CordRepFlat::New(len + alloc_hint); - rep->length = len; + rep->length = len; memcpy(rep->Data(), data, len); - reps[n++] = VerifyTree(rep); - data += len; - length -= len; - } while (length != 0); - return MakeBalancedTree(reps.data(), n); -} - -namespace cord_internal { - + reps[n++] = VerifyTree(rep); + data += len; + length -= len; + } while (length != 0); + return MakeBalancedTree(reps.data(), n); +} + +namespace cord_internal { + void InitializeCordRepExternal(y_absl::string_view data, CordRepExternal* rep) { - assert(!data.empty()); - rep->length = data.size(); - rep->tag = EXTERNAL; - rep->base = data.data(); + assert(!data.empty()); + rep->length = data.size(); + rep->tag = EXTERNAL; + rep->base = data.data(); VerifyTree(rep); -} - -} // namespace cord_internal - -static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) { - // Never create empty substring nodes - if (length == 0) { +} + +} // namespace cord_internal + +static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) { + // Never create empty substring nodes + if (length == 0) { CordRep::Unref(child); - return nullptr; - } else { - CordRepSubstring* rep = new CordRepSubstring(); - assert((offset + length) <= child->length); - rep->length = length; + return nullptr; + } else { + CordRepSubstring* rep = new CordRepSubstring(); + assert((offset + length) <= child->length); + rep->length = length; rep->tag = cord_internal::SUBSTRING; - rep->start = offset; - rep->child = child; - return VerifyTree(rep); - } -} - + rep->start = offset; + rep->child = child; + return VerifyTree(rep); + } +} + // Creates a CordRep from the provided string. If the string is large enough, // and not wasteful, we move the string into an external cord rep, preserving // the already allocated string contents. @@ -303,41 +303,41 @@ static CordRep* CordRepFromString(TString&& src) { return rep; } -// -------------------------------------------------------------------- -// Cord::InlineRep functions - +// -------------------------------------------------------------------- +// Cord::InlineRep functions + constexpr unsigned char Cord::InlineRep::kMaxInline; - -inline void Cord::InlineRep::set_data(const char* data, size_t n, - bool nullify_tail) { - static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15"); - + +inline void Cord::InlineRep::set_data(const char* data, size_t n, + bool nullify_tail) { + static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15"); + cord_internal::SmallMemmove(data_.as_chars(), data, n, nullify_tail); set_inline_size(n); -} - -inline char* Cord::InlineRep::set_data(size_t n) { - assert(n <= kMaxInline); +} + +inline char* Cord::InlineRep::set_data(size_t n) { + assert(n <= kMaxInline); ResetToEmpty(); set_inline_size(n); return data_.as_chars(); -} - -inline void Cord::InlineRep::reduce_size(size_t n) { +} + +inline void Cord::InlineRep::reduce_size(size_t n) { size_t tag = inline_size(); - assert(tag <= kMaxInline); - assert(tag >= n); - tag -= n; + assert(tag <= kMaxInline); + assert(tag >= n); + tag -= n; memset(data_.as_chars() + tag, 0, n); set_inline_size(static_cast<char>(tag)); -} - -inline void Cord::InlineRep::remove_prefix(size_t n) { +} + +inline void Cord::InlineRep::remove_prefix(size_t n) { cord_internal::SmallMemmove(data_.as_chars(), data_.as_chars() + n, inline_size() - n); - reduce_size(n); -} - + reduce_size(n); +} + // Returns `rep` converted into a CordRepBtree. // Directly returns `rep` if `rep` is already a CordRepBtree. static CordRepBtree* ForceBtree(CordRep* rep) { @@ -370,14 +370,14 @@ void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) { } void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) { - if (tree == nullptr) return; + if (tree == nullptr) return; if (data_.is_tree()) { AppendTreeToTree(tree, method); - } else { + } else { AppendTreeToInlined(tree, method); - } -} - + } +} + void Cord::InlineRep::PrependTreeToInlined(CordRep* tree, MethodIdentifier method) { assert(!is_tree()); @@ -408,17 +408,17 @@ void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) { assert(tree != nullptr); if (data_.is_tree()) { PrependTreeToTree(tree, method); - } else { + } else { PrependTreeToInlined(tree, method); - } -} - -// Searches for a non-full flat node at the rightmost leaf of the tree. If a -// suitable leaf is found, the function will update the length field for all -// nodes to account for the size increase. The append region address will be -// written to region and the actual size increase will be written to size. -static inline bool PrepareAppendRegion(CordRep* root, char** region, - size_t* size, size_t max_length) { + } +} + +// Searches for a non-full flat node at the rightmost leaf of the tree. If a +// suitable leaf is found, the function will update the length field for all +// nodes to account for the size increase. The append region address will be +// written to region and the actual size increase will be written to size. +static inline bool PrepareAppendRegion(CordRep* root, char** region, + size_t* size, size_t max_length) { if (root->IsBtree() && root->refcount.IsMutable()) { Span<char> span = root->btree()->GetAppendBuffer(max_length); if (!span.empty()) { @@ -428,44 +428,44 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region, } } - // Search down the right-hand path for a non-full FLAT node. - CordRep* dst = root; + // Search down the right-hand path for a non-full FLAT node. + CordRep* dst = root; while (dst->IsConcat() && dst->refcount.IsMutable()) { - dst = dst->concat()->right; - } - + dst = dst->concat()->right; + } + if (!dst->IsFlat() || !dst->refcount.IsMutable()) { - *region = nullptr; - *size = 0; - return false; - } - - const size_t in_use = dst->length; + *region = nullptr; + *size = 0; + return false; + } + + const size_t in_use = dst->length; const size_t capacity = dst->flat()->Capacity(); - if (in_use == capacity) { - *region = nullptr; - *size = 0; - return false; - } - - size_t size_increase = std::min(capacity - in_use, max_length); - - // We need to update the length fields for all nodes, including the leaf node. - for (CordRep* rep = root; rep != dst; rep = rep->concat()->right) { - rep->length += size_increase; - } - dst->length += size_increase; - + if (in_use == capacity) { + *region = nullptr; + *size = 0; + return false; + } + + size_t size_increase = std::min(capacity - in_use, max_length); + + // We need to update the length fields for all nodes, including the leaf node. + for (CordRep* rep = root; rep != dst; rep = rep->concat()->right) { + rep->length += size_increase; + } + dst->length += size_increase; + *region = dst->flat()->Data() + in_use; - *size = size_increase; - return true; -} - + *size = size_increase; + return true; +} + template <bool has_length> -void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, +void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, size_t length) { auto constexpr method = CordzUpdateTracker::kGetAppendRegion; - + CordRep* root = tree(); size_t sz = root ? root->length : inline_size(); if (root == nullptr) { @@ -476,21 +476,21 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, set_inline_size(has_length ? sz + length : kMaxInline); return; } - } - + } + size_t extra = has_length ? length : (std::max)(sz, kMinFlatLength); CordRep* rep = root ? root : MakeFlatWithExtraCapacity(extra); CordzUpdateScope scope(root ? data_.cordz_info() : nullptr, method); if (PrepareAppendRegion(rep, region, size, length)) { CommitTree(root, rep, scope, method); - return; - } - - // Allocate new node. + return; + } + + // Allocate new node. CordRepFlat* new_node = CordRepFlat::New(extra); new_node->length = std::min(new_node->Capacity(), length); *region = new_node->Data(); - *size = new_node->length; + *size = new_node->length; if (btree_enabled()) { rep = CordRepBtree::Append(ForceBtree(rep), new_node); @@ -498,8 +498,8 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, rep = Concat(rep, new_node); } CommitTree(root, rep, scope, method); -} - +} + // Computes the memory side of the provided edge which must be a valid data edge // for a btrtee, i.e., a FLAT, EXTERNAL or SUBSTRING of a FLAT or EXTERNAL node. static bool RepMemoryUsageDataEdge(const CordRep* rep, @@ -508,11 +508,11 @@ static bool RepMemoryUsageDataEdge(const CordRep* rep, if (ABSL_PREDICT_FALSE(rep->IsSubstring())) { maybe_sub_size = sizeof(cord_internal::CordRepSubstring); rep = rep->substring()->child; - } + } if (rep->IsFlat()) { *total_mem_usage += maybe_sub_size + rep->flat()->AllocatedSize(); return true; - } + } if (rep->IsExternal()) { // We don't know anything about the embedded / bound data, but we can safely // assume it is 'at least' a word / pointer to data. In the future we may @@ -524,15 +524,15 @@ static bool RepMemoryUsageDataEdge(const CordRep* rep, return true; } return false; -} - -// If the rep is a leaf, this will increment the value at total_mem_usage and -// will return true. -static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { +} + +// If the rep is a leaf, this will increment the value at total_mem_usage and +// will return true. +static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { if (rep->IsFlat()) { *total_mem_usage += rep->flat()->AllocatedSize(); - return true; - } + return true; + } if (rep->IsExternal()) { // We don't know anything about the embedded / bound data, but we can safely // assume it is 'at least' a word / pointer to data. In the future we may @@ -540,12 +540,12 @@ static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { // well-known externals, such as a TString instance. *total_mem_usage += sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + rep->length; - return true; - } - return false; -} - -void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { + return true; + } + return false; +} + +void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { assert(&src != this); assert(is_tree() || src.is_tree()); auto constexpr method = CordzUpdateTracker::kAssignCord; @@ -553,7 +553,7 @@ void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { EmplaceTree(CordRep::Ref(src.as_tree()), src.data_, method); return; } - + CordRep* tree = as_tree(); if (CordRep* src_tree = src.tree()) { // Leave any existing `cordz_info` in place, and let MaybeTrackCord() @@ -563,31 +563,31 @@ void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { } else { CordzInfo::MaybeUntrackCord(data_.cordz_info()); data_ = src.data_; - } + } CordRep::Unref(tree); -} - +} + void Cord::InlineRep::UnrefTree() { - if (is_tree()) { + if (is_tree()) { CordzInfo::MaybeUntrackCord(data_.cordz_info()); CordRep::Unref(tree()); - } -} - -// -------------------------------------------------------------------- -// Constructors and destructors - + } +} + +// -------------------------------------------------------------------- +// Constructors and destructors + Cord::Cord(y_absl::string_view src, MethodIdentifier method) : contents_(InlineData::kDefaultInit) { - const size_t n = src.size(); - if (n <= InlineRep::kMaxInline) { + const size_t n = src.size(); + if (n <= InlineRep::kMaxInline) { contents_.set_data(src.data(), n, true); - } else { + } else { CordRep* rep = NewTree(src.data(), n, 0); contents_.EmplaceTree(rep, method); - } -} - + } +} + template <typename T, Cord::EnableIfString<T>> Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) { if (src.size() <= InlineRep::kMaxInline) { @@ -600,23 +600,23 @@ Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) { template Cord::Cord(TString&& src); -// The destruction code is separate so that the compiler can determine -// that it does not need to call the destructor on a moved-from Cord. -void Cord::DestroyCordSlow() { +// The destruction code is separate so that the compiler can determine +// that it does not need to call the destructor on a moved-from Cord. +void Cord::DestroyCordSlow() { assert(contents_.is_tree()); CordzInfo::MaybeUntrackCord(contents_.cordz_info()); CordRep::Unref(VerifyTree(contents_.as_tree())); -} - -// -------------------------------------------------------------------- -// Mutators - -void Cord::Clear() { +} + +// -------------------------------------------------------------------- +// Mutators + +void Cord::Clear() { if (CordRep* tree = contents_.clear()) { CordRep::Unref(tree); } -} - +} + Cord& Cord::AssignLargeString(TString&& src) { auto constexpr method = CordzUpdateTracker::kAssignString; assert(src.size() > kMaxBytesToCopy); @@ -631,21 +631,21 @@ Cord& Cord::AssignLargeString(TString&& src) { return *this; } -Cord& Cord::operator=(y_absl::string_view src) { +Cord& Cord::operator=(y_absl::string_view src) { auto constexpr method = CordzUpdateTracker::kAssignString; - const char* data = src.data(); - size_t length = src.size(); - CordRep* tree = contents_.tree(); - if (length <= InlineRep::kMaxInline) { + const char* data = src.data(); + size_t length = src.size(); + CordRep* tree = contents_.tree(); + if (length <= InlineRep::kMaxInline) { // Embed into this->contents_, which is somewhat subtle: // - MaybeUntrackCord must be called before Unref(tree). // - MaybeUntrackCord must be called before set_data() clobbers cordz_info. // - set_data() must be called before Unref(tree) as it may reference tree. if (tree != nullptr) CordzInfo::MaybeUntrackCord(contents_.cordz_info()); - contents_.set_data(data, length, true); + contents_.set_data(data, length, true); if (tree != nullptr) CordRep::Unref(tree); - return *this; - } + return *this; + } if (tree != nullptr) { CordzUpdateScope scope(contents_.cordz_info(), method); if (tree->IsFlat() && tree->flat()->Capacity() >= length && @@ -664,22 +664,22 @@ Cord& Cord::operator=(y_absl::string_view src) { return *this; } -// TODO(sanjay): Move to Cord::InlineRep section of file. For now, -// we keep it here to make diffs easier. +// TODO(sanjay): Move to Cord::InlineRep section of file. For now, +// we keep it here to make diffs easier. void Cord::InlineRep::AppendArray(y_absl::string_view src, MethodIdentifier method) { if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. - - size_t appended = 0; + + size_t appended = 0; CordRep* rep = tree(); const CordRep* const root = rep; CordzUpdateScope scope(root ? cordz_info() : nullptr, method); if (root != nullptr) { - char* region; + char* region; if (PrepareAppendRegion(rep, ®ion, &appended, src.size())) { memcpy(region, src.data(), appended); - } - } else { + } + } else { // Try to fit in the inline buffer if possible. size_t inline_length = inline_size(); if (src.size() <= kMaxInline - inline_length) { @@ -697,14 +697,14 @@ void Cord::InlineRep::AppendArray(y_absl::string_view src, memcpy(rep->flat()->Data(), data_.as_chars(), inline_length); memcpy(rep->flat()->Data() + inline_length, src.data(), appended); rep->length = inline_length + appended; - } - + } + src.remove_prefix(appended); if (src.empty()) { CommitTree(root, rep, scope, method); - return; - } - + return; + } + if (btree_enabled()) { // TODO(b/192061034): keep legacy 10% growth rate: consider other rates. rep = ForceBtree(rep); @@ -727,22 +727,22 @@ void Cord::InlineRep::AppendArray(y_absl::string_view src, rep = Concat(rep, NewTree(src.data(), src.size(), length - src.size())); } CommitTree(root, rep, scope, method); -} - -inline CordRep* Cord::TakeRep() const& { +} + +inline CordRep* Cord::TakeRep() const& { return CordRep::Ref(contents_.tree()); -} - -inline CordRep* Cord::TakeRep() && { - CordRep* rep = contents_.tree(); - contents_.clear(); - return rep; -} - -template <typename C> -inline void Cord::AppendImpl(C&& src) { +} + +inline CordRep* Cord::TakeRep() && { + CordRep* rep = contents_.tree(); + contents_.clear(); + return rep; +} + +template <typename C> +inline void Cord::AppendImpl(C&& src) { auto constexpr method = CordzUpdateTracker::kAppendCord; - if (empty()) { + if (empty()) { // Since destination is empty, we can avoid allocating a node, if (src.contents_.is_tree()) { // by taking the tree directly @@ -752,48 +752,48 @@ inline void Cord::AppendImpl(C&& src) { // or copying over inline data contents_.data_ = src.contents_.data_; } - return; - } - - // For short cords, it is faster to copy data if there is room in dst. - const size_t src_size = src.contents_.size(); - if (src_size <= kMaxBytesToCopy) { - CordRep* src_tree = src.contents_.tree(); - if (src_tree == nullptr) { - // src has embedded data. + return; + } + + // For short cords, it is faster to copy data if there is room in dst. + const size_t src_size = src.contents_.size(); + if (src_size <= kMaxBytesToCopy) { + CordRep* src_tree = src.contents_.tree(); + if (src_tree == nullptr) { + // src has embedded data. contents_.AppendArray({src.contents_.data(), src_size}, method); - return; - } + return; + } if (src_tree->IsFlat()) { - // src tree just has one flat node. + // src tree just has one flat node. contents_.AppendArray({src_tree->flat()->Data(), src_size}, method); - return; - } - if (&src == this) { - // ChunkIterator below assumes that src is not modified during traversal. - Append(Cord(src)); - return; - } - // TODO(mec): Should we only do this if "dst" has space? - for (y_absl::string_view chunk : src.Chunks()) { - Append(chunk); - } - return; - } - + return; + } + if (&src == this) { + // ChunkIterator below assumes that src is not modified during traversal. + Append(Cord(src)); + return; + } + // TODO(mec): Should we only do this if "dst" has space? + for (y_absl::string_view chunk : src.Chunks()) { + Append(chunk); + } + return; + } + // Guaranteed to be a tree (kMaxBytesToCopy > kInlinedSize) CordRep* rep = std::forward<C>(src).TakeRep(); contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord); -} - +} + void Cord::Append(const Cord& src) { AppendImpl(src); } - + void Cord::Append(Cord&& src) { AppendImpl(std::move(src)); } - + template <typename T, Cord::EnableIfString<T>> void Cord::Append(T&& src) { if (src.size() <= kMaxBytesToCopy) { @@ -806,21 +806,21 @@ void Cord::Append(T&& src) { template void Cord::Append(TString&& src); -void Cord::Prepend(const Cord& src) { - CordRep* src_tree = src.contents_.tree(); - if (src_tree != nullptr) { +void Cord::Prepend(const Cord& src) { + CordRep* src_tree = src.contents_.tree(); + if (src_tree != nullptr) { CordRep::Ref(src_tree); contents_.PrependTree(src_tree, CordzUpdateTracker::kPrependCord); - return; - } - - // `src` cord is inlined. - y_absl::string_view src_contents(src.contents_.data(), src.contents_.size()); - return Prepend(src_contents); -} - + return; + } + + // `src` cord is inlined. + y_absl::string_view src_contents(src.contents_.data(), src.contents_.size()); + return Prepend(src_contents); +} + void Cord::PrependArray(y_absl::string_view src, MethodIdentifier method) { - if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. + if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. if (!contents_.is_tree()) { size_t cur_size = contents_.inline_size(); if (cur_size + src.size() <= InlineRep::kMaxInline) { @@ -841,107 +841,107 @@ template <typename T, Cord::EnableIfString<T>> inline void Cord::Prepend(T&& src) { if (src.size() <= kMaxBytesToCopy) { Prepend(y_absl::string_view(src)); - } else { + } else { CordRep* rep = CordRepFromString(std::forward<T>(src)); contents_.PrependTree(rep, CordzUpdateTracker::kPrependString); - } -} - + } +} + template void Cord::Prepend(TString&& src); -static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { - if (n >= node->length) return nullptr; +static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { + if (n >= node->length) return nullptr; if (n == 0) return CordRep::Ref(node); - y_absl::InlinedVector<CordRep*, kInlinedVectorSize> rhs_stack; - + y_absl::InlinedVector<CordRep*, kInlinedVectorSize> rhs_stack; + while (node->IsConcat()) { - assert(n <= node->length); - if (n < node->concat()->left->length) { - // Push right to stack, descend left. - rhs_stack.push_back(node->concat()->right); - node = node->concat()->left; - } else { - // Drop left, descend right. - n -= node->concat()->left->length; - node = node->concat()->right; - } - } - assert(n <= node->length); - - if (n == 0) { + assert(n <= node->length); + if (n < node->concat()->left->length) { + // Push right to stack, descend left. + rhs_stack.push_back(node->concat()->right); + node = node->concat()->left; + } else { + // Drop left, descend right. + n -= node->concat()->left->length; + node = node->concat()->right; + } + } + assert(n <= node->length); + + if (n == 0) { CordRep::Ref(node); - } else { - size_t start = n; - size_t len = node->length - n; + } else { + size_t start = n; + size_t len = node->length - n; if (node->IsSubstring()) { - // Consider in-place update of node, similar to in RemoveSuffixFrom(). - start += node->substring()->start; - node = node->substring()->child; - } + // Consider in-place update of node, similar to in RemoveSuffixFrom(). + start += node->substring()->start; + node = node->substring()->child; + } node = NewSubstring(CordRep::Ref(node), start, len); - } - while (!rhs_stack.empty()) { + } + while (!rhs_stack.empty()) { node = Concat(node, CordRep::Ref(rhs_stack.back())); - rhs_stack.pop_back(); - } - return node; -} - -// RemoveSuffixFrom() is very similar to RemovePrefixFrom(), with the -// exception that removing a suffix has an optimization where a node may be -// edited in place iff that node and all its ancestors have a refcount of 1. -static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { - if (n >= node->length) return nullptr; + rhs_stack.pop_back(); + } + return node; +} + +// RemoveSuffixFrom() is very similar to RemovePrefixFrom(), with the +// exception that removing a suffix has an optimization where a node may be +// edited in place iff that node and all its ancestors have a refcount of 1. +static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { + if (n >= node->length) return nullptr; if (n == 0) return CordRep::Ref(node); - y_absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack; + y_absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack; bool inplace_ok = node->refcount.IsMutable(); - + while (node->IsConcat()) { - assert(n <= node->length); - if (n < node->concat()->right->length) { - // Push left to stack, descend right. - lhs_stack.push_back(node->concat()->left); - node = node->concat()->right; - } else { - // Drop right, descend left. - n -= node->concat()->right->length; - node = node->concat()->left; - } + assert(n <= node->length); + if (n < node->concat()->right->length) { + // Push left to stack, descend right. + lhs_stack.push_back(node->concat()->left); + node = node->concat()->right; + } else { + // Drop right, descend left. + n -= node->concat()->right->length; + node = node->concat()->left; + } inplace_ok = inplace_ok && node->refcount.IsMutable(); - } - assert(n <= node->length); - - if (n == 0) { + } + assert(n <= node->length); + + if (n == 0) { CordRep::Ref(node); } else if (inplace_ok && !node->IsExternal()) { - // Consider making a new buffer if the current node capacity is much - // larger than the new length. + // Consider making a new buffer if the current node capacity is much + // larger than the new length. CordRep::Ref(node); - node->length -= n; - } else { - size_t start = 0; - size_t len = node->length - n; + node->length -= n; + } else { + size_t start = 0; + size_t len = node->length - n; if (node->IsSubstring()) { - start = node->substring()->start; - node = node->substring()->child; - } + start = node->substring()->start; + node = node->substring()->child; + } node = NewSubstring(CordRep::Ref(node), start, len); - } - while (!lhs_stack.empty()) { + } + while (!lhs_stack.empty()) { node = Concat(CordRep::Ref(lhs_stack.back()), node); - lhs_stack.pop_back(); - } - return node; -} - -void Cord::RemovePrefix(size_t n) { - ABSL_INTERNAL_CHECK(n <= size(), - y_absl::StrCat("Requested prefix size ", n, - " exceeds Cord's size ", size())); - CordRep* tree = contents_.tree(); - if (tree == nullptr) { - contents_.remove_prefix(n); - } else { + lhs_stack.pop_back(); + } + return node; +} + +void Cord::RemovePrefix(size_t n) { + ABSL_INTERNAL_CHECK(n <= size(), + y_absl::StrCat("Requested prefix size ", n, + " exceeds Cord's size ", size())); + CordRep* tree = contents_.tree(); + if (tree == nullptr) { + contents_.remove_prefix(n); + } else { auto constexpr method = CordzUpdateTracker::kRemovePrefix; CordzUpdateScope scope(contents_.cordz_info(), method); if (tree->IsBtree()) { @@ -954,17 +954,17 @@ void Cord::RemovePrefix(size_t n) { tree = VerifyTree(newrep); } contents_.SetTreeOrEmpty(tree, scope); - } -} - -void Cord::RemoveSuffix(size_t n) { - ABSL_INTERNAL_CHECK(n <= size(), - y_absl::StrCat("Requested suffix size ", n, - " exceeds Cord's size ", size())); - CordRep* tree = contents_.tree(); - if (tree == nullptr) { - contents_.reduce_size(n); - } else { + } +} + +void Cord::RemoveSuffix(size_t n) { + ABSL_INTERNAL_CHECK(n <= size(), + y_absl::StrCat("Requested suffix size ", n, + " exceeds Cord's size ", size())); + CordRep* tree = contents_.tree(); + if (tree == nullptr) { + contents_.reduce_size(n); + } else { auto constexpr method = CordzUpdateTracker::kRemoveSuffix; CordzUpdateScope scope(contents_.cordz_info(), method); if (tree->IsBtree()) { @@ -975,296 +975,296 @@ void Cord::RemoveSuffix(size_t n) { tree = VerifyTree(newrep); } contents_.SetTreeOrEmpty(tree, scope); - } -} - -// Work item for NewSubRange(). -struct SubRange { - SubRange(CordRep* a_node, size_t a_pos, size_t a_n) - : node(a_node), pos(a_pos), n(a_n) {} - CordRep* node; // nullptr means concat last 2 results. - size_t pos; - size_t n; -}; - -static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) { - y_absl::InlinedVector<CordRep*, kInlinedVectorSize> results; - y_absl::InlinedVector<SubRange, kInlinedVectorSize> todo; - todo.push_back(SubRange(node, pos, n)); - do { - const SubRange& sr = todo.back(); - node = sr.node; - pos = sr.pos; - n = sr.n; - todo.pop_back(); - - if (node == nullptr) { - assert(results.size() >= 2); - CordRep* right = results.back(); - results.pop_back(); - CordRep* left = results.back(); - results.pop_back(); - results.push_back(Concat(left, right)); - } else if (pos == 0 && n == node->length) { + } +} + +// Work item for NewSubRange(). +struct SubRange { + SubRange(CordRep* a_node, size_t a_pos, size_t a_n) + : node(a_node), pos(a_pos), n(a_n) {} + CordRep* node; // nullptr means concat last 2 results. + size_t pos; + size_t n; +}; + +static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) { + y_absl::InlinedVector<CordRep*, kInlinedVectorSize> results; + y_absl::InlinedVector<SubRange, kInlinedVectorSize> todo; + todo.push_back(SubRange(node, pos, n)); + do { + const SubRange& sr = todo.back(); + node = sr.node; + pos = sr.pos; + n = sr.n; + todo.pop_back(); + + if (node == nullptr) { + assert(results.size() >= 2); + CordRep* right = results.back(); + results.pop_back(); + CordRep* left = results.back(); + results.pop_back(); + results.push_back(Concat(left, right)); + } else if (pos == 0 && n == node->length) { results.push_back(CordRep::Ref(node)); } else if (!node->IsConcat()) { if (node->IsSubstring()) { - pos += node->substring()->start; - node = node->substring()->child; - } + pos += node->substring()->start; + node = node->substring()->child; + } results.push_back(NewSubstring(CordRep::Ref(node), pos, n)); - } else if (pos + n <= node->concat()->left->length) { - todo.push_back(SubRange(node->concat()->left, pos, n)); - } else if (pos >= node->concat()->left->length) { - pos -= node->concat()->left->length; - todo.push_back(SubRange(node->concat()->right, pos, n)); - } else { - size_t left_n = node->concat()->left->length - pos; - todo.push_back(SubRange(nullptr, 0, 0)); // Concat() - todo.push_back(SubRange(node->concat()->right, 0, n - left_n)); - todo.push_back(SubRange(node->concat()->left, pos, left_n)); - } - } while (!todo.empty()); - assert(results.size() == 1); - return results[0]; -} - -Cord Cord::Subcord(size_t pos, size_t new_size) const { - Cord sub_cord; - size_t length = size(); - if (pos > length) pos = length; - if (new_size > length - pos) new_size = length - pos; + } else if (pos + n <= node->concat()->left->length) { + todo.push_back(SubRange(node->concat()->left, pos, n)); + } else if (pos >= node->concat()->left->length) { + pos -= node->concat()->left->length; + todo.push_back(SubRange(node->concat()->right, pos, n)); + } else { + size_t left_n = node->concat()->left->length - pos; + todo.push_back(SubRange(nullptr, 0, 0)); // Concat() + todo.push_back(SubRange(node->concat()->right, 0, n - left_n)); + todo.push_back(SubRange(node->concat()->left, pos, left_n)); + } + } while (!todo.empty()); + assert(results.size() == 1); + return results[0]; +} + +Cord Cord::Subcord(size_t pos, size_t new_size) const { + Cord sub_cord; + size_t length = size(); + if (pos > length) pos = length; + if (new_size > length - pos) new_size = length - pos; if (new_size == 0) return sub_cord; - CordRep* tree = contents_.tree(); - if (tree == nullptr) { - // sub_cord is newly constructed, no need to re-zero-out the tail of - // contents_ memory. - sub_cord.contents_.set_data(contents_.data() + pos, new_size, false); + CordRep* tree = contents_.tree(); + if (tree == nullptr) { + // sub_cord is newly constructed, no need to re-zero-out the tail of + // contents_ memory. + sub_cord.contents_.set_data(contents_.data() + pos, new_size, false); return sub_cord; } if (new_size <= InlineRep::kMaxInline) { char* dest = sub_cord.contents_.data_.as_chars(); - Cord::ChunkIterator it = chunk_begin(); - it.AdvanceBytes(pos); - size_t remaining_size = new_size; - while (remaining_size > it->size()) { - cord_internal::SmallMemmove(dest, it->data(), it->size()); - remaining_size -= it->size(); - dest += it->size(); - ++it; - } - cord_internal::SmallMemmove(dest, it->data(), remaining_size); + Cord::ChunkIterator it = chunk_begin(); + it.AdvanceBytes(pos); + size_t remaining_size = new_size; + while (remaining_size > it->size()) { + cord_internal::SmallMemmove(dest, it->data(), it->size()); + remaining_size -= it->size(); + dest += it->size(); + ++it; + } + cord_internal::SmallMemmove(dest, it->data(), remaining_size); sub_cord.contents_.set_inline_size(new_size); return sub_cord; } if (tree->IsBtree()) { tree = tree->btree()->SubTree(pos, new_size); - } else { + } else { tree = NewSubRange(tree, pos, new_size); - } + } sub_cord.contents_.EmplaceTree(tree, contents_.data_, CordzUpdateTracker::kSubCord); - return sub_cord; -} - -// -------------------------------------------------------------------- -// Balancing - -class CordForest { - public: - explicit CordForest(size_t length) - : root_length_(length), trees_(kMinLengthSize, nullptr) {} - - void Build(CordRep* cord_root) { - std::vector<CordRep*> pending = {cord_root}; - - while (!pending.empty()) { - CordRep* node = pending.back(); - pending.pop_back(); - CheckNode(node); + return sub_cord; +} + +// -------------------------------------------------------------------- +// Balancing + +class CordForest { + public: + explicit CordForest(size_t length) + : root_length_(length), trees_(kMinLengthSize, nullptr) {} + + void Build(CordRep* cord_root) { + std::vector<CordRep*> pending = {cord_root}; + + while (!pending.empty()) { + CordRep* node = pending.back(); + pending.pop_back(); + CheckNode(node); if (ABSL_PREDICT_FALSE(!node->IsConcat())) { - AddNode(node); - continue; - } - - CordRepConcat* concat_node = node->concat(); - if (concat_node->depth() >= kMinLengthSize || - concat_node->length < min_length[concat_node->depth()]) { - pending.push_back(concat_node->right); - pending.push_back(concat_node->left); - - if (concat_node->refcount.IsOne()) { - concat_node->left = concat_freelist_; - concat_freelist_ = concat_node; - } else { + AddNode(node); + continue; + } + + CordRepConcat* concat_node = node->concat(); + if (concat_node->depth() >= kMinLengthSize || + concat_node->length < min_length[concat_node->depth()]) { + pending.push_back(concat_node->right); + pending.push_back(concat_node->left); + + if (concat_node->refcount.IsOne()) { + concat_node->left = concat_freelist_; + concat_freelist_ = concat_node; + } else { CordRep::Ref(concat_node->right); CordRep::Ref(concat_node->left); CordRep::Unref(concat_node); - } - } else { - AddNode(node); - } - } - } - - CordRep* ConcatNodes() { - CordRep* sum = nullptr; - for (auto* node : trees_) { - if (node == nullptr) continue; - - sum = PrependNode(node, sum); - root_length_ -= node->length; - if (root_length_ == 0) break; - } - ABSL_INTERNAL_CHECK(sum != nullptr, "Failed to locate sum node"); - return VerifyTree(sum); - } - - private: - CordRep* AppendNode(CordRep* node, CordRep* sum) { - return (sum == nullptr) ? node : MakeConcat(sum, node); - } - - CordRep* PrependNode(CordRep* node, CordRep* sum) { - return (sum == nullptr) ? node : MakeConcat(node, sum); - } - - void AddNode(CordRep* node) { - CordRep* sum = nullptr; - + } + } else { + AddNode(node); + } + } + } + + CordRep* ConcatNodes() { + CordRep* sum = nullptr; + for (auto* node : trees_) { + if (node == nullptr) continue; + + sum = PrependNode(node, sum); + root_length_ -= node->length; + if (root_length_ == 0) break; + } + ABSL_INTERNAL_CHECK(sum != nullptr, "Failed to locate sum node"); + return VerifyTree(sum); + } + + private: + CordRep* AppendNode(CordRep* node, CordRep* sum) { + return (sum == nullptr) ? node : MakeConcat(sum, node); + } + + CordRep* PrependNode(CordRep* node, CordRep* sum) { + return (sum == nullptr) ? node : MakeConcat(node, sum); + } + + void AddNode(CordRep* node) { + CordRep* sum = nullptr; + // Collect together everything with which we will merge with node - int i = 0; - for (; node->length > min_length[i + 1]; ++i) { - auto& tree_at_i = trees_[i]; - - if (tree_at_i == nullptr) continue; - sum = PrependNode(tree_at_i, sum); - tree_at_i = nullptr; - } - - sum = AppendNode(node, sum); - - // Insert sum into appropriate place in the forest - for (; sum->length >= min_length[i]; ++i) { - auto& tree_at_i = trees_[i]; - if (tree_at_i == nullptr) continue; - - sum = MakeConcat(tree_at_i, sum); - tree_at_i = nullptr; - } - - // min_length[0] == 1, which means sum->length >= min_length[0] - assert(i > 0); - trees_[i - 1] = sum; - } - - // Make concat node trying to resue existing CordRepConcat nodes we - // already collected in the concat_freelist_. - CordRep* MakeConcat(CordRep* left, CordRep* right) { - if (concat_freelist_ == nullptr) return RawConcat(left, right); - - CordRepConcat* rep = concat_freelist_; - if (concat_freelist_->left == nullptr) { - concat_freelist_ = nullptr; - } else { - concat_freelist_ = concat_freelist_->left->concat(); - } - SetConcatChildren(rep, left, right); - - return rep; - } - - static void CheckNode(CordRep* node) { - ABSL_INTERNAL_CHECK(node->length != 0u, ""); + int i = 0; + for (; node->length > min_length[i + 1]; ++i) { + auto& tree_at_i = trees_[i]; + + if (tree_at_i == nullptr) continue; + sum = PrependNode(tree_at_i, sum); + tree_at_i = nullptr; + } + + sum = AppendNode(node, sum); + + // Insert sum into appropriate place in the forest + for (; sum->length >= min_length[i]; ++i) { + auto& tree_at_i = trees_[i]; + if (tree_at_i == nullptr) continue; + + sum = MakeConcat(tree_at_i, sum); + tree_at_i = nullptr; + } + + // min_length[0] == 1, which means sum->length >= min_length[0] + assert(i > 0); + trees_[i - 1] = sum; + } + + // Make concat node trying to resue existing CordRepConcat nodes we + // already collected in the concat_freelist_. + CordRep* MakeConcat(CordRep* left, CordRep* right) { + if (concat_freelist_ == nullptr) return RawConcat(left, right); + + CordRepConcat* rep = concat_freelist_; + if (concat_freelist_->left == nullptr) { + concat_freelist_ = nullptr; + } else { + concat_freelist_ = concat_freelist_->left->concat(); + } + SetConcatChildren(rep, left, right); + + return rep; + } + + static void CheckNode(CordRep* node) { + ABSL_INTERNAL_CHECK(node->length != 0u, ""); if (node->IsConcat()) { - ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, ""); - ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, ""); - ABSL_INTERNAL_CHECK(node->length == (node->concat()->left->length + - node->concat()->right->length), - ""); - } - } - - size_t root_length_; - - // use an inlined vector instead of a flat array to get bounds checking - y_absl::InlinedVector<CordRep*, kInlinedVectorSize> trees_; - - // List of concat nodes we can re-use for Cord balancing. - CordRepConcat* concat_freelist_ = nullptr; -}; - -static CordRep* Rebalance(CordRep* node) { - VerifyTree(node); + ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, ""); + ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, ""); + ABSL_INTERNAL_CHECK(node->length == (node->concat()->left->length + + node->concat()->right->length), + ""); + } + } + + size_t root_length_; + + // use an inlined vector instead of a flat array to get bounds checking + y_absl::InlinedVector<CordRep*, kInlinedVectorSize> trees_; + + // List of concat nodes we can re-use for Cord balancing. + CordRepConcat* concat_freelist_ = nullptr; +}; + +static CordRep* Rebalance(CordRep* node) { + VerifyTree(node); assert(node->IsConcat()); - - if (node->length == 0) { - return nullptr; - } - - CordForest forest(node->length); - forest.Build(node); - return forest.ConcatNodes(); -} - -// -------------------------------------------------------------------- -// Comparators - -namespace { - -int ClampResult(int memcmp_res) { - return static_cast<int>(memcmp_res > 0) - static_cast<int>(memcmp_res < 0); -} - -int CompareChunks(y_absl::string_view* lhs, y_absl::string_view* rhs, - size_t* size_to_compare) { - size_t compared_size = std::min(lhs->size(), rhs->size()); - assert(*size_to_compare >= compared_size); - *size_to_compare -= compared_size; - - int memcmp_res = ::memcmp(lhs->data(), rhs->data(), compared_size); - if (memcmp_res != 0) return memcmp_res; - - lhs->remove_prefix(compared_size); - rhs->remove_prefix(compared_size); - - return 0; -} - -// This overload set computes comparison results from memcmp result. This -// interface is used inside GenericCompare below. Differet implementations -// are specialized for int and bool. For int we clamp result to {-1, 0, 1} -// set. For bool we just interested in "value == 0". -template <typename ResultType> -ResultType ComputeCompareResult(int memcmp_res) { - return ClampResult(memcmp_res); -} -template <> -bool ComputeCompareResult<bool>(int memcmp_res) { - return memcmp_res == 0; -} - -} // namespace - + + if (node->length == 0) { + return nullptr; + } + + CordForest forest(node->length); + forest.Build(node); + return forest.ConcatNodes(); +} + +// -------------------------------------------------------------------- +// Comparators + +namespace { + +int ClampResult(int memcmp_res) { + return static_cast<int>(memcmp_res > 0) - static_cast<int>(memcmp_res < 0); +} + +int CompareChunks(y_absl::string_view* lhs, y_absl::string_view* rhs, + size_t* size_to_compare) { + size_t compared_size = std::min(lhs->size(), rhs->size()); + assert(*size_to_compare >= compared_size); + *size_to_compare -= compared_size; + + int memcmp_res = ::memcmp(lhs->data(), rhs->data(), compared_size); + if (memcmp_res != 0) return memcmp_res; + + lhs->remove_prefix(compared_size); + rhs->remove_prefix(compared_size); + + return 0; +} + +// This overload set computes comparison results from memcmp result. This +// interface is used inside GenericCompare below. Differet implementations +// are specialized for int and bool. For int we clamp result to {-1, 0, 1} +// set. For bool we just interested in "value == 0". +template <typename ResultType> +ResultType ComputeCompareResult(int memcmp_res) { + return ClampResult(memcmp_res); +} +template <> +bool ComputeCompareResult<bool>(int memcmp_res) { + return memcmp_res == 0; +} + +} // namespace + // Helper routine. Locates the first flat or external chunk of the Cord without // initializing the iterator, and returns a string_view referencing the data. -inline y_absl::string_view Cord::InlineRep::FindFlatStartPiece() const { +inline y_absl::string_view Cord::InlineRep::FindFlatStartPiece() const { if (!is_tree()) { return y_absl::string_view(data_.as_chars(), data_.inline_size()); - } - - CordRep* node = tree(); + } + + CordRep* node = tree(); if (node->IsFlat()) { return y_absl::string_view(node->flat()->Data(), node->length); - } - + } + if (node->IsExternal()) { - return y_absl::string_view(node->external()->base, node->length); - } - + return y_absl::string_view(node->external()->base, node->length); + } + if (node->IsBtree()) { CordRepBtree* tree = node->btree(); int height = tree->height(); @@ -1274,264 +1274,264 @@ inline y_absl::string_view Cord::InlineRep::FindFlatStartPiece() const { return tree->Data(tree->begin()); } - // Walk down the left branches until we hit a non-CONCAT node. + // Walk down the left branches until we hit a non-CONCAT node. while (node->IsConcat()) { - node = node->concat()->left; - } - - // Get the child node if we encounter a SUBSTRING. - size_t offset = 0; - size_t length = node->length; - assert(length != 0); - + node = node->concat()->left; + } + + // Get the child node if we encounter a SUBSTRING. + size_t offset = 0; + size_t length = node->length; + assert(length != 0); + if (node->IsSubstring()) { - offset = node->substring()->start; - node = node->substring()->child; - } - + offset = node->substring()->start; + node = node->substring()->child; + } + if (node->IsFlat()) { return y_absl::string_view(node->flat()->Data() + offset, length); - } - + } + assert(node->IsExternal() && "Expect FLAT or EXTERNAL node here"); - - return y_absl::string_view(node->external()->base + offset, length); -} - -inline int Cord::CompareSlowPath(y_absl::string_view rhs, size_t compared_size, - size_t size_to_compare) const { - auto advance = [](Cord::ChunkIterator* it, y_absl::string_view* chunk) { - if (!chunk->empty()) return true; - ++*it; - if (it->bytes_remaining_ == 0) return false; - *chunk = **it; - return true; - }; - - Cord::ChunkIterator lhs_it = chunk_begin(); - - // compared_size is inside first chunk. - y_absl::string_view lhs_chunk = - (lhs_it.bytes_remaining_ != 0) ? *lhs_it : y_absl::string_view(); - assert(compared_size <= lhs_chunk.size()); - assert(compared_size <= rhs.size()); - lhs_chunk.remove_prefix(compared_size); - rhs.remove_prefix(compared_size); - size_to_compare -= compared_size; // skip already compared size. - - while (advance(&lhs_it, &lhs_chunk) && !rhs.empty()) { - int comparison_result = CompareChunks(&lhs_chunk, &rhs, &size_to_compare); - if (comparison_result != 0) return comparison_result; - if (size_to_compare == 0) return 0; - } - - return static_cast<int>(rhs.empty()) - static_cast<int>(lhs_chunk.empty()); -} - -inline int Cord::CompareSlowPath(const Cord& rhs, size_t compared_size, - size_t size_to_compare) const { - auto advance = [](Cord::ChunkIterator* it, y_absl::string_view* chunk) { - if (!chunk->empty()) return true; - ++*it; - if (it->bytes_remaining_ == 0) return false; - *chunk = **it; - return true; - }; - - Cord::ChunkIterator lhs_it = chunk_begin(); - Cord::ChunkIterator rhs_it = rhs.chunk_begin(); - - // compared_size is inside both first chunks. - y_absl::string_view lhs_chunk = - (lhs_it.bytes_remaining_ != 0) ? *lhs_it : y_absl::string_view(); - y_absl::string_view rhs_chunk = - (rhs_it.bytes_remaining_ != 0) ? *rhs_it : y_absl::string_view(); - assert(compared_size <= lhs_chunk.size()); - assert(compared_size <= rhs_chunk.size()); - lhs_chunk.remove_prefix(compared_size); - rhs_chunk.remove_prefix(compared_size); - size_to_compare -= compared_size; // skip already compared size. - - while (advance(&lhs_it, &lhs_chunk) && advance(&rhs_it, &rhs_chunk)) { - int memcmp_res = CompareChunks(&lhs_chunk, &rhs_chunk, &size_to_compare); - if (memcmp_res != 0) return memcmp_res; - if (size_to_compare == 0) return 0; - } - - return static_cast<int>(rhs_chunk.empty()) - - static_cast<int>(lhs_chunk.empty()); -} - -inline y_absl::string_view Cord::GetFirstChunk(const Cord& c) { - return c.contents_.FindFlatStartPiece(); -} -inline y_absl::string_view Cord::GetFirstChunk(y_absl::string_view sv) { - return sv; -} - -// Compares up to 'size_to_compare' bytes of 'lhs' with 'rhs'. It is assumed -// that 'size_to_compare' is greater that size of smallest of first chunks. -template <typename ResultType, typename RHS> -ResultType GenericCompare(const Cord& lhs, const RHS& rhs, - size_t size_to_compare) { - y_absl::string_view lhs_chunk = Cord::GetFirstChunk(lhs); - y_absl::string_view rhs_chunk = Cord::GetFirstChunk(rhs); - - size_t compared_size = std::min(lhs_chunk.size(), rhs_chunk.size()); - assert(size_to_compare >= compared_size); - int memcmp_res = ::memcmp(lhs_chunk.data(), rhs_chunk.data(), compared_size); - if (compared_size == size_to_compare || memcmp_res != 0) { - return ComputeCompareResult<ResultType>(memcmp_res); - } - - return ComputeCompareResult<ResultType>( - lhs.CompareSlowPath(rhs, compared_size, size_to_compare)); -} - -bool Cord::EqualsImpl(y_absl::string_view rhs, size_t size_to_compare) const { - return GenericCompare<bool>(*this, rhs, size_to_compare); -} - -bool Cord::EqualsImpl(const Cord& rhs, size_t size_to_compare) const { - return GenericCompare<bool>(*this, rhs, size_to_compare); -} - -template <typename RHS> -inline int SharedCompareImpl(const Cord& lhs, const RHS& rhs) { - size_t lhs_size = lhs.size(); - size_t rhs_size = rhs.size(); - if (lhs_size == rhs_size) { - return GenericCompare<int>(lhs, rhs, lhs_size); - } - if (lhs_size < rhs_size) { - auto data_comp_res = GenericCompare<int>(lhs, rhs, lhs_size); - return data_comp_res == 0 ? -1 : data_comp_res; - } - - auto data_comp_res = GenericCompare<int>(lhs, rhs, rhs_size); - return data_comp_res == 0 ? +1 : data_comp_res; -} - -int Cord::Compare(y_absl::string_view rhs) const { - return SharedCompareImpl(*this, rhs); -} - -int Cord::CompareImpl(const Cord& rhs) const { - return SharedCompareImpl(*this, rhs); -} - -bool Cord::EndsWith(y_absl::string_view rhs) const { - size_t my_size = size(); - size_t rhs_size = rhs.size(); - - if (my_size < rhs_size) return false; - - Cord tmp(*this); - tmp.RemovePrefix(my_size - rhs_size); - return tmp.EqualsImpl(rhs, rhs_size); -} - -bool Cord::EndsWith(const Cord& rhs) const { - size_t my_size = size(); - size_t rhs_size = rhs.size(); - - if (my_size < rhs_size) return false; - - Cord tmp(*this); - tmp.RemovePrefix(my_size - rhs_size); - return tmp.EqualsImpl(rhs, rhs_size); -} - -// -------------------------------------------------------------------- -// Misc. - -Cord::operator TString() const { - TString s; - y_absl::CopyCordToString(*this, &s); - return s; -} - -void CopyCordToString(const Cord& src, TString* dst) { - if (!src.contents_.is_tree()) { - src.contents_.CopyTo(dst); - } else { - y_absl::strings_internal::STLStringResizeUninitialized(dst, src.size()); - src.CopyToArraySlowPath(&(*dst)[0]); - } -} - -void Cord::CopyToArraySlowPath(char* dst) const { - assert(contents_.is_tree()); - y_absl::string_view fragment; - if (GetFlatAux(contents_.tree(), &fragment)) { - memcpy(dst, fragment.data(), fragment.size()); - return; - } - for (y_absl::string_view chunk : Chunks()) { - memcpy(dst, chunk.data(), chunk.size()); - dst += chunk.size(); - } -} - + + return y_absl::string_view(node->external()->base + offset, length); +} + +inline int Cord::CompareSlowPath(y_absl::string_view rhs, size_t compared_size, + size_t size_to_compare) const { + auto advance = [](Cord::ChunkIterator* it, y_absl::string_view* chunk) { + if (!chunk->empty()) return true; + ++*it; + if (it->bytes_remaining_ == 0) return false; + *chunk = **it; + return true; + }; + + Cord::ChunkIterator lhs_it = chunk_begin(); + + // compared_size is inside first chunk. + y_absl::string_view lhs_chunk = + (lhs_it.bytes_remaining_ != 0) ? *lhs_it : y_absl::string_view(); + assert(compared_size <= lhs_chunk.size()); + assert(compared_size <= rhs.size()); + lhs_chunk.remove_prefix(compared_size); + rhs.remove_prefix(compared_size); + size_to_compare -= compared_size; // skip already compared size. + + while (advance(&lhs_it, &lhs_chunk) && !rhs.empty()) { + int comparison_result = CompareChunks(&lhs_chunk, &rhs, &size_to_compare); + if (comparison_result != 0) return comparison_result; + if (size_to_compare == 0) return 0; + } + + return static_cast<int>(rhs.empty()) - static_cast<int>(lhs_chunk.empty()); +} + +inline int Cord::CompareSlowPath(const Cord& rhs, size_t compared_size, + size_t size_to_compare) const { + auto advance = [](Cord::ChunkIterator* it, y_absl::string_view* chunk) { + if (!chunk->empty()) return true; + ++*it; + if (it->bytes_remaining_ == 0) return false; + *chunk = **it; + return true; + }; + + Cord::ChunkIterator lhs_it = chunk_begin(); + Cord::ChunkIterator rhs_it = rhs.chunk_begin(); + + // compared_size is inside both first chunks. + y_absl::string_view lhs_chunk = + (lhs_it.bytes_remaining_ != 0) ? *lhs_it : y_absl::string_view(); + y_absl::string_view rhs_chunk = + (rhs_it.bytes_remaining_ != 0) ? *rhs_it : y_absl::string_view(); + assert(compared_size <= lhs_chunk.size()); + assert(compared_size <= rhs_chunk.size()); + lhs_chunk.remove_prefix(compared_size); + rhs_chunk.remove_prefix(compared_size); + size_to_compare -= compared_size; // skip already compared size. + + while (advance(&lhs_it, &lhs_chunk) && advance(&rhs_it, &rhs_chunk)) { + int memcmp_res = CompareChunks(&lhs_chunk, &rhs_chunk, &size_to_compare); + if (memcmp_res != 0) return memcmp_res; + if (size_to_compare == 0) return 0; + } + + return static_cast<int>(rhs_chunk.empty()) - + static_cast<int>(lhs_chunk.empty()); +} + +inline y_absl::string_view Cord::GetFirstChunk(const Cord& c) { + return c.contents_.FindFlatStartPiece(); +} +inline y_absl::string_view Cord::GetFirstChunk(y_absl::string_view sv) { + return sv; +} + +// Compares up to 'size_to_compare' bytes of 'lhs' with 'rhs'. It is assumed +// that 'size_to_compare' is greater that size of smallest of first chunks. +template <typename ResultType, typename RHS> +ResultType GenericCompare(const Cord& lhs, const RHS& rhs, + size_t size_to_compare) { + y_absl::string_view lhs_chunk = Cord::GetFirstChunk(lhs); + y_absl::string_view rhs_chunk = Cord::GetFirstChunk(rhs); + + size_t compared_size = std::min(lhs_chunk.size(), rhs_chunk.size()); + assert(size_to_compare >= compared_size); + int memcmp_res = ::memcmp(lhs_chunk.data(), rhs_chunk.data(), compared_size); + if (compared_size == size_to_compare || memcmp_res != 0) { + return ComputeCompareResult<ResultType>(memcmp_res); + } + + return ComputeCompareResult<ResultType>( + lhs.CompareSlowPath(rhs, compared_size, size_to_compare)); +} + +bool Cord::EqualsImpl(y_absl::string_view rhs, size_t size_to_compare) const { + return GenericCompare<bool>(*this, rhs, size_to_compare); +} + +bool Cord::EqualsImpl(const Cord& rhs, size_t size_to_compare) const { + return GenericCompare<bool>(*this, rhs, size_to_compare); +} + +template <typename RHS> +inline int SharedCompareImpl(const Cord& lhs, const RHS& rhs) { + size_t lhs_size = lhs.size(); + size_t rhs_size = rhs.size(); + if (lhs_size == rhs_size) { + return GenericCompare<int>(lhs, rhs, lhs_size); + } + if (lhs_size < rhs_size) { + auto data_comp_res = GenericCompare<int>(lhs, rhs, lhs_size); + return data_comp_res == 0 ? -1 : data_comp_res; + } + + auto data_comp_res = GenericCompare<int>(lhs, rhs, rhs_size); + return data_comp_res == 0 ? +1 : data_comp_res; +} + +int Cord::Compare(y_absl::string_view rhs) const { + return SharedCompareImpl(*this, rhs); +} + +int Cord::CompareImpl(const Cord& rhs) const { + return SharedCompareImpl(*this, rhs); +} + +bool Cord::EndsWith(y_absl::string_view rhs) const { + size_t my_size = size(); + size_t rhs_size = rhs.size(); + + if (my_size < rhs_size) return false; + + Cord tmp(*this); + tmp.RemovePrefix(my_size - rhs_size); + return tmp.EqualsImpl(rhs, rhs_size); +} + +bool Cord::EndsWith(const Cord& rhs) const { + size_t my_size = size(); + size_t rhs_size = rhs.size(); + + if (my_size < rhs_size) return false; + + Cord tmp(*this); + tmp.RemovePrefix(my_size - rhs_size); + return tmp.EqualsImpl(rhs, rhs_size); +} + +// -------------------------------------------------------------------- +// Misc. + +Cord::operator TString() const { + TString s; + y_absl::CopyCordToString(*this, &s); + return s; +} + +void CopyCordToString(const Cord& src, TString* dst) { + if (!src.contents_.is_tree()) { + src.contents_.CopyTo(dst); + } else { + y_absl::strings_internal::STLStringResizeUninitialized(dst, src.size()); + src.CopyToArraySlowPath(&(*dst)[0]); + } +} + +void Cord::CopyToArraySlowPath(char* dst) const { + assert(contents_.is_tree()); + y_absl::string_view fragment; + if (GetFlatAux(contents_.tree(), &fragment)) { + memcpy(dst, fragment.data(), fragment.size()); + return; + } + for (y_absl::string_view chunk : Chunks()) { + memcpy(dst, chunk.data(), chunk.size()); + dst += chunk.size(); + } +} + Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() { auto& stack_of_right_children = stack_of_right_children_; if (stack_of_right_children.empty()) { - assert(!current_chunk_.empty()); // Called on invalid iterator. - // We have reached the end of the Cord. - return *this; - } - - // Process the next node on the stack. + assert(!current_chunk_.empty()); // Called on invalid iterator. + // We have reached the end of the Cord. + return *this; + } + + // Process the next node on the stack. CordRep* node = stack_of_right_children.back(); stack_of_right_children.pop_back(); - - // Walk down the left branches until we hit a non-CONCAT node. Save the - // right children to the stack for subsequent traversal. + + // Walk down the left branches until we hit a non-CONCAT node. Save the + // right children to the stack for subsequent traversal. while (node->IsConcat()) { stack_of_right_children.push_back(node->concat()->right); - node = node->concat()->left; - } - - // Get the child node if we encounter a SUBSTRING. - size_t offset = 0; - size_t length = node->length; + node = node->concat()->left; + } + + // Get the child node if we encounter a SUBSTRING. + size_t offset = 0; + size_t length = node->length; if (node->IsSubstring()) { - offset = node->substring()->start; - node = node->substring()->child; - } - + offset = node->substring()->start; + node = node->substring()->child; + } + assert(node->IsExternal() || node->IsFlat()); - assert(length != 0); - const char* data = + assert(length != 0); + const char* data = node->IsExternal() ? node->external()->base : node->flat()->Data(); - current_chunk_ = y_absl::string_view(data + offset, length); - current_leaf_ = node; - return *this; -} - -Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { + current_chunk_ = y_absl::string_view(data + offset, length); + current_leaf_ = node; + return *this; +} + +Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { ABSL_HARDENING_ASSERT(bytes_remaining_ >= n && "Attempted to iterate past `end()`"); - Cord subcord; + Cord subcord; auto constexpr method = CordzUpdateTracker::kCordReader; - - if (n <= InlineRep::kMaxInline) { - // Range to read fits in inline data. Flatten it. - char* data = subcord.contents_.set_data(n); - while (n > current_chunk_.size()) { - memcpy(data, current_chunk_.data(), current_chunk_.size()); - data += current_chunk_.size(); - n -= current_chunk_.size(); - ++*this; - } - memcpy(data, current_chunk_.data(), n); - if (n < current_chunk_.size()) { - RemoveChunkPrefix(n); - } else if (n > 0) { - ++*this; - } - return subcord; - } + + if (n <= InlineRep::kMaxInline) { + // Range to read fits in inline data. Flatten it. + char* data = subcord.contents_.set_data(n); + while (n > current_chunk_.size()) { + memcpy(data, current_chunk_.data(), current_chunk_.size()); + data += current_chunk_.size(); + n -= current_chunk_.size(); + ++*this; + } + memcpy(data, current_chunk_.data(), n); + if (n < current_chunk_.size()) { + RemoveChunkPrefix(n); + } else if (n > 0) { + ++*this; + } + return subcord; + } if (btree_reader_) { size_t chunk_size = current_chunk_.size(); @@ -1552,261 +1552,261 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { } auto& stack_of_right_children = stack_of_right_children_; - if (n < current_chunk_.size()) { - // Range to read is a proper subrange of the current chunk. - assert(current_leaf_ != nullptr); + if (n < current_chunk_.size()) { + // Range to read is a proper subrange of the current chunk. + assert(current_leaf_ != nullptr); CordRep* subnode = CordRep::Ref(current_leaf_); const char* data = subnode->IsExternal() ? subnode->external()->base : subnode->flat()->Data(); - subnode = NewSubstring(subnode, current_chunk_.data() - data, n); + subnode = NewSubstring(subnode, current_chunk_.data() - data, n); subcord.contents_.EmplaceTree(VerifyTree(subnode), method); - RemoveChunkPrefix(n); - return subcord; - } - - // Range to read begins with a proper subrange of the current chunk. - assert(!current_chunk_.empty()); - assert(current_leaf_ != nullptr); + RemoveChunkPrefix(n); + return subcord; + } + + // Range to read begins with a proper subrange of the current chunk. + assert(!current_chunk_.empty()); + assert(current_leaf_ != nullptr); CordRep* subnode = CordRep::Ref(current_leaf_); - if (current_chunk_.size() < subnode->length) { + if (current_chunk_.size() < subnode->length) { const char* data = subnode->IsExternal() ? subnode->external()->base : subnode->flat()->Data(); - subnode = NewSubstring(subnode, current_chunk_.data() - data, - current_chunk_.size()); - } - n -= current_chunk_.size(); - bytes_remaining_ -= current_chunk_.size(); - - // Process the next node(s) on the stack, reading whole subtrees depending on - // their length and how many bytes we are advancing. - CordRep* node = nullptr; + subnode = NewSubstring(subnode, current_chunk_.data() - data, + current_chunk_.size()); + } + n -= current_chunk_.size(); + bytes_remaining_ -= current_chunk_.size(); + + // Process the next node(s) on the stack, reading whole subtrees depending on + // their length and how many bytes we are advancing. + CordRep* node = nullptr; while (!stack_of_right_children.empty()) { node = stack_of_right_children.back(); stack_of_right_children.pop_back(); - if (node->length > n) break; - // TODO(qrczak): This might unnecessarily recreate existing concat nodes. - // Avoiding that would need pretty complicated logic (instead of + if (node->length > n) break; + // TODO(qrczak): This might unnecessarily recreate existing concat nodes. + // Avoiding that would need pretty complicated logic (instead of // current_leaf, keep current_subtree_ which points to the highest node - // such that the current leaf can be found on the path of left children - // starting from current_subtree_; delay creating subnode while node is - // below current_subtree_; find the proper node along the path of left - // children starting from current_subtree_ if this loop exits while staying - // below current_subtree_; etc.; alternatively, push parents instead of - // right children on the stack). + // such that the current leaf can be found on the path of left children + // starting from current_subtree_; delay creating subnode while node is + // below current_subtree_; find the proper node along the path of left + // children starting from current_subtree_ if this loop exits while staying + // below current_subtree_; etc.; alternatively, push parents instead of + // right children on the stack). subnode = Concat(subnode, CordRep::Ref(node)); - n -= node->length; - bytes_remaining_ -= node->length; - node = nullptr; - } - - if (node == nullptr) { - // We have reached the end of the Cord. - assert(bytes_remaining_ == 0); + n -= node->length; + bytes_remaining_ -= node->length; + node = nullptr; + } + + if (node == nullptr) { + // We have reached the end of the Cord. + assert(bytes_remaining_ == 0); subcord.contents_.EmplaceTree(VerifyTree(subnode), method); - return subcord; - } - - // Walk down the appropriate branches until we hit a non-CONCAT node. Save the - // right children to the stack for subsequent traversal. + return subcord; + } + + // Walk down the appropriate branches until we hit a non-CONCAT node. Save the + // right children to the stack for subsequent traversal. while (node->IsConcat()) { - if (node->concat()->left->length > n) { - // Push right, descend left. + if (node->concat()->left->length > n) { + // Push right, descend left. stack_of_right_children.push_back(node->concat()->right); - node = node->concat()->left; - } else { - // Read left, descend right. + node = node->concat()->left; + } else { + // Read left, descend right. subnode = Concat(subnode, CordRep::Ref(node->concat()->left)); - n -= node->concat()->left->length; - bytes_remaining_ -= node->concat()->left->length; - node = node->concat()->right; - } - } - - // Get the child node if we encounter a SUBSTRING. - size_t offset = 0; - size_t length = node->length; + n -= node->concat()->left->length; + bytes_remaining_ -= node->concat()->left->length; + node = node->concat()->right; + } + } + + // Get the child node if we encounter a SUBSTRING. + size_t offset = 0; + size_t length = node->length; if (node->IsSubstring()) { - offset = node->substring()->start; - node = node->substring()->child; - } - - // Range to read ends with a proper (possibly empty) subrange of the current - // chunk. + offset = node->substring()->start; + node = node->substring()->child; + } + + // Range to read ends with a proper (possibly empty) subrange of the current + // chunk. assert(node->IsExternal() || node->IsFlat()); - assert(length > n); + assert(length > n); if (n > 0) { subnode = Concat(subnode, NewSubstring(CordRep::Ref(node), offset, n)); } - const char* data = + const char* data = node->IsExternal() ? node->external()->base : node->flat()->Data(); - current_chunk_ = y_absl::string_view(data + offset + n, length - n); - current_leaf_ = node; - bytes_remaining_ -= n; + current_chunk_ = y_absl::string_view(data + offset + n, length - n); + current_leaf_ = node; + bytes_remaining_ -= n; subcord.contents_.EmplaceTree(VerifyTree(subnode), method); - return subcord; -} - -void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) { - assert(bytes_remaining_ >= n && "Attempted to iterate past `end()`"); - assert(n >= current_chunk_.size()); // This should only be called when - // iterating to a new node. - - n -= current_chunk_.size(); - bytes_remaining_ -= current_chunk_.size(); - + return subcord; +} + +void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) { + assert(bytes_remaining_ >= n && "Attempted to iterate past `end()`"); + assert(n >= current_chunk_.size()); // This should only be called when + // iterating to a new node. + + n -= current_chunk_.size(); + bytes_remaining_ -= current_chunk_.size(); + if (stack_of_right_children_.empty()) { // We have reached the end of the Cord. assert(bytes_remaining_ == 0); return; } - // Process the next node(s) on the stack, skipping whole subtrees depending on - // their length and how many bytes we are advancing. - CordRep* node = nullptr; + // Process the next node(s) on the stack, skipping whole subtrees depending on + // their length and how many bytes we are advancing. + CordRep* node = nullptr; auto& stack_of_right_children = stack_of_right_children_; while (!stack_of_right_children.empty()) { node = stack_of_right_children.back(); stack_of_right_children.pop_back(); - if (node->length > n) break; - n -= node->length; - bytes_remaining_ -= node->length; - node = nullptr; - } - - if (node == nullptr) { - // We have reached the end of the Cord. - assert(bytes_remaining_ == 0); - return; - } - - // Walk down the appropriate branches until we hit a non-CONCAT node. Save the - // right children to the stack for subsequent traversal. + if (node->length > n) break; + n -= node->length; + bytes_remaining_ -= node->length; + node = nullptr; + } + + if (node == nullptr) { + // We have reached the end of the Cord. + assert(bytes_remaining_ == 0); + return; + } + + // Walk down the appropriate branches until we hit a non-CONCAT node. Save the + // right children to the stack for subsequent traversal. while (node->IsConcat()) { - if (node->concat()->left->length > n) { - // Push right, descend left. + if (node->concat()->left->length > n) { + // Push right, descend left. stack_of_right_children.push_back(node->concat()->right); - node = node->concat()->left; - } else { - // Skip left, descend right. - n -= node->concat()->left->length; - bytes_remaining_ -= node->concat()->left->length; - node = node->concat()->right; - } - } - - // Get the child node if we encounter a SUBSTRING. - size_t offset = 0; - size_t length = node->length; + node = node->concat()->left; + } else { + // Skip left, descend right. + n -= node->concat()->left->length; + bytes_remaining_ -= node->concat()->left->length; + node = node->concat()->right; + } + } + + // Get the child node if we encounter a SUBSTRING. + size_t offset = 0; + size_t length = node->length; if (node->IsSubstring()) { - offset = node->substring()->start; - node = node->substring()->child; - } - + offset = node->substring()->start; + node = node->substring()->child; + } + assert(node->IsExternal() || node->IsFlat()); - assert(length > n); - const char* data = + assert(length > n); + const char* data = node->IsExternal() ? node->external()->base : node->flat()->Data(); - current_chunk_ = y_absl::string_view(data + offset + n, length - n); - current_leaf_ = node; - bytes_remaining_ -= n; -} - -char Cord::operator[](size_t i) const { + current_chunk_ = y_absl::string_view(data + offset + n, length - n); + current_leaf_ = node; + bytes_remaining_ -= n; +} + +char Cord::operator[](size_t i) const { ABSL_HARDENING_ASSERT(i < size()); - size_t offset = i; - const CordRep* rep = contents_.tree(); - if (rep == nullptr) { - return contents_.data()[i]; - } - while (true) { - assert(rep != nullptr); - assert(offset < rep->length); + size_t offset = i; + const CordRep* rep = contents_.tree(); + if (rep == nullptr) { + return contents_.data()[i]; + } + while (true) { + assert(rep != nullptr); + assert(offset < rep->length); if (rep->IsFlat()) { - // Get the "i"th character directly from the flat array. + // Get the "i"th character directly from the flat array. return rep->flat()->Data()[offset]; } else if (rep->IsBtree()) { return rep->btree()->GetCharacter(offset); } else if (rep->IsExternal()) { - // Get the "i"th character from the external array. - return rep->external()->base[offset]; + // Get the "i"th character from the external array. + return rep->external()->base[offset]; } else if (rep->IsConcat()) { - // Recursively branch to the side of the concatenation that the "i"th - // character is on. - size_t left_length = rep->concat()->left->length; - if (offset < left_length) { - rep = rep->concat()->left; - } else { - offset -= left_length; - rep = rep->concat()->right; - } - } else { - // This must be a substring a node, so bypass it to get to the child. + // Recursively branch to the side of the concatenation that the "i"th + // character is on. + size_t left_length = rep->concat()->left->length; + if (offset < left_length) { + rep = rep->concat()->left; + } else { + offset -= left_length; + rep = rep->concat()->right; + } + } else { + // This must be a substring a node, so bypass it to get to the child. assert(rep->IsSubstring()); - offset += rep->substring()->start; - rep = rep->substring()->child; - } - } -} - -y_absl::string_view Cord::FlattenSlowPath() { + offset += rep->substring()->start; + rep = rep->substring()->child; + } + } +} + +y_absl::string_view Cord::FlattenSlowPath() { assert(contents_.is_tree()); - size_t total_size = size(); - CordRep* new_rep; - char* new_buffer; - - // Try to put the contents into a new flat rep. If they won't fit in the - // biggest possible flat node, use an external rep instead. - if (total_size <= kMaxFlatLength) { + size_t total_size = size(); + CordRep* new_rep; + char* new_buffer; + + // Try to put the contents into a new flat rep. If they won't fit in the + // biggest possible flat node, use an external rep instead. + if (total_size <= kMaxFlatLength) { new_rep = CordRepFlat::New(total_size); - new_rep->length = total_size; + new_rep->length = total_size; new_buffer = new_rep->flat()->Data(); - CopyToArraySlowPath(new_buffer); - } else { - new_buffer = std::allocator<char>().allocate(total_size); - CopyToArraySlowPath(new_buffer); - new_rep = y_absl::cord_internal::NewExternalRep( - y_absl::string_view(new_buffer, total_size), [](y_absl::string_view s) { - std::allocator<char>().deallocate(const_cast<char*>(s.data()), - s.size()); - }); - } + CopyToArraySlowPath(new_buffer); + } else { + new_buffer = std::allocator<char>().allocate(total_size); + CopyToArraySlowPath(new_buffer); + new_rep = y_absl::cord_internal::NewExternalRep( + y_absl::string_view(new_buffer, total_size), [](y_absl::string_view s) { + std::allocator<char>().deallocate(const_cast<char*>(s.data()), + s.size()); + }); + } CordzUpdateScope scope(contents_.cordz_info(), CordzUpdateTracker::kFlatten); CordRep::Unref(contents_.as_tree()); contents_.SetTree(new_rep, scope); - return y_absl::string_view(new_buffer, total_size); -} - -/* static */ bool Cord::GetFlatAux(CordRep* rep, y_absl::string_view* fragment) { - assert(rep != nullptr); + return y_absl::string_view(new_buffer, total_size); +} + +/* static */ bool Cord::GetFlatAux(CordRep* rep, y_absl::string_view* fragment) { + assert(rep != nullptr); if (rep->IsFlat()) { *fragment = y_absl::string_view(rep->flat()->Data(), rep->length); - return true; + return true; } else if (rep->IsExternal()) { - *fragment = y_absl::string_view(rep->external()->base, rep->length); - return true; + *fragment = y_absl::string_view(rep->external()->base, rep->length); + return true; } else if (rep->IsBtree()) { return rep->btree()->IsFlat(fragment); } else if (rep->IsSubstring()) { - CordRep* child = rep->substring()->child; + CordRep* child = rep->substring()->child; if (child->IsFlat()) { *fragment = y_absl::string_view( child->flat()->Data() + rep->substring()->start, rep->length); - return true; + return true; } else if (child->IsExternal()) { - *fragment = y_absl::string_view( - child->external()->base + rep->substring()->start, rep->length); - return true; + *fragment = y_absl::string_view( + child->external()->base + rep->substring()->start, rep->length); + return true; } else if (child->IsBtree()) { return child->btree()->IsFlat(rep->substring()->start, rep->length, fragment); - } - } - return false; -} - -/* static */ void Cord::ForEachChunkAux( - y_absl::cord_internal::CordRep* rep, - y_absl::FunctionRef<void(y_absl::string_view)> callback) { + } + } + return false; +} + +/* static */ void Cord::ForEachChunkAux( + y_absl::cord_internal::CordRep* rep, + y_absl::FunctionRef<void(y_absl::string_view)> callback) { if (rep->IsBtree()) { ChunkIterator it(rep), end; while (it != end) { @@ -1816,175 +1816,175 @@ y_absl::string_view Cord::FlattenSlowPath() { return; } - assert(rep != nullptr); - int stack_pos = 0; - constexpr int stack_max = 128; - // Stack of right branches for tree traversal - y_absl::cord_internal::CordRep* stack[stack_max]; - y_absl::cord_internal::CordRep* current_node = rep; - while (true) { + assert(rep != nullptr); + int stack_pos = 0; + constexpr int stack_max = 128; + // Stack of right branches for tree traversal + y_absl::cord_internal::CordRep* stack[stack_max]; + y_absl::cord_internal::CordRep* current_node = rep; + while (true) { if (current_node->IsConcat()) { - if (stack_pos == stack_max) { - // There's no more room on our stack array to add another right branch, - // and the idea is to avoid allocations, so call this function - // recursively to navigate this subtree further. (This is not something - // we expect to happen in practice). - ForEachChunkAux(current_node, callback); - - // Pop the next right branch and iterate. - current_node = stack[--stack_pos]; - continue; - } else { - // Save the right branch for later traversal and continue down the left - // branch. - stack[stack_pos++] = current_node->concat()->right; - current_node = current_node->concat()->left; - continue; - } - } - // This is a leaf node, so invoke our callback. - y_absl::string_view chunk; - bool success = GetFlatAux(current_node, &chunk); - assert(success); - if (success) { - callback(chunk); - } - if (stack_pos == 0) { - // end of traversal - return; - } - current_node = stack[--stack_pos]; - } -} - + if (stack_pos == stack_max) { + // There's no more room on our stack array to add another right branch, + // and the idea is to avoid allocations, so call this function + // recursively to navigate this subtree further. (This is not something + // we expect to happen in practice). + ForEachChunkAux(current_node, callback); + + // Pop the next right branch and iterate. + current_node = stack[--stack_pos]; + continue; + } else { + // Save the right branch for later traversal and continue down the left + // branch. + stack[stack_pos++] = current_node->concat()->right; + current_node = current_node->concat()->left; + continue; + } + } + // This is a leaf node, so invoke our callback. + y_absl::string_view chunk; + bool success = GetFlatAux(current_node, &chunk); + assert(success); + if (success) { + callback(chunk); + } + if (stack_pos == 0) { + // end of traversal + return; + } + current_node = stack[--stack_pos]; + } +} + static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, int indent) { - const int kIndentStep = 1; - y_absl::InlinedVector<CordRep*, kInlinedVectorSize> stack; - y_absl::InlinedVector<int, kInlinedVectorSize> indents; - for (;;) { - *os << std::setw(3) << rep->refcount.Get(); - *os << " " << std::setw(7) << rep->length; - *os << " ["; - if (include_data) *os << static_cast<void*>(rep); - *os << "]"; - *os << " " << (IsRootBalanced(rep) ? 'b' : 'u'); - *os << " " << std::setw(indent) << ""; + const int kIndentStep = 1; + y_absl::InlinedVector<CordRep*, kInlinedVectorSize> stack; + y_absl::InlinedVector<int, kInlinedVectorSize> indents; + for (;;) { + *os << std::setw(3) << rep->refcount.Get(); + *os << " " << std::setw(7) << rep->length; + *os << " ["; + if (include_data) *os << static_cast<void*>(rep); + *os << "]"; + *os << " " << (IsRootBalanced(rep) ? 'b' : 'u'); + *os << " " << std::setw(indent) << ""; if (rep->IsConcat()) { - *os << "CONCAT depth=" << Depth(rep) << "\n"; - indent += kIndentStep; - indents.push_back(indent); - stack.push_back(rep->concat()->right); - rep = rep->concat()->left; + *os << "CONCAT depth=" << Depth(rep) << "\n"; + indent += kIndentStep; + indents.push_back(indent); + stack.push_back(rep->concat()->right); + rep = rep->concat()->left; } else if (rep->IsSubstring()) { - *os << "SUBSTRING @ " << rep->substring()->start << "\n"; - indent += kIndentStep; - rep = rep->substring()->child; + *os << "SUBSTRING @ " << rep->substring()->start << "\n"; + indent += kIndentStep; + rep = rep->substring()->child; } else { // Leaf or ring if (rep->IsExternal()) { - *os << "EXTERNAL ["; - if (include_data) - *os << y_absl::CEscape(TString(rep->external()->base, rep->length)); - *os << "]\n"; + *os << "EXTERNAL ["; + if (include_data) + *os << y_absl::CEscape(TString(rep->external()->base, rep->length)); + *os << "]\n"; } else if (rep->IsFlat()) { *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; - if (include_data) + if (include_data) *os << y_absl::CEscape(TString(rep->flat()->Data(), rep->length)); - *os << "]\n"; + *os << "]\n"; } else { CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os); - } - if (stack.empty()) break; - rep = stack.back(); - stack.pop_back(); - indent = indents.back(); - indents.pop_back(); - } - } - ABSL_INTERNAL_CHECK(indents.empty(), ""); -} - -static TString ReportError(CordRep* root, CordRep* node) { - std::ostringstream buf; - buf << "Error at node " << node << " in:"; - DumpNode(root, true, &buf); - return TString(buf.str()); -} - -static bool VerifyNode(CordRep* root, CordRep* start_node, - bool full_validation) { - y_absl::InlinedVector<CordRep*, 2> worklist; - worklist.push_back(start_node); - do { - CordRep* node = worklist.back(); - worklist.pop_back(); - - ABSL_INTERNAL_CHECK(node != nullptr, ReportError(root, node)); - if (node != root) { - ABSL_INTERNAL_CHECK(node->length != 0, ReportError(root, node)); - } - + } + if (stack.empty()) break; + rep = stack.back(); + stack.pop_back(); + indent = indents.back(); + indents.pop_back(); + } + } + ABSL_INTERNAL_CHECK(indents.empty(), ""); +} + +static TString ReportError(CordRep* root, CordRep* node) { + std::ostringstream buf; + buf << "Error at node " << node << " in:"; + DumpNode(root, true, &buf); + return TString(buf.str()); +} + +static bool VerifyNode(CordRep* root, CordRep* start_node, + bool full_validation) { + y_absl::InlinedVector<CordRep*, 2> worklist; + worklist.push_back(start_node); + do { + CordRep* node = worklist.back(); + worklist.pop_back(); + + ABSL_INTERNAL_CHECK(node != nullptr, ReportError(root, node)); + if (node != root) { + ABSL_INTERNAL_CHECK(node->length != 0, ReportError(root, node)); + } + if (node->IsConcat()) { - ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, - ReportError(root, node)); - ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, - ReportError(root, node)); - ABSL_INTERNAL_CHECK((node->length == node->concat()->left->length + - node->concat()->right->length), - ReportError(root, node)); - if (full_validation) { - worklist.push_back(node->concat()->right); - worklist.push_back(node->concat()->left); - } + ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, + ReportError(root, node)); + ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, + ReportError(root, node)); + ABSL_INTERNAL_CHECK((node->length == node->concat()->left->length + + node->concat()->right->length), + ReportError(root, node)); + if (full_validation) { + worklist.push_back(node->concat()->right); + worklist.push_back(node->concat()->left); + } } else if (node->IsFlat()) { ABSL_INTERNAL_CHECK(node->length <= node->flat()->Capacity(), ReportError(root, node)); } else if (node->IsExternal()) { - ABSL_INTERNAL_CHECK(node->external()->base != nullptr, - ReportError(root, node)); + ABSL_INTERNAL_CHECK(node->external()->base != nullptr, + ReportError(root, node)); } else if (node->IsSubstring()) { - ABSL_INTERNAL_CHECK( - node->substring()->start < node->substring()->child->length, - ReportError(root, node)); - ABSL_INTERNAL_CHECK(node->substring()->start + node->length <= - node->substring()->child->length, - ReportError(root, node)); - } - } while (!worklist.empty()); - return true; -} - -// Traverses the tree and computes the total memory allocated. -/* static */ size_t Cord::MemoryUsageAux(const CordRep* rep) { - size_t total_mem_usage = 0; - - // Allow a quick exit for the common case that the root is a leaf. - if (RepMemoryUsageLeaf(rep, &total_mem_usage)) { - return total_mem_usage; - } - - // Iterate over the tree. cur_node is never a leaf node and leaf nodes will - // never be appended to tree_stack. This reduces overhead from manipulating - // tree_stack. - y_absl::InlinedVector<const CordRep*, kInlinedVectorSize> tree_stack; - const CordRep* cur_node = rep; - while (true) { - const CordRep* next_node = nullptr; - + ABSL_INTERNAL_CHECK( + node->substring()->start < node->substring()->child->length, + ReportError(root, node)); + ABSL_INTERNAL_CHECK(node->substring()->start + node->length <= + node->substring()->child->length, + ReportError(root, node)); + } + } while (!worklist.empty()); + return true; +} + +// Traverses the tree and computes the total memory allocated. +/* static */ size_t Cord::MemoryUsageAux(const CordRep* rep) { + size_t total_mem_usage = 0; + + // Allow a quick exit for the common case that the root is a leaf. + if (RepMemoryUsageLeaf(rep, &total_mem_usage)) { + return total_mem_usage; + } + + // Iterate over the tree. cur_node is never a leaf node and leaf nodes will + // never be appended to tree_stack. This reduces overhead from manipulating + // tree_stack. + y_absl::InlinedVector<const CordRep*, kInlinedVectorSize> tree_stack; + const CordRep* cur_node = rep; + while (true) { + const CordRep* next_node = nullptr; + if (cur_node->IsConcat()) { - total_mem_usage += sizeof(CordRepConcat); - const CordRep* left = cur_node->concat()->left; - if (!RepMemoryUsageLeaf(left, &total_mem_usage)) { - next_node = left; - } - - const CordRep* right = cur_node->concat()->right; - if (!RepMemoryUsageLeaf(right, &total_mem_usage)) { - if (next_node) { - tree_stack.push_back(next_node); - } - next_node = right; - } + total_mem_usage += sizeof(CordRepConcat); + const CordRep* left = cur_node->concat()->left; + if (!RepMemoryUsageLeaf(left, &total_mem_usage)) { + next_node = left; + } + + const CordRep* right = cur_node->concat()->right; + if (!RepMemoryUsageLeaf(right, &total_mem_usage)) { + if (next_node) { + tree_stack.push_back(next_node); + } + next_node = right; + } } else if (cur_node->IsBtree()) { total_mem_usage += sizeof(CordRepBtree); const CordRepBtree* node = cur_node->btree(); @@ -1997,51 +1997,51 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, tree_stack.push_back(edge); } } - } else { - // Since cur_node is not a leaf or a concat node it must be a substring. + } else { + // Since cur_node is not a leaf or a concat node it must be a substring. assert(cur_node->IsSubstring()); - total_mem_usage += sizeof(CordRepSubstring); - next_node = cur_node->substring()->child; - if (RepMemoryUsageLeaf(next_node, &total_mem_usage)) { - next_node = nullptr; - } - } - - if (!next_node) { - if (tree_stack.empty()) { - return total_mem_usage; - } - next_node = tree_stack.back(); - tree_stack.pop_back(); - } - cur_node = next_node; - } -} - -std::ostream& operator<<(std::ostream& out, const Cord& cord) { - for (y_absl::string_view chunk : cord.Chunks()) { - out.write(chunk.data(), chunk.size()); - } - return out; -} - -namespace strings_internal { + total_mem_usage += sizeof(CordRepSubstring); + next_node = cur_node->substring()->child; + if (RepMemoryUsageLeaf(next_node, &total_mem_usage)) { + next_node = nullptr; + } + } + + if (!next_node) { + if (tree_stack.empty()) { + return total_mem_usage; + } + next_node = tree_stack.back(); + tree_stack.pop_back(); + } + cur_node = next_node; + } +} + +std::ostream& operator<<(std::ostream& out, const Cord& cord) { + for (y_absl::string_view chunk : cord.Chunks()) { + out.write(chunk.data(), chunk.size()); + } + return out; +} + +namespace strings_internal { size_t CordTestAccess::FlatOverhead() { return cord_internal::kFlatOverhead; } size_t CordTestAccess::MaxFlatLength() { return cord_internal::kMaxFlatLength; } -size_t CordTestAccess::FlatTagToLength(uint8_t tag) { +size_t CordTestAccess::FlatTagToLength(uint8_t tag) { return cord_internal::TagToLength(tag); -} -uint8_t CordTestAccess::LengthToTag(size_t s) { - ABSL_INTERNAL_CHECK(s <= kMaxFlatLength, y_absl::StrCat("Invalid length ", s)); +} +uint8_t CordTestAccess::LengthToTag(size_t s) { + ABSL_INTERNAL_CHECK(s <= kMaxFlatLength, y_absl::StrCat("Invalid length ", s)); return cord_internal::AllocatedSizeToTag(s + cord_internal::kFlatOverhead); -} -size_t CordTestAccess::SizeofCordRepConcat() { return sizeof(CordRepConcat); } -size_t CordTestAccess::SizeofCordRepExternal() { - return sizeof(CordRepExternal); -} -size_t CordTestAccess::SizeofCordRepSubstring() { - return sizeof(CordRepSubstring); -} -} // namespace strings_internal -ABSL_NAMESPACE_END -} // namespace y_absl +} +size_t CordTestAccess::SizeofCordRepConcat() { return sizeof(CordRepConcat); } +size_t CordTestAccess::SizeofCordRepExternal() { + return sizeof(CordRepExternal); +} +size_t CordTestAccess::SizeofCordRepSubstring() { + return sizeof(CordRepSubstring); +} +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.h index 62359e0cf8..1722ff1e67 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.h @@ -1,17 +1,17 @@ -// Copyright 2020 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 -// -// https://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. -// +// Copyright 2020 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 +// +// https://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. +// // ----------------------------------------------------------------------------- // File: cord.h // ----------------------------------------------------------------------------- @@ -52,33 +52,33 @@ // // Thread Safety // -// Cord has the same thread-safety properties as many other types like -// TString, std::vector<>, int, etc -- it is thread-compatible. In +// Cord has the same thread-safety properties as many other types like +// TString, std::vector<>, int, etc -- it is thread-compatible. In // particular, if threads do not call non-const methods, then it is safe to call // const methods without synchronization. Copying a Cord produces a new instance // that can be used concurrently with the original in arbitrary ways. - -#ifndef ABSL_STRINGS_CORD_H_ -#define ABSL_STRINGS_CORD_H_ - -#include <algorithm> -#include <cstddef> -#include <cstdint> -#include <cstring> + +#ifndef ABSL_STRINGS_CORD_H_ +#define ABSL_STRINGS_CORD_H_ + +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <cstring> #include <iosfwd> -#include <iterator> -#include <util/generic/string.h> +#include <iterator> +#include <util/generic/string.h> #include <type_traits> - + #include "y_absl/base/config.h" -#include "y_absl/base/internal/endian.h" -#include "y_absl/base/internal/per_thread_tls.h" -#include "y_absl/base/macros.h" -#include "y_absl/base/port.h" -#include "y_absl/container/inlined_vector.h" -#include "y_absl/functional/function_ref.h" -#include "y_absl/meta/type_traits.h" -#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/base/internal/endian.h" +#include "y_absl/base/internal/per_thread_tls.h" +#include "y_absl/base/macros.h" +#include "y_absl/base/port.h" +#include "y_absl/container/inlined_vector.h" +#include "y_absl/functional/function_ref.h" +#include "y_absl/meta/type_traits.h" +#include "y_absl/strings/internal/cord_internal.h" #include "y_absl/strings/internal/cord_rep_btree.h" #include "y_absl/strings/internal/cord_rep_btree_reader.h" #include "y_absl/strings/internal/cord_rep_ring.h" @@ -87,19 +87,19 @@ #include "y_absl/strings/internal/cordz_statistics.h" #include "y_absl/strings/internal/cordz_update_scope.h" #include "y_absl/strings/internal/cordz_update_tracker.h" -#include "y_absl/strings/internal/resize_uninitialized.h" +#include "y_absl/strings/internal/resize_uninitialized.h" #include "y_absl/strings/internal/string_constant.h" -#include "y_absl/strings/string_view.h" +#include "y_absl/strings/string_view.h" #include "y_absl/types/optional.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -class Cord; -class CordTestPeer; -template <typename Releaser> -Cord MakeCordFromExternal(y_absl::string_view, Releaser&&); -void CopyCordToString(const Cord& src, TString* dst); - + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +class Cord; +class CordTestPeer; +template <typename Releaser> +Cord MakeCordFromExternal(y_absl::string_view, Releaser&&); +void CopyCordToString(const Cord& src, TString* dst); + // Cord // // A Cord is a sequence of characters, designed to be more efficient than a @@ -128,54 +128,54 @@ void CopyCordToString(const Cord& src, TString* dst); // Additionally, the API provides iterator utilities to iterate through Cord // data via chunks or character bytes. // -class Cord { - private: - template <typename T> - using EnableIfString = - y_absl::enable_if_t<std::is_same<T, TString>::value, int>; - - public: +class Cord { + private: + template <typename T> + using EnableIfString = + y_absl::enable_if_t<std::is_same<T, TString>::value, int>; + + public: // Cord::Cord() Constructors. - + // Creates an empty Cord. - constexpr Cord() noexcept; - + constexpr Cord() noexcept; + // Creates a Cord from an existing Cord. Cord is copyable and efficiently // movable. The moved-from state is valid but unspecified. - Cord(const Cord& src); - Cord(Cord&& src) noexcept; - Cord& operator=(const Cord& x); - Cord& operator=(Cord&& x) noexcept; - + Cord(const Cord& src); + Cord(Cord&& src) noexcept; + Cord& operator=(const Cord& x); + Cord& operator=(Cord&& x) noexcept; + // Creates a Cord from a `src` string. This constructor is marked explicit to // prevent implicit Cord constructions from arguments convertible to an // `y_absl::string_view`. - explicit Cord(y_absl::string_view src); - Cord& operator=(y_absl::string_view src); - + explicit Cord(y_absl::string_view src); + Cord& operator=(y_absl::string_view src); + // Creates a Cord from a `TString&&` rvalue. These constructors are // templated to avoid ambiguities for types that are convertible to both // `y_absl::string_view` and `TString`, such as `const char*`. - template <typename T, EnableIfString<T> = 0> + template <typename T, EnableIfString<T> = 0> explicit Cord(T&& src); - template <typename T, EnableIfString<T> = 0> - Cord& operator=(T&& src); - + template <typename T, EnableIfString<T> = 0> + Cord& operator=(T&& src); + // Cord::~Cord() // // Destructs the Cord. - ~Cord() { - if (contents_.is_tree()) DestroyCordSlow(); - } - + ~Cord() { + if (contents_.is_tree()) DestroyCordSlow(); + } + // MakeCordFromExternal() - // + // // Creates a Cord that takes ownership of external string memory. The // contents of `data` are not copied to the Cord; instead, the external // memory is added to the Cord and reference-counted. This data may not be // changed for the life of the Cord, though it may be prepended or appended // to. - // + // // `MakeCordFromExternal()` takes a callable "releaser" that is invoked when // the reference count for `data` reaches zero. As noted above, this data must // remain live until the releaser is invoked. The callable releaser also must: @@ -183,146 +183,146 @@ class Cord { // * be move constructible // * support `void operator()(y_absl::string_view) const` or `void operator()` // - // Example: - // - // Cord MakeCord(BlockPool* pool) { - // Block* block = pool->NewBlock(); - // FillBlock(block); - // return y_absl::MakeCordFromExternal( - // block->ToStringView(), + // Example: + // + // Cord MakeCord(BlockPool* pool) { + // Block* block = pool->NewBlock(); + // FillBlock(block); + // return y_absl::MakeCordFromExternal( + // block->ToStringView(), // [pool, block](y_absl::string_view v) { // pool->FreeBlock(block, v); - // }); - // } - // + // }); + // } + // // WARNING: Because a Cord can be reference-counted, it's likely a bug if your // releaser doesn't do anything. For example, consider the following: - // - // void Foo(const char* buffer, int len) { - // auto c = y_absl::MakeCordFromExternal(y_absl::string_view(buffer, len), - // [](y_absl::string_view) {}); - // - // // BUG: If Bar() copies its cord for any reason, including keeping a - // // substring of it, the lifetime of buffer might be extended beyond - // // when Foo() returns. - // Bar(c); - // } - template <typename Releaser> - friend Cord MakeCordFromExternal(y_absl::string_view data, Releaser&& releaser); - + // + // void Foo(const char* buffer, int len) { + // auto c = y_absl::MakeCordFromExternal(y_absl::string_view(buffer, len), + // [](y_absl::string_view) {}); + // + // // BUG: If Bar() copies its cord for any reason, including keeping a + // // substring of it, the lifetime of buffer might be extended beyond + // // when Foo() returns. + // Bar(c); + // } + template <typename Releaser> + friend Cord MakeCordFromExternal(y_absl::string_view data, Releaser&& releaser); + // Cord::Clear() // // Releases the Cord data. Any nodes that share data with other Cords, if // applicable, will have their reference counts reduced by 1. - void Clear(); - + void Clear(); + // Cord::Append() // // Appends data to the Cord, which may come from another Cord or other string // data. - void Append(const Cord& src); - void Append(Cord&& src); - void Append(y_absl::string_view src); - template <typename T, EnableIfString<T> = 0> - void Append(T&& src); - + void Append(const Cord& src); + void Append(Cord&& src); + void Append(y_absl::string_view src); + template <typename T, EnableIfString<T> = 0> + void Append(T&& src); + // Cord::Prepend() // // Prepends data to the Cord, which may come from another Cord or other string // data. - void Prepend(const Cord& src); - void Prepend(y_absl::string_view src); - template <typename T, EnableIfString<T> = 0> - void Prepend(T&& src); - + void Prepend(const Cord& src); + void Prepend(y_absl::string_view src); + template <typename T, EnableIfString<T> = 0> + void Prepend(T&& src); + // Cord::RemovePrefix() // // Removes the first `n` bytes of a Cord. - void RemovePrefix(size_t n); - void RemoveSuffix(size_t n); - + void RemovePrefix(size_t n); + void RemoveSuffix(size_t n); + // Cord::Subcord() // // Returns a new Cord representing the subrange [pos, pos + new_size) of - // *this. If pos >= size(), the result is empty(). If - // (pos + new_size) >= size(), the result is the subrange [pos, size()). - Cord Subcord(size_t pos, size_t new_size) const; - + // *this. If pos >= size(), the result is empty(). If + // (pos + new_size) >= size(), the result is the subrange [pos, size()). + Cord Subcord(size_t pos, size_t new_size) const; + // Cord::swap() // // Swaps the contents of the Cord with `other`. void swap(Cord& other) noexcept; - + // swap() // // Swaps the contents of two Cords. friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); } - + // Cord::size() // // Returns the size of the Cord. - size_t size() const; + size_t size() const; // Cord::empty() // // Determines whether the given Cord is empty, returning `true` is so. - bool empty() const; - + bool empty() const; + // Cord::EstimatedMemoryUsage() // // Returns the *approximate* number of bytes held in full or in part by this // Cord (which may not remain the same between invocations). Note that Cords // that share memory could each be "charged" independently for the same shared // memory. - size_t EstimatedMemoryUsage() const; - + size_t EstimatedMemoryUsage() const; + // Cord::Compare() // // Compares 'this' Cord with rhs. This function and its relatives treat Cords // as sequences of unsigned bytes. The comparison is a straightforward // lexicographic comparison. `Cord::Compare()` returns values as follows: // - // -1 'this' Cord is smaller - // 0 two Cords are equal - // 1 'this' Cord is larger - int Compare(y_absl::string_view rhs) const; - int Compare(const Cord& rhs) const; - + // -1 'this' Cord is smaller + // 0 two Cords are equal + // 1 'this' Cord is larger + int Compare(y_absl::string_view rhs) const; + int Compare(const Cord& rhs) const; + // Cord::StartsWith() // // Determines whether the Cord starts with the passed string data `rhs`. - bool StartsWith(const Cord& rhs) const; - bool StartsWith(y_absl::string_view rhs) const; + bool StartsWith(const Cord& rhs) const; + bool StartsWith(y_absl::string_view rhs) const; // Cord::EndsWith() // // Determines whether the Cord ends with the passed string data `rhs`. - bool EndsWith(y_absl::string_view rhs) const; - bool EndsWith(const Cord& rhs) const; - + bool EndsWith(y_absl::string_view rhs) const; + bool EndsWith(const Cord& rhs) const; + // Cord::operator TString() // // Converts a Cord into a `TString()`. This operator is marked explicit to // prevent unintended Cord usage in functions that take a string. - explicit operator TString() const; - + explicit operator TString() const; + // CopyCordToString() - // + // // Copies the contents of a `src` Cord into a `*dst` string. // // This function optimizes the case of reusing the destination string since it - // can reuse previously allocated capacity. However, this function does not - // guarantee that pointers previously returned by `dst->data()` remain valid - // even if `*dst` had enough capacity to hold `src`. If `*dst` is a new - // object, prefer to simply use the conversion operator to `TString`. - friend void CopyCordToString(const Cord& src, TString* dst); - - class CharIterator; - + // can reuse previously allocated capacity. However, this function does not + // guarantee that pointers previously returned by `dst->data()` remain valid + // even if `*dst` had enough capacity to hold `src`. If `*dst` is a new + // object, prefer to simply use the conversion operator to `TString`. + friend void CopyCordToString(const Cord& src, TString* dst); + + class CharIterator; + //---------------------------------------------------------------------------- // Cord::ChunkIterator //---------------------------------------------------------------------------- - // + // // A `Cord::ChunkIterator` allows iteration over the constituent chunks of its // Cord. Such iteration allows you to perform non-const operatons on the data // of a Cord without modifying it. @@ -335,8 +335,8 @@ class Cord { // // * The iterator is invalidated after any non-const operation on the // Cord object over which it iterates. - // * The `string_view` returned by dereferencing a valid, non-`end()` - // iterator is guaranteed to be non-empty. + // * The `string_view` returned by dereferencing a valid, non-`end()` + // iterator is guaranteed to be non-empty. // * Two `ChunkIterator` objects can be compared equal if and only if they // remain valid and iterate over the same Cord. // * The iterator in this case is a proxy iterator; the `string_view` @@ -345,29 +345,29 @@ class Cord { // prevent lifetime issues, `ChunkIterator::reference` is not a true // reference type and is equivalent to `value_type`. // * The iterator keeps state that can grow for Cords that contain many - // nodes and are imbalanced due to sharing. Prefer to pass this type by - // const reference instead of by value. - class ChunkIterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = y_absl::string_view; - using difference_type = ptrdiff_t; - using pointer = const value_type*; - using reference = value_type; - - ChunkIterator() = default; - - ChunkIterator& operator++(); - ChunkIterator operator++(int); - bool operator==(const ChunkIterator& other) const; - bool operator!=(const ChunkIterator& other) const; - reference operator*() const; - pointer operator->() const; - - friend class Cord; - friend class CharIterator; - - private: + // nodes and are imbalanced due to sharing. Prefer to pass this type by + // const reference instead of by value. + class ChunkIterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = y_absl::string_view; + using difference_type = ptrdiff_t; + using pointer = const value_type*; + using reference = value_type; + + ChunkIterator() = default; + + ChunkIterator& operator++(); + ChunkIterator operator++(int); + bool operator==(const ChunkIterator& other) const; + bool operator!=(const ChunkIterator& other) const; + reference operator*() const; + pointer operator->() const; + + friend class Cord; + friend class CharIterator; + + private: using CordRep = y_absl::cord_internal::CordRep; using CordRepBtree = y_absl::cord_internal::CordRepBtree; using CordRepBtreeReader = y_absl::cord_internal::CordRepBtreeReader; @@ -381,17 +381,17 @@ class Cord { // Constructs a `begin()` iterator from `tree`. `tree` must not be null. explicit ChunkIterator(cord_internal::CordRep* tree); - // Constructs a `begin()` iterator from `cord`. - explicit ChunkIterator(const Cord* cord); - + // Constructs a `begin()` iterator from `cord`. + explicit ChunkIterator(const Cord* cord); + // Initializes this instance from a tree. Invoked by constructors. void InitTree(cord_internal::CordRep* tree); - // Removes `n` bytes from `current_chunk_`. Expects `n` to be smaller than - // `current_chunk_.size()`. - void RemoveChunkPrefix(size_t n); - Cord AdvanceAndReadBytes(size_t n); - void AdvanceBytes(size_t n); + // Removes `n` bytes from `current_chunk_`. Expects `n` to be smaller than + // `current_chunk_.size()`. + void RemoveChunkPrefix(size_t n); + Cord AdvanceAndReadBytes(size_t n); + void AdvanceBytes(size_t n); // Stack specific operator++ ChunkIterator& AdvanceStack(); @@ -400,56 +400,56 @@ class Cord { ChunkIterator& AdvanceBtree(); void AdvanceBytesBtree(size_t n); - // Iterates `n` bytes, where `n` is expected to be greater than or equal to - // `current_chunk_.size()`. - void AdvanceBytesSlowPath(size_t n); - - // A view into bytes of the current `CordRep`. It may only be a view to a - // suffix of bytes if this is being used by `CharIterator`. - y_absl::string_view current_chunk_; - // The current leaf, or `nullptr` if the iterator points to short data. - // If the current chunk is a substring node, current_leaf_ points to the - // underlying flat or external node. - y_absl::cord_internal::CordRep* current_leaf_ = nullptr; - // The number of bytes left in the `Cord` over which we are iterating. - size_t bytes_remaining_ = 0; + // Iterates `n` bytes, where `n` is expected to be greater than or equal to + // `current_chunk_.size()`. + void AdvanceBytesSlowPath(size_t n); + + // A view into bytes of the current `CordRep`. It may only be a view to a + // suffix of bytes if this is being used by `CharIterator`. + y_absl::string_view current_chunk_; + // The current leaf, or `nullptr` if the iterator points to short data. + // If the current chunk is a substring node, current_leaf_ points to the + // underlying flat or external node. + y_absl::cord_internal::CordRep* current_leaf_ = nullptr; + // The number of bytes left in the `Cord` over which we are iterating. + size_t bytes_remaining_ = 0; // Cord reader for cord btrees. Empty if not traversing a btree. CordRepBtreeReader btree_reader_; // See 'Stack' alias definition. Stack stack_of_right_children_; - }; - + }; + // Cord::ChunkIterator::chunk_begin() // - // Returns an iterator to the first chunk of the `Cord`. - // + // Returns an iterator to the first chunk of the `Cord`. + // // Generally, prefer using `Cord::Chunks()` within a range-based for loop for // iterating over the chunks of a Cord. This method may be useful for getting // a `ChunkIterator` where range-based for-loops are not useful. - // - // Example: - // - // y_absl::Cord::ChunkIterator FindAsChunk(const y_absl::Cord& c, - // y_absl::string_view s) { - // return std::find(c.chunk_begin(), c.chunk_end(), s); - // } - ChunkIterator chunk_begin() const; + // + // Example: + // + // y_absl::Cord::ChunkIterator FindAsChunk(const y_absl::Cord& c, + // y_absl::string_view s) { + // return std::find(c.chunk_begin(), c.chunk_end(), s); + // } + ChunkIterator chunk_begin() const; // Cord::ChunkItertator::chunk_end() // - // Returns an iterator one increment past the last chunk of the `Cord`. + // Returns an iterator one increment past the last chunk of the `Cord`. // // Generally, prefer using `Cord::Chunks()` within a range-based for loop for // iterating over the chunks of a Cord. This method may be useful for getting // a `ChunkIterator` where range-based for-loops may not be available. - ChunkIterator chunk_end() const; - + ChunkIterator chunk_end() const; + //---------------------------------------------------------------------------- // Cord::ChunkIterator::ChunkRange //---------------------------------------------------------------------------- - // + // // `ChunkRange` is a helper class for iterating over the chunks of the `Cord`, // producing an iterator which can be used within a range-based for loop. // Construction of a `ChunkRange` will return an iterator pointing to the @@ -458,8 +458,8 @@ class Cord { // // Implementation note: `ChunkRange` is simply a convenience wrapper over // `Cord::chunk_begin()` and `Cord::chunk_end()`. - class ChunkRange { - public: + class ChunkRange { + public: // Fulfill minimum c++ container requirements [container.requirements] // Theses (partial) container type definitions allow ChunkRange to be used // in various utilities expecting a subset of [container.requirements]. @@ -470,40 +470,40 @@ class Cord { using iterator = ChunkIterator; using const_iterator = ChunkIterator; - explicit ChunkRange(const Cord* cord) : cord_(cord) {} - - ChunkIterator begin() const; - ChunkIterator end() const; - - private: - const Cord* cord_; - }; - + explicit ChunkRange(const Cord* cord) : cord_(cord) {} + + ChunkIterator begin() const; + ChunkIterator end() const; + + private: + const Cord* cord_; + }; + // Cord::Chunks() - // + // // Returns a `Cord::ChunkIterator::ChunkRange` for iterating over the chunks // of a `Cord` with a range-based for-loop. For most iteration tasks on a // Cord, use `Cord::Chunks()` to retrieve this iterator. // - // Example: - // - // void ProcessChunks(const Cord& cord) { - // for (y_absl::string_view chunk : cord.Chunks()) { ... } - // } - // - // Note that the ordinary caveats of temporary lifetime extension apply: - // - // void Process() { - // for (y_absl::string_view chunk : CordFactory().Chunks()) { - // // The temporary Cord returned by CordFactory has been destroyed! - // } - // } - ChunkRange Chunks() const; - + // Example: + // + // void ProcessChunks(const Cord& cord) { + // for (y_absl::string_view chunk : cord.Chunks()) { ... } + // } + // + // Note that the ordinary caveats of temporary lifetime extension apply: + // + // void Process() { + // for (y_absl::string_view chunk : CordFactory().Chunks()) { + // // The temporary Cord returned by CordFactory has been destroyed! + // } + // } + ChunkRange Chunks() const; + //---------------------------------------------------------------------------- // Cord::CharIterator //---------------------------------------------------------------------------- - // + // // A `Cord::CharIterator` allows iteration over the constituent characters of // a `Cord`. // @@ -518,79 +518,79 @@ class Cord { // * Two `CharIterator` objects can be compared equal if and only if they // remain valid and iterate over the same Cord. // * The iterator keeps state that can grow for Cords that contain many - // nodes and are imbalanced due to sharing. Prefer to pass this type by - // const reference instead of by value. + // nodes and are imbalanced due to sharing. Prefer to pass this type by + // const reference instead of by value. // * This type cannot act as a forward iterator because a `Cord` can reuse // sections of memory. This fact violates the requirement for forward // iterators to compare equal if dereferencing them returns the same // object. - class CharIterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = char; - using difference_type = ptrdiff_t; - using pointer = const char*; - using reference = const char&; - - CharIterator() = default; - - CharIterator& operator++(); - CharIterator operator++(int); - bool operator==(const CharIterator& other) const; - bool operator!=(const CharIterator& other) const; - reference operator*() const; - pointer operator->() const; - - friend Cord; - - private: - explicit CharIterator(const Cord* cord) : chunk_iterator_(cord) {} - - ChunkIterator chunk_iterator_; - }; - + class CharIterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = char; + using difference_type = ptrdiff_t; + using pointer = const char*; + using reference = const char&; + + CharIterator() = default; + + CharIterator& operator++(); + CharIterator operator++(int); + bool operator==(const CharIterator& other) const; + bool operator!=(const CharIterator& other) const; + reference operator*() const; + pointer operator->() const; + + friend Cord; + + private: + explicit CharIterator(const Cord* cord) : chunk_iterator_(cord) {} + + ChunkIterator chunk_iterator_; + }; + // Cord::CharIterator::AdvanceAndRead() - // + // // Advances the `Cord::CharIterator` by `n_bytes` and returns the bytes // advanced as a separate `Cord`. `n_bytes` must be less than or equal to the // number of bytes within the Cord; otherwise, behavior is undefined. It is // valid to pass `char_end()` and `0`. - static Cord AdvanceAndRead(CharIterator* it, size_t n_bytes); - + static Cord AdvanceAndRead(CharIterator* it, size_t n_bytes); + // Cord::CharIterator::Advance() - // + // // Advances the `Cord::CharIterator` by `n_bytes`. `n_bytes` must be less than // or equal to the number of bytes remaining within the Cord; otherwise, // behavior is undefined. It is valid to pass `char_end()` and `0`. - static void Advance(CharIterator* it, size_t n_bytes); - + static void Advance(CharIterator* it, size_t n_bytes); + // Cord::CharIterator::ChunkRemaining() // - // Returns the longest contiguous view starting at the iterator's position. - // - // `it` must be dereferenceable. - static y_absl::string_view ChunkRemaining(const CharIterator& it); - + // Returns the longest contiguous view starting at the iterator's position. + // + // `it` must be dereferenceable. + static y_absl::string_view ChunkRemaining(const CharIterator& it); + // Cord::CharIterator::char_begin() // - // Returns an iterator to the first character of the `Cord`. + // Returns an iterator to the first character of the `Cord`. // // Generally, prefer using `Cord::Chars()` within a range-based for loop for // iterating over the chunks of a Cord. This method may be useful for getting // a `CharIterator` where range-based for-loops may not be available. - CharIterator char_begin() const; + CharIterator char_begin() const; // Cord::CharIterator::char_end() // - // Returns an iterator to one past the last character of the `Cord`. + // Returns an iterator to one past the last character of the `Cord`. // // Generally, prefer using `Cord::Chars()` within a range-based for loop for // iterating over the chunks of a Cord. This method may be useful for getting // a `CharIterator` where range-based for-loops are not useful. - CharIterator char_end() const; - + CharIterator char_end() const; + // Cord::CharIterator::CharRange - // + // // `CharRange` is a helper class for iterating over the characters of a // producing an iterator which can be used within a range-based for loop. // Construction of a `CharRange` will return an iterator pointing to the first @@ -599,8 +599,8 @@ class Cord { // // Implementation note: `CharRange` is simply a convenience wrapper over // `Cord::char_begin()` and `Cord::char_end()`. - class CharRange { - public: + class CharRange { + public: // Fulfill minimum c++ container requirements [container.requirements] // Theses (partial) container type definitions allow CharRange to be used // in various utilities expecting a subset of [container.requirements]. @@ -611,36 +611,36 @@ class Cord { using iterator = CharIterator; using const_iterator = CharIterator; - explicit CharRange(const Cord* cord) : cord_(cord) {} - - CharIterator begin() const; - CharIterator end() const; - - private: - const Cord* cord_; - }; - + explicit CharRange(const Cord* cord) : cord_(cord) {} + + CharIterator begin() const; + CharIterator end() const; + + private: + const Cord* cord_; + }; + // Cord::CharIterator::Chars() - // + // // Returns a `Cord::CharIterator` for iterating over the characters of a // `Cord` with a range-based for-loop. For most character-based iteration // tasks on a Cord, use `Cord::Chars()` to retrieve this iterator. // - // Example: - // - // void ProcessCord(const Cord& cord) { - // for (char c : cord.Chars()) { ... } - // } - // - // Note that the ordinary caveats of temporary lifetime extension apply: - // - // void Process() { - // for (char c : CordFactory().Chars()) { - // // The temporary Cord returned by CordFactory has been destroyed! - // } - // } - CharRange Chars() const; - + // Example: + // + // void ProcessCord(const Cord& cord) { + // for (char c : cord.Chars()) { ... } + // } + // + // Note that the ordinary caveats of temporary lifetime extension apply: + // + // void Process() { + // for (char c : CordFactory().Chars()) { + // // The temporary Cord returned by CordFactory has been destroyed! + // } + // } + CharRange Chars() const; + // Cord::operator[] // // Gets the "i"th character of the Cord and returns it, provided that @@ -648,11 +648,11 @@ class Cord { // // NOTE: This routine is reasonably efficient. It is roughly // logarithmic based on the number of chunks that make up the cord. Still, - // if you need to iterate over the contents of a cord, you should + // if you need to iterate over the contents of a cord, you should // use a CharIterator/ChunkIterator rather than call operator[] or Get() // repeatedly in a loop. - char operator[](size_t i) const; - + char operator[](size_t i) const; + // Cord::TryFlat() // // If this cord's representation is a single flat array, returns a @@ -661,11 +661,11 @@ class Cord { // Cord::Flatten() // - // Flattens the cord into a single array and returns a view of the data. - // - // If the cord was already flat, the contents are not modified. - y_absl::string_view Flatten(); - + // Flattens the cord into a single array and returns a view of the data. + // + // If the cord was already flat, the contents are not modified. + y_absl::string_view Flatten(); + // Supports y_absl::Cord as a sink object for y_absl::Format(). friend void AbslFormatFlush(y_absl::Cord* cord, y_absl::string_view part) { cord->Append(part); @@ -688,7 +688,7 @@ class Cord { template <typename T> explicit constexpr Cord(strings_internal::StringConstant<T>); - private: + private: using CordRep = y_absl::cord_internal::CordRep; using CordRepFlat = y_absl::cord_internal::CordRepFlat; using CordzInfo = cord_internal::CordzInfo; @@ -701,56 +701,56 @@ class Cord { // public API call causing the cord to be created. explicit Cord(y_absl::string_view src, MethodIdentifier method); - friend class CordTestPeer; - friend bool operator==(const Cord& lhs, const Cord& rhs); - friend bool operator==(const Cord& lhs, y_absl::string_view rhs); - + friend class CordTestPeer; + friend bool operator==(const Cord& lhs, const Cord& rhs); + friend bool operator==(const Cord& lhs, y_absl::string_view rhs); + friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord); // Calls the provided function once for each cord chunk, in order. Unlike - // Chunks(), this API will not allocate memory. - void ForEachChunk(y_absl::FunctionRef<void(y_absl::string_view)>) const; - - // Allocates new contiguous storage for the contents of the cord. This is - // called by Flatten() when the cord was not already flat. - y_absl::string_view FlattenSlowPath(); - - // Actual cord contents are hidden inside the following simple - // class so that we can isolate the bulk of cord.cc from changes - // to the representation. - // + // Chunks(), this API will not allocate memory. + void ForEachChunk(y_absl::FunctionRef<void(y_absl::string_view)>) const; + + // Allocates new contiguous storage for the contents of the cord. This is + // called by Flatten() when the cord was not already flat. + y_absl::string_view FlattenSlowPath(); + + // Actual cord contents are hidden inside the following simple + // class so that we can isolate the bulk of cord.cc from changes + // to the representation. + // // InlineRep holds either a tree pointer, or an array of kMaxInline bytes. - class InlineRep { - public: + class InlineRep { + public: static constexpr unsigned char kMaxInline = cord_internal::kMaxInline; - static_assert(kMaxInline >= sizeof(y_absl::cord_internal::CordRep*), ""); - + static_assert(kMaxInline >= sizeof(y_absl::cord_internal::CordRep*), ""); + constexpr InlineRep() : data_() {} explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {} - InlineRep(const InlineRep& src); - InlineRep(InlineRep&& src); - InlineRep& operator=(const InlineRep& src); - InlineRep& operator=(InlineRep&& src) noexcept; - + InlineRep(const InlineRep& src); + InlineRep(InlineRep&& src); + InlineRep& operator=(const InlineRep& src); + InlineRep& operator=(InlineRep&& src) noexcept; + explicit constexpr InlineRep(cord_internal::InlineData data); - void Swap(InlineRep* rhs); - bool empty() const; - size_t size() const; - const char* data() const; // Returns nullptr if holding pointer - void set_data(const char* data, size_t n, - bool nullify_tail); // Discards pointer, if any + void Swap(InlineRep* rhs); + bool empty() const; + size_t size() const; + const char* data() const; // Returns nullptr if holding pointer + void set_data(const char* data, size_t n, + bool nullify_tail); // Discards pointer, if any char* set_data(size_t n); // Write data to the result - // Returns nullptr if holding bytes - y_absl::cord_internal::CordRep* tree() const; + // Returns nullptr if holding bytes + y_absl::cord_internal::CordRep* tree() const; y_absl::cord_internal::CordRep* as_tree() const; - // Returns non-null iff was holding a pointer - y_absl::cord_internal::CordRep* clear(); + // Returns non-null iff was holding a pointer + y_absl::cord_internal::CordRep* clear(); // Converts to pointer if necessary. void reduce_size(size_t n); // REQUIRES: holding data - void remove_prefix(size_t n); // REQUIRES: holding data + void remove_prefix(size_t n); // REQUIRES: holding data void AppendArray(y_absl::string_view src, MethodIdentifier method); - y_absl::string_view FindFlatStartPiece() const; + y_absl::string_view FindFlatStartPiece() const; // Creates a CordRepFlat instance from the current inlined data with `extra' // bytes of desired additional capacity. @@ -794,40 +794,40 @@ class Cord { template <bool has_length> void GetAppendRegion(char** region, size_t* size, size_t length); - bool IsSame(const InlineRep& other) const { + bool IsSame(const InlineRep& other) const { return memcmp(&data_, &other.data_, sizeof(data_)) == 0; - } - int BitwiseCompare(const InlineRep& other) const { - uint64_t x, y; + } + int BitwiseCompare(const InlineRep& other) const { + uint64_t x, y; // Use memcpy to avoid aliasing issues. memcpy(&x, &data_, sizeof(x)); memcpy(&y, &other.data_, sizeof(y)); - if (x == y) { + if (x == y) { memcpy(&x, reinterpret_cast<const char*>(&data_) + 8, sizeof(x)); memcpy(&y, reinterpret_cast<const char*>(&other.data_) + 8, sizeof(y)); - if (x == y) return 0; - } - return y_absl::big_endian::FromHost64(x) < y_absl::big_endian::FromHost64(y) - ? -1 - : 1; - } - void CopyTo(TString* dst) const { - // memcpy is much faster when operating on a known size. On most supported + if (x == y) return 0; + } + return y_absl::big_endian::FromHost64(x) < y_absl::big_endian::FromHost64(y) + ? -1 + : 1; + } + void CopyTo(TString* dst) const { + // memcpy is much faster when operating on a known size. On most supported // platforms, the small string optimization is large enough that resizing - // to 15 bytes does not cause a memory allocation. - y_absl::strings_internal::STLStringResizeUninitialized(dst, - sizeof(data_) - 1); + // to 15 bytes does not cause a memory allocation. + y_absl::strings_internal::STLStringResizeUninitialized(dst, + sizeof(data_) - 1); memcpy(&(*dst)[0], &data_, sizeof(data_) - 1); - // erase is faster than resize because the logic for memory allocation is - // not needed. + // erase is faster than resize because the logic for memory allocation is + // not needed. dst->erase(inline_size()); - } - - // Copies the inline contents into `dst`. Assumes the cord is not empty. - void CopyToArray(char* dst) const; - + } + + // Copies the inline contents into `dst`. Assumes the cord is not empty. + void CopyToArray(char* dst) const; + bool is_tree() const { return data_.is_tree(); } - + // Returns true if the Cord is being profiled by cordz. bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); } @@ -845,61 +845,61 @@ class Cord { // Resets the current cordz_info to null / empty. void clear_cordz_info() { data_.clear_cordz_info(); } - private: - friend class Cord; - - void AssignSlow(const InlineRep& src); + private: + friend class Cord; + + void AssignSlow(const InlineRep& src); // Unrefs the tree and stops profiling. void UnrefTree(); - + void ResetToEmpty() { data_ = {}; } void set_inline_size(size_t size) { data_.set_inline_size(size); } size_t inline_size() const { return data_.inline_size(); } cord_internal::InlineData data_; - }; - InlineRep contents_; - + }; + InlineRep contents_; + // Helper for MemoryUsage(). - static size_t MemoryUsageAux(const y_absl::cord_internal::CordRep* rep); - + static size_t MemoryUsageAux(const y_absl::cord_internal::CordRep* rep); + // Helper for GetFlat() and TryFlat(). - static bool GetFlatAux(y_absl::cord_internal::CordRep* rep, - y_absl::string_view* fragment); - + static bool GetFlatAux(y_absl::cord_internal::CordRep* rep, + y_absl::string_view* fragment); + // Helper for ForEachChunk(). - static void ForEachChunkAux( - y_absl::cord_internal::CordRep* rep, - y_absl::FunctionRef<void(y_absl::string_view)> callback); - - // The destructor for non-empty Cords. - void DestroyCordSlow(); - - // Out-of-line implementation of slower parts of logic. - void CopyToArraySlowPath(char* dst) const; - int CompareSlowPath(y_absl::string_view rhs, size_t compared_size, - size_t size_to_compare) const; - int CompareSlowPath(const Cord& rhs, size_t compared_size, - size_t size_to_compare) const; - bool EqualsImpl(y_absl::string_view rhs, size_t size_to_compare) const; - bool EqualsImpl(const Cord& rhs, size_t size_to_compare) const; - int CompareImpl(const Cord& rhs) const; - - template <typename ResultType, typename RHS> - friend ResultType GenericCompare(const Cord& lhs, const RHS& rhs, - size_t size_to_compare); - static y_absl::string_view GetFirstChunk(const Cord& c); - static y_absl::string_view GetFirstChunk(y_absl::string_view sv); - - // Returns a new reference to contents_.tree(), or steals an existing - // reference if called on an rvalue. - y_absl::cord_internal::CordRep* TakeRep() const&; - y_absl::cord_internal::CordRep* TakeRep() &&; - + static void ForEachChunkAux( + y_absl::cord_internal::CordRep* rep, + y_absl::FunctionRef<void(y_absl::string_view)> callback); + + // The destructor for non-empty Cords. + void DestroyCordSlow(); + + // Out-of-line implementation of slower parts of logic. + void CopyToArraySlowPath(char* dst) const; + int CompareSlowPath(y_absl::string_view rhs, size_t compared_size, + size_t size_to_compare) const; + int CompareSlowPath(const Cord& rhs, size_t compared_size, + size_t size_to_compare) const; + bool EqualsImpl(y_absl::string_view rhs, size_t size_to_compare) const; + bool EqualsImpl(const Cord& rhs, size_t size_to_compare) const; + int CompareImpl(const Cord& rhs) const; + + template <typename ResultType, typename RHS> + friend ResultType GenericCompare(const Cord& lhs, const RHS& rhs, + size_t size_to_compare); + static y_absl::string_view GetFirstChunk(const Cord& c); + static y_absl::string_view GetFirstChunk(y_absl::string_view sv); + + // Returns a new reference to contents_.tree(), or steals an existing + // reference if called on an rvalue. + y_absl::cord_internal::CordRep* TakeRep() const&; + y_absl::cord_internal::CordRep* TakeRep() &&; + // Helper for Append(). - template <typename C> - void AppendImpl(C&& src); + template <typename C> + void AppendImpl(C&& src); // Prepends the provided data to this instance. `method` contains the public // API method for this action which is tracked for Cordz sampling purposes. @@ -919,106 +919,106 @@ class Cord { }); return H::combine(combiner.finalize(std::move(hash_state)), size()); } -}; - -ABSL_NAMESPACE_END -} // namespace y_absl - -namespace y_absl { -ABSL_NAMESPACE_BEGIN - -// allow a Cord to be logged -extern std::ostream& operator<<(std::ostream& out, const Cord& cord); - -// ------------------------------------------------------------------ -// Internal details follow. Clients should ignore. - -namespace cord_internal { - -// Fast implementation of memmove for up to 15 bytes. This implementation is -// safe for overlapping regions. If nullify_tail is true, the destination is -// padded with '\0' up to 16 bytes. -inline void SmallMemmove(char* dst, const char* src, size_t n, - bool nullify_tail = false) { - if (n >= 8) { - assert(n <= 16); - uint64_t buf1; - uint64_t buf2; - memcpy(&buf1, src, 8); - memcpy(&buf2, src + n - 8, 8); - if (nullify_tail) { - memset(dst + 8, 0, 8); - } - memcpy(dst, &buf1, 8); - memcpy(dst + n - 8, &buf2, 8); - } else if (n >= 4) { - uint32_t buf1; - uint32_t buf2; - memcpy(&buf1, src, 4); - memcpy(&buf2, src + n - 4, 4); - if (nullify_tail) { - memset(dst + 4, 0, 4); - memset(dst + 8, 0, 8); - } - memcpy(dst, &buf1, 4); - memcpy(dst + n - 4, &buf2, 4); - } else { - if (n != 0) { - dst[0] = src[0]; - dst[n / 2] = src[n / 2]; - dst[n - 1] = src[n - 1]; - } - if (nullify_tail) { - memset(dst + 8, 0, 8); - memset(dst + n, 0, 8); - } - } -} - +}; + +ABSL_NAMESPACE_END +} // namespace y_absl + +namespace y_absl { +ABSL_NAMESPACE_BEGIN + +// allow a Cord to be logged +extern std::ostream& operator<<(std::ostream& out, const Cord& cord); + +// ------------------------------------------------------------------ +// Internal details follow. Clients should ignore. + +namespace cord_internal { + +// Fast implementation of memmove for up to 15 bytes. This implementation is +// safe for overlapping regions. If nullify_tail is true, the destination is +// padded with '\0' up to 16 bytes. +inline void SmallMemmove(char* dst, const char* src, size_t n, + bool nullify_tail = false) { + if (n >= 8) { + assert(n <= 16); + uint64_t buf1; + uint64_t buf2; + memcpy(&buf1, src, 8); + memcpy(&buf2, src + n - 8, 8); + if (nullify_tail) { + memset(dst + 8, 0, 8); + } + memcpy(dst, &buf1, 8); + memcpy(dst + n - 8, &buf2, 8); + } else if (n >= 4) { + uint32_t buf1; + uint32_t buf2; + memcpy(&buf1, src, 4); + memcpy(&buf2, src + n - 4, 4); + if (nullify_tail) { + memset(dst + 4, 0, 4); + memset(dst + 8, 0, 8); + } + memcpy(dst, &buf1, 4); + memcpy(dst + n - 4, &buf2, 4); + } else { + if (n != 0) { + dst[0] = src[0]; + dst[n / 2] = src[n / 2]; + dst[n - 1] = src[n - 1]; + } + if (nullify_tail) { + memset(dst + 8, 0, 8); + memset(dst + n, 0, 8); + } + } +} + // Does non-template-specific `CordRepExternal` initialization. -// Expects `data` to be non-empty. +// Expects `data` to be non-empty. void InitializeCordRepExternal(y_absl::string_view data, CordRepExternal* rep); - -// Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer -// to it, or `nullptr` if `data` was empty. -template <typename Releaser> -// NOLINTNEXTLINE - suppress clang-tidy raw pointer return. -CordRep* NewExternalRep(y_absl::string_view data, Releaser&& releaser) { - using ReleaserType = y_absl::decay_t<Releaser>; - if (data.empty()) { - // Never create empty external nodes. + +// Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer +// to it, or `nullptr` if `data` was empty. +template <typename Releaser> +// NOLINTNEXTLINE - suppress clang-tidy raw pointer return. +CordRep* NewExternalRep(y_absl::string_view data, Releaser&& releaser) { + using ReleaserType = y_absl::decay_t<Releaser>; + if (data.empty()) { + // Never create empty external nodes. InvokeReleaser(Rank0{}, ReleaserType(std::forward<Releaser>(releaser)), data); - return nullptr; - } - + return nullptr; + } + CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>( std::forward<Releaser>(releaser), 0); InitializeCordRepExternal(data, rep); return rep; -} - -// Overload for function reference types that dispatches using a function -// pointer because there are no `alignof()` or `sizeof()` a function reference. -// NOLINTNEXTLINE - suppress clang-tidy raw pointer return. -inline CordRep* NewExternalRep(y_absl::string_view data, - void (&releaser)(y_absl::string_view)) { - return NewExternalRep(data, &releaser); -} - -} // namespace cord_internal - -template <typename Releaser> -Cord MakeCordFromExternal(y_absl::string_view data, Releaser&& releaser) { - Cord cord; +} + +// Overload for function reference types that dispatches using a function +// pointer because there are no `alignof()` or `sizeof()` a function reference. +// NOLINTNEXTLINE - suppress clang-tidy raw pointer return. +inline CordRep* NewExternalRep(y_absl::string_view data, + void (&releaser)(y_absl::string_view)) { + return NewExternalRep(data, &releaser); +} + +} // namespace cord_internal + +template <typename Releaser> +Cord MakeCordFromExternal(y_absl::string_view data, Releaser&& releaser) { + Cord cord; if (auto* rep = ::y_absl::cord_internal::NewExternalRep( data, std::forward<Releaser>(releaser))) { cord.contents_.EmplaceTree(rep, Cord::MethodIdentifier::kMakeCordFromExternal); } - return cord; -} - + return cord; +} + constexpr Cord::InlineRep::InlineRep(cord_internal::InlineData data) : data_(data) {} @@ -1030,64 +1030,64 @@ inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) } else { data_ = src.data_; } -} - +} + inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) { src.ResetToEmpty(); -} - -inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) { - if (this == &src) { - return *this; - } - if (!is_tree() && !src.is_tree()) { +} + +inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) { + if (this == &src) { + return *this; + } + if (!is_tree() && !src.is_tree()) { data_ = src.data_; - return *this; - } - AssignSlow(src); - return *this; -} - -inline Cord::InlineRep& Cord::InlineRep::operator=( - Cord::InlineRep&& src) noexcept { - if (is_tree()) { + return *this; + } + AssignSlow(src); + return *this; +} + +inline Cord::InlineRep& Cord::InlineRep::operator=( + Cord::InlineRep&& src) noexcept { + if (is_tree()) { UnrefTree(); - } + } data_ = src.data_; src.ResetToEmpty(); - return *this; -} - -inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) { - if (rhs == this) { - return; - } + return *this; +} + +inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) { + if (rhs == this) { + return; + } std::swap(data_, rhs->data_); -} - -inline const char* Cord::InlineRep::data() const { +} + +inline const char* Cord::InlineRep::data() const { return is_tree() ? nullptr : data_.as_chars(); -} - +} + inline y_absl::cord_internal::CordRep* Cord::InlineRep::as_tree() const { assert(data_.is_tree()); return data_.as_tree(); } -inline y_absl::cord_internal::CordRep* Cord::InlineRep::tree() const { - if (is_tree()) { +inline y_absl::cord_internal::CordRep* Cord::InlineRep::tree() const { + if (is_tree()) { return as_tree(); - } else { - return nullptr; - } -} - + } else { + return nullptr; + } +} + inline bool Cord::InlineRep::empty() const { return data_.is_empty(); } - -inline size_t Cord::InlineRep::size() const { + +inline size_t Cord::InlineRep::size() const { return is_tree() ? as_tree()->length : inline_size(); -} - +} + inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity( size_t extra) { static_assert(cord_internal::kMinFlatLength >= sizeof(data_), ""); @@ -1124,12 +1124,12 @@ inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep, assert(data_.is_tree()); if (rep) { data_.set_tree(rep); - } else { + } else { data_ = {}; - } + } scope.SetCordRep(rep); -} - +} + inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep, const CordzUpdateScope& scope, MethodIdentifier method) { @@ -1137,27 +1137,27 @@ inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep, SetTree(rep, scope); } else { EmplaceTree(rep, method); - } -} - -inline y_absl::cord_internal::CordRep* Cord::InlineRep::clear() { + } +} + +inline y_absl::cord_internal::CordRep* Cord::InlineRep::clear() { if (is_tree()) { CordzInfo::MaybeUntrackCord(cordz_info()); } y_absl::cord_internal::CordRep* result = tree(); ResetToEmpty(); - return result; -} - -inline void Cord::InlineRep::CopyToArray(char* dst) const { - assert(!is_tree()); + return result; +} + +inline void Cord::InlineRep::CopyToArray(char* dst) const { + assert(!is_tree()); size_t n = inline_size(); - assert(n != 0); + assert(n != 0); cord_internal::SmallMemmove(dst, data_.as_chars(), n); -} - -constexpr inline Cord::Cord() noexcept {} - +} + +constexpr inline Cord::Cord() noexcept {} + inline Cord::Cord(y_absl::string_view src) : Cord(src, CordzUpdateTracker::kConstructorString) {} @@ -1171,11 +1171,11 @@ constexpr Cord::Cord(strings_internal::StringConstant<T>) &cord_internal::ConstInitExternalStorage< strings_internal::StringConstant<T>>::value)) {} -inline Cord& Cord::operator=(const Cord& x) { - contents_ = x.contents_; - return *this; -} - +inline Cord& Cord::operator=(const Cord& x) { + contents_ = x.contents_; + return *this; +} + template <typename T, Cord::EnableIfString<T>> Cord& Cord::operator=(T&& src) { if (src.size() <= cord_internal::kMaxBytesToCopy) { @@ -1187,34 +1187,34 @@ Cord& Cord::operator=(T&& src) { inline Cord::Cord(const Cord& src) : contents_(src.contents_) {} -inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {} - +inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {} + inline void Cord::swap(Cord& other) noexcept { contents_.Swap(&other.contents_); } -inline Cord& Cord::operator=(Cord&& x) noexcept { - contents_ = std::move(x.contents_); - return *this; -} - +inline Cord& Cord::operator=(Cord&& x) noexcept { + contents_ = std::move(x.contents_); + return *this; +} + extern template Cord::Cord(TString&& src); - -inline size_t Cord::size() const { - // Length is 1st field in str.rep_ - return contents_.size(); -} - -inline bool Cord::empty() const { return contents_.empty(); } - -inline size_t Cord::EstimatedMemoryUsage() const { - size_t result = sizeof(Cord); - if (const y_absl::cord_internal::CordRep* rep = contents_.tree()) { - result += MemoryUsageAux(rep); - } - return result; -} - + +inline size_t Cord::size() const { + // Length is 1st field in str.rep_ + return contents_.size(); +} + +inline bool Cord::empty() const { return contents_.empty(); } + +inline size_t Cord::EstimatedMemoryUsage() const { + size_t result = sizeof(Cord); + if (const y_absl::cord_internal::CordRep* rep = contents_.tree()) { + result += MemoryUsageAux(rep); + } + return result; +} + inline y_absl::optional<y_absl::string_view> Cord::TryFlat() const { y_absl::cord_internal::CordRep* rep = contents_.tree(); if (rep == nullptr) { @@ -1227,52 +1227,52 @@ inline y_absl::optional<y_absl::string_view> Cord::TryFlat() const { return y_absl::nullopt; } -inline y_absl::string_view Cord::Flatten() { - y_absl::cord_internal::CordRep* rep = contents_.tree(); - if (rep == nullptr) { - return y_absl::string_view(contents_.data(), contents_.size()); - } else { - y_absl::string_view already_flat_contents; - if (GetFlatAux(rep, &already_flat_contents)) { - return already_flat_contents; - } - } - return FlattenSlowPath(); -} - -inline void Cord::Append(y_absl::string_view src) { +inline y_absl::string_view Cord::Flatten() { + y_absl::cord_internal::CordRep* rep = contents_.tree(); + if (rep == nullptr) { + return y_absl::string_view(contents_.data(), contents_.size()); + } else { + y_absl::string_view already_flat_contents; + if (GetFlatAux(rep, &already_flat_contents)) { + return already_flat_contents; + } + } + return FlattenSlowPath(); +} + +inline void Cord::Append(y_absl::string_view src) { contents_.AppendArray(src, CordzUpdateTracker::kAppendString); -} - +} + inline void Cord::Prepend(y_absl::string_view src) { PrependArray(src, CordzUpdateTracker::kPrependString); } extern template void Cord::Append(TString&& src); extern template void Cord::Prepend(TString&& src); - -inline int Cord::Compare(const Cord& rhs) const { - if (!contents_.is_tree() && !rhs.contents_.is_tree()) { - return contents_.BitwiseCompare(rhs.contents_); - } - - return CompareImpl(rhs); -} - -// Does 'this' cord start/end with rhs -inline bool Cord::StartsWith(const Cord& rhs) const { - if (contents_.IsSame(rhs.contents_)) return true; - size_t rhs_size = rhs.size(); - if (size() < rhs_size) return false; - return EqualsImpl(rhs, rhs_size); -} - -inline bool Cord::StartsWith(y_absl::string_view rhs) const { - size_t rhs_size = rhs.size(); - if (size() < rhs_size) return false; - return EqualsImpl(rhs, rhs_size); -} - + +inline int Cord::Compare(const Cord& rhs) const { + if (!contents_.is_tree() && !rhs.contents_.is_tree()) { + return contents_.BitwiseCompare(rhs.contents_); + } + + return CompareImpl(rhs); +} + +// Does 'this' cord start/end with rhs +inline bool Cord::StartsWith(const Cord& rhs) const { + if (contents_.IsSame(rhs.contents_)) return true; + size_t rhs_size = rhs.size(); + if (size() < rhs_size) return false; + return EqualsImpl(rhs, rhs_size); +} + +inline bool Cord::StartsWith(y_absl::string_view rhs) const { + size_t rhs_size = rhs.size(); + if (size() < rhs_size) return false; + return EqualsImpl(rhs, rhs_size); +} + inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) { if (tree->tag == cord_internal::BTREE) { current_chunk_ = btree_reader_.Init(tree->btree()); @@ -1288,16 +1288,16 @@ inline Cord::ChunkIterator::ChunkIterator(cord_internal::CordRep* tree) InitTree(tree); } -inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) - : bytes_remaining_(cord->size()) { - if (cord->contents_.is_tree()) { +inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) + : bytes_remaining_(cord->size()) { + if (cord->contents_.is_tree()) { InitTree(cord->contents_.as_tree()); - } else { + } else { current_chunk_ = y_absl::string_view(cord->contents_.data(), bytes_remaining_); - } -} - + } +} + inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() { current_chunk_ = btree_reader_.Next(); return *this; @@ -1331,191 +1331,191 @@ inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() { return *this; } -inline Cord::ChunkIterator Cord::ChunkIterator::operator++(int) { - ChunkIterator tmp(*this); - operator++(); - return tmp; -} - -inline bool Cord::ChunkIterator::operator==(const ChunkIterator& other) const { - return bytes_remaining_ == other.bytes_remaining_; -} - -inline bool Cord::ChunkIterator::operator!=(const ChunkIterator& other) const { - return !(*this == other); -} - -inline Cord::ChunkIterator::reference Cord::ChunkIterator::operator*() const { +inline Cord::ChunkIterator Cord::ChunkIterator::operator++(int) { + ChunkIterator tmp(*this); + operator++(); + return tmp; +} + +inline bool Cord::ChunkIterator::operator==(const ChunkIterator& other) const { + return bytes_remaining_ == other.bytes_remaining_; +} + +inline bool Cord::ChunkIterator::operator!=(const ChunkIterator& other) const { + return !(*this == other); +} + +inline Cord::ChunkIterator::reference Cord::ChunkIterator::operator*() const { ABSL_HARDENING_ASSERT(bytes_remaining_ != 0); - return current_chunk_; -} - -inline Cord::ChunkIterator::pointer Cord::ChunkIterator::operator->() const { + return current_chunk_; +} + +inline Cord::ChunkIterator::pointer Cord::ChunkIterator::operator->() const { ABSL_HARDENING_ASSERT(bytes_remaining_ != 0); - return ¤t_chunk_; -} - -inline void Cord::ChunkIterator::RemoveChunkPrefix(size_t n) { - assert(n < current_chunk_.size()); - current_chunk_.remove_prefix(n); - bytes_remaining_ -= n; -} - -inline void Cord::ChunkIterator::AdvanceBytes(size_t n) { + return ¤t_chunk_; +} + +inline void Cord::ChunkIterator::RemoveChunkPrefix(size_t n) { + assert(n < current_chunk_.size()); + current_chunk_.remove_prefix(n); + bytes_remaining_ -= n; +} + +inline void Cord::ChunkIterator::AdvanceBytes(size_t n) { assert(bytes_remaining_ >= n); - if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) { - RemoveChunkPrefix(n); - } else if (n != 0) { + if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) { + RemoveChunkPrefix(n); + } else if (n != 0) { btree_reader_ ? AdvanceBytesBtree(n) : AdvanceBytesSlowPath(n); - } -} - -inline Cord::ChunkIterator Cord::chunk_begin() const { - return ChunkIterator(this); -} - -inline Cord::ChunkIterator Cord::chunk_end() const { return ChunkIterator(); } - -inline Cord::ChunkIterator Cord::ChunkRange::begin() const { - return cord_->chunk_begin(); -} - -inline Cord::ChunkIterator Cord::ChunkRange::end() const { - return cord_->chunk_end(); -} - -inline Cord::ChunkRange Cord::Chunks() const { return ChunkRange(this); } - -inline Cord::CharIterator& Cord::CharIterator::operator++() { - if (ABSL_PREDICT_TRUE(chunk_iterator_->size() > 1)) { - chunk_iterator_.RemoveChunkPrefix(1); - } else { - ++chunk_iterator_; - } - return *this; -} - -inline Cord::CharIterator Cord::CharIterator::operator++(int) { - CharIterator tmp(*this); - operator++(); - return tmp; -} - -inline bool Cord::CharIterator::operator==(const CharIterator& other) const { - return chunk_iterator_ == other.chunk_iterator_; -} - -inline bool Cord::CharIterator::operator!=(const CharIterator& other) const { - return !(*this == other); -} - -inline Cord::CharIterator::reference Cord::CharIterator::operator*() const { - return *chunk_iterator_->data(); -} - -inline Cord::CharIterator::pointer Cord::CharIterator::operator->() const { - return chunk_iterator_->data(); -} - -inline Cord Cord::AdvanceAndRead(CharIterator* it, size_t n_bytes) { - assert(it != nullptr); - return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes); -} - -inline void Cord::Advance(CharIterator* it, size_t n_bytes) { - assert(it != nullptr); - it->chunk_iterator_.AdvanceBytes(n_bytes); -} - -inline y_absl::string_view Cord::ChunkRemaining(const CharIterator& it) { - return *it.chunk_iterator_; -} - -inline Cord::CharIterator Cord::char_begin() const { - return CharIterator(this); -} - -inline Cord::CharIterator Cord::char_end() const { return CharIterator(); } - -inline Cord::CharIterator Cord::CharRange::begin() const { - return cord_->char_begin(); -} - -inline Cord::CharIterator Cord::CharRange::end() const { - return cord_->char_end(); -} - -inline Cord::CharRange Cord::Chars() const { return CharRange(this); } - -inline void Cord::ForEachChunk( - y_absl::FunctionRef<void(y_absl::string_view)> callback) const { - y_absl::cord_internal::CordRep* rep = contents_.tree(); - if (rep == nullptr) { - callback(y_absl::string_view(contents_.data(), contents_.size())); - } else { - return ForEachChunkAux(rep, callback); - } -} - -// Nonmember Cord-to-Cord relational operarators. -inline bool operator==(const Cord& lhs, const Cord& rhs) { - if (lhs.contents_.IsSame(rhs.contents_)) return true; - size_t rhs_size = rhs.size(); - if (lhs.size() != rhs_size) return false; - return lhs.EqualsImpl(rhs, rhs_size); -} - -inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); } + } +} + +inline Cord::ChunkIterator Cord::chunk_begin() const { + return ChunkIterator(this); +} + +inline Cord::ChunkIterator Cord::chunk_end() const { return ChunkIterator(); } + +inline Cord::ChunkIterator Cord::ChunkRange::begin() const { + return cord_->chunk_begin(); +} + +inline Cord::ChunkIterator Cord::ChunkRange::end() const { + return cord_->chunk_end(); +} + +inline Cord::ChunkRange Cord::Chunks() const { return ChunkRange(this); } + +inline Cord::CharIterator& Cord::CharIterator::operator++() { + if (ABSL_PREDICT_TRUE(chunk_iterator_->size() > 1)) { + chunk_iterator_.RemoveChunkPrefix(1); + } else { + ++chunk_iterator_; + } + return *this; +} + +inline Cord::CharIterator Cord::CharIterator::operator++(int) { + CharIterator tmp(*this); + operator++(); + return tmp; +} + +inline bool Cord::CharIterator::operator==(const CharIterator& other) const { + return chunk_iterator_ == other.chunk_iterator_; +} + +inline bool Cord::CharIterator::operator!=(const CharIterator& other) const { + return !(*this == other); +} + +inline Cord::CharIterator::reference Cord::CharIterator::operator*() const { + return *chunk_iterator_->data(); +} + +inline Cord::CharIterator::pointer Cord::CharIterator::operator->() const { + return chunk_iterator_->data(); +} + +inline Cord Cord::AdvanceAndRead(CharIterator* it, size_t n_bytes) { + assert(it != nullptr); + return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes); +} + +inline void Cord::Advance(CharIterator* it, size_t n_bytes) { + assert(it != nullptr); + it->chunk_iterator_.AdvanceBytes(n_bytes); +} + +inline y_absl::string_view Cord::ChunkRemaining(const CharIterator& it) { + return *it.chunk_iterator_; +} + +inline Cord::CharIterator Cord::char_begin() const { + return CharIterator(this); +} + +inline Cord::CharIterator Cord::char_end() const { return CharIterator(); } + +inline Cord::CharIterator Cord::CharRange::begin() const { + return cord_->char_begin(); +} + +inline Cord::CharIterator Cord::CharRange::end() const { + return cord_->char_end(); +} + +inline Cord::CharRange Cord::Chars() const { return CharRange(this); } + +inline void Cord::ForEachChunk( + y_absl::FunctionRef<void(y_absl::string_view)> callback) const { + y_absl::cord_internal::CordRep* rep = contents_.tree(); + if (rep == nullptr) { + callback(y_absl::string_view(contents_.data(), contents_.size())); + } else { + return ForEachChunkAux(rep, callback); + } +} + +// Nonmember Cord-to-Cord relational operarators. +inline bool operator==(const Cord& lhs, const Cord& rhs) { + if (lhs.contents_.IsSame(rhs.contents_)) return true; + size_t rhs_size = rhs.size(); + if (lhs.size() != rhs_size) return false; + return lhs.EqualsImpl(rhs, rhs_size); +} + +inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); } inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; } inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; } -inline bool operator<=(const Cord& x, const Cord& y) { - return x.Compare(y) <= 0; -} -inline bool operator>=(const Cord& x, const Cord& y) { - return x.Compare(y) >= 0; -} - -// Nonmember Cord-to-y_absl::string_view relational operators. -// -// Due to implicit conversions, these also enable comparisons of Cord with -// with TString, ::string, and const char*. -inline bool operator==(const Cord& lhs, y_absl::string_view rhs) { - size_t lhs_size = lhs.size(); - size_t rhs_size = rhs.size(); - if (lhs_size != rhs_size) return false; - return lhs.EqualsImpl(rhs, rhs_size); -} - -inline bool operator==(y_absl::string_view x, const Cord& y) { return y == x; } -inline bool operator!=(const Cord& x, y_absl::string_view y) { return !(x == y); } -inline bool operator!=(y_absl::string_view x, const Cord& y) { return !(x == y); } -inline bool operator<(const Cord& x, y_absl::string_view y) { - return x.Compare(y) < 0; -} -inline bool operator<(y_absl::string_view x, const Cord& y) { - return y.Compare(x) > 0; -} -inline bool operator>(const Cord& x, y_absl::string_view y) { return y < x; } -inline bool operator>(y_absl::string_view x, const Cord& y) { return y < x; } -inline bool operator<=(const Cord& x, y_absl::string_view y) { return !(y < x); } -inline bool operator<=(y_absl::string_view x, const Cord& y) { return !(y < x); } -inline bool operator>=(const Cord& x, y_absl::string_view y) { return !(x < y); } -inline bool operator>=(y_absl::string_view x, const Cord& y) { return !(x < y); } - -// Some internals exposed to test code. -namespace strings_internal { -class CordTestAccess { - public: - static size_t FlatOverhead(); - static size_t MaxFlatLength(); - static size_t SizeofCordRepConcat(); - static size_t SizeofCordRepExternal(); - static size_t SizeofCordRepSubstring(); - static size_t FlatTagToLength(uint8_t tag); - static uint8_t LengthToTag(size_t s); -}; -} // namespace strings_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_CORD_H_ +inline bool operator<=(const Cord& x, const Cord& y) { + return x.Compare(y) <= 0; +} +inline bool operator>=(const Cord& x, const Cord& y) { + return x.Compare(y) >= 0; +} + +// Nonmember Cord-to-y_absl::string_view relational operators. +// +// Due to implicit conversions, these also enable comparisons of Cord with +// with TString, ::string, and const char*. +inline bool operator==(const Cord& lhs, y_absl::string_view rhs) { + size_t lhs_size = lhs.size(); + size_t rhs_size = rhs.size(); + if (lhs_size != rhs_size) return false; + return lhs.EqualsImpl(rhs, rhs_size); +} + +inline bool operator==(y_absl::string_view x, const Cord& y) { return y == x; } +inline bool operator!=(const Cord& x, y_absl::string_view y) { return !(x == y); } +inline bool operator!=(y_absl::string_view x, const Cord& y) { return !(x == y); } +inline bool operator<(const Cord& x, y_absl::string_view y) { + return x.Compare(y) < 0; +} +inline bool operator<(y_absl::string_view x, const Cord& y) { + return y.Compare(x) > 0; +} +inline bool operator>(const Cord& x, y_absl::string_view y) { return y < x; } +inline bool operator>(y_absl::string_view x, const Cord& y) { return y < x; } +inline bool operator<=(const Cord& x, y_absl::string_view y) { return !(y < x); } +inline bool operator<=(y_absl::string_view x, const Cord& y) { return !(y < x); } +inline bool operator>=(const Cord& x, y_absl::string_view y) { return !(x < y); } +inline bool operator>=(y_absl::string_view x, const Cord& y) { return !(x < y); } + +// Some internals exposed to test code. +namespace strings_internal { +class CordTestAccess { + public: + static size_t FlatOverhead(); + static size_t MaxFlatLength(); + static size_t SizeofCordRepConcat(); + static size_t SizeofCordRepExternal(); + static size_t SizeofCordRepSubstring(); + static size_t FlatTagToLength(uint8_t tag); + static uint8_t LengthToTag(size_t s); +}; +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_CORD_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord_test_helpers.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord_test_helpers.h index 8dd7c05751..14b46ab606 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord_test_helpers.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord_test_helpers.h @@ -1,34 +1,34 @@ -// -// Copyright 2018 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 -// -// https://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. -// - -#ifndef ABSL_STRINGS_CORD_TEST_HELPERS_H_ -#define ABSL_STRINGS_CORD_TEST_HELPERS_H_ - +// +// Copyright 2018 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 +// +// https://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. +// + +#ifndef ABSL_STRINGS_CORD_TEST_HELPERS_H_ +#define ABSL_STRINGS_CORD_TEST_HELPERS_H_ + #include <cstdint> #include <iostream> #include <util/generic/string.h> #include "y_absl/base/config.h" -#include "y_absl/strings/cord.h" +#include "y_absl/strings/cord.h" #include "y_absl/strings/internal/cord_internal.h" #include "y_absl/strings/string_view.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN - + +namespace y_absl { +ABSL_NAMESPACE_BEGIN + // Cord sizes relevant for testing enum class TestCordSize { // An empty value @@ -84,39 +84,39 @@ inline std::ostream& operator<<(std::ostream& stream, TestCordSize size) { return stream << ToString(size); } -// Creates a multi-segment Cord from an iterable container of strings. The -// resulting Cord is guaranteed to have one segment for every string in the -// container. This allows code to be unit tested with multi-segment Cord -// inputs. -// -// Example: -// -// y_absl::Cord c = y_absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"}); -// EXPECT_FALSE(c.GetFlat(&unused)); -// -// The mechanism by which this Cord is created is an implementation detail. Any -// implementation that produces a multi-segment Cord may produce a flat Cord in -// the future as new optimizations are added to the Cord class. -// MakeFragmentedCord will, however, always be updated to return a multi-segment -// Cord. -template <typename Container> -Cord MakeFragmentedCord(const Container& c) { - Cord result; - for (const auto& s : c) { - auto* external = new TString(s); - Cord tmp = y_absl::MakeCordFromExternal( - *external, [external](y_absl::string_view) { delete external; }); - tmp.Prepend(result); - result = tmp; - } - return result; -} - -inline Cord MakeFragmentedCord(std::initializer_list<y_absl::string_view> list) { - return MakeFragmentedCord<std::initializer_list<y_absl::string_view>>(list); -} - -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_CORD_TEST_HELPERS_H_ +// Creates a multi-segment Cord from an iterable container of strings. The +// resulting Cord is guaranteed to have one segment for every string in the +// container. This allows code to be unit tested with multi-segment Cord +// inputs. +// +// Example: +// +// y_absl::Cord c = y_absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"}); +// EXPECT_FALSE(c.GetFlat(&unused)); +// +// The mechanism by which this Cord is created is an implementation detail. Any +// implementation that produces a multi-segment Cord may produce a flat Cord in +// the future as new optimizations are added to the Cord class. +// MakeFragmentedCord will, however, always be updated to return a multi-segment +// Cord. +template <typename Container> +Cord MakeFragmentedCord(const Container& c) { + Cord result; + for (const auto& s : c) { + auto* external = new TString(s); + Cord tmp = y_absl::MakeCordFromExternal( + *external, [external](y_absl::string_view) { delete external; }); + tmp.Prepend(result); + result = tmp; + } + return result; +} + +inline Cord MakeFragmentedCord(std::initializer_list<y_absl::string_view> list) { + return MakeFragmentedCord<std::initializer_list<y_absl::string_view>>(list); +} + +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_CORD_TEST_HELPERS_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/escaping.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/escaping.cc index 8c82740608..a66434921c 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/escaping.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/escaping.cc @@ -20,13 +20,13 @@ #include <cstring> #include <iterator> #include <limits> -#include <util/generic/string.h> +#include <util/generic/string.h> #include "y_absl/base/internal/endian.h" #include "y_absl/base/internal/raw_logging.h" #include "y_absl/base/internal/unaligned_access.h" #include "y_absl/strings/internal/char_map.h" -#include "y_absl/strings/internal/escaping.h" +#include "y_absl/strings/internal/escaping.h" #include "y_absl/strings/internal/resize_uninitialized.h" #include "y_absl/strings/internal/utf8.h" #include "y_absl/strings/str_cat.h" @@ -34,7 +34,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { // These are used for the leave_nulls_escaped argument to CUnescapeInternal(). @@ -796,7 +796,7 @@ bool Base64UnescapeInternal(const char* src, size_t slen, String* dest, } /* clang-format off */ -constexpr char kHexValueLenient[256] = { +constexpr char kHexValueLenient[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -812,9 +812,9 @@ constexpr char kHexValueLenient[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; - + /* clang-format on */ // This is a templated function so that T can be either a char* @@ -823,8 +823,8 @@ constexpr char kHexValueLenient[256] = { template <typename T> void HexStringToBytesInternal(const char* from, T to, ptrdiff_t num) { for (int i = 0; i < num; i++) { - to[i] = (kHexValueLenient[from[i * 2] & 0xFF] << 4) + - (kHexValueLenient[from[i * 2 + 1] & 0xFF]); + to[i] = (kHexValueLenient[from[i * 2] & 0xFF] << 4) + + (kHexValueLenient[from[i * 2 + 1] & 0xFF]); } } @@ -902,30 +902,30 @@ bool WebSafeBase64Unescape(y_absl::string_view src, TString* dest) { } void Base64Escape(y_absl::string_view src, TString* dest) { - strings_internal::Base64EscapeInternal( - reinterpret_cast<const unsigned char*>(src.data()), src.size(), dest, - true, strings_internal::kBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast<const unsigned char*>(src.data()), src.size(), dest, + true, strings_internal::kBase64Chars); } void WebSafeBase64Escape(y_absl::string_view src, TString* dest) { - strings_internal::Base64EscapeInternal( - reinterpret_cast<const unsigned char*>(src.data()), src.size(), dest, - false, kWebSafeBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast<const unsigned char*>(src.data()), src.size(), dest, + false, kWebSafeBase64Chars); } TString Base64Escape(y_absl::string_view src) { TString dest; - strings_internal::Base64EscapeInternal( - reinterpret_cast<const unsigned char*>(src.data()), src.size(), &dest, - true, strings_internal::kBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast<const unsigned char*>(src.data()), src.size(), &dest, + true, strings_internal::kBase64Chars); return dest; } TString WebSafeBase64Escape(y_absl::string_view src) { TString dest; - strings_internal::Base64EscapeInternal( - reinterpret_cast<const unsigned char*>(src.data()), src.size(), &dest, - false, kWebSafeBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast<const unsigned char*>(src.data()), src.size(), &dest, + false, kWebSafeBase64Chars); return dest; } @@ -945,5 +945,5 @@ TString BytesToHexString(y_absl::string_view from) { return result; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/escaping.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/escaping.h index 8868b87879..149d497f03 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/escaping.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/escaping.h @@ -24,7 +24,7 @@ #define ABSL_STRINGS_ESCAPING_H_ #include <cstddef> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <vector> #include "y_absl/base/macros.h" @@ -33,7 +33,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // CUnescape() // @@ -158,7 +158,7 @@ TString HexStringToBytes(y_absl::string_view from); // `2*from.size()`. TString BytesToHexString(y_absl::string_view from); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_ESCAPING_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal/ya.make index 4e57fc75f6..6b12ede171 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal/ya.make @@ -11,23 +11,23 @@ OWNER( LICENSE(Apache-2.0) -PEERDIR( +PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity -) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp-tstring -) + contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity +) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp-tstring +) NO_COMPILER_WARNINGS() SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) SRCS( - escaping.cc + escaping.cc ostringstream.cc utf8.cc ) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/char_map.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/char_map.h index 25428e304c..9d19d6b721 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/char_map.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/char_map.h @@ -28,7 +28,7 @@ #include "y_absl/base/port.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { class Charmap { @@ -150,7 +150,7 @@ constexpr Charmap GraphCharmap() { return PrintCharmap() & ~SpaceCharmap(); } constexpr Charmap PunctCharmap() { return GraphCharmap() & ~AlnumCharmap(); } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_CHAR_MAP_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_bigint.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_bigint.cc index 72a4fa188b..c14e28c0c5 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_bigint.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_bigint.cc @@ -16,10 +16,10 @@ #include <algorithm> #include <cassert> -#include <util/generic/string.h> +#include <util/generic/string.h> namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { namespace { @@ -158,12 +158,12 @@ const uint32_t* LargePowerOfFiveData(int i) { int LargePowerOfFiveSize(int i) { return 2 * i; } } // namespace -ABSL_DLL const uint32_t kFiveToNth[14] = { +ABSL_DLL const uint32_t kFiveToNth[14] = { 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125, }; -ABSL_DLL const uint32_t kTenToNth[10] = { +ABSL_DLL const uint32_t kTenToNth[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, }; @@ -355,5 +355,5 @@ template class BigUnsigned<4>; template class BigUnsigned<84>; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_bigint.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_bigint.h index a77aab14dd..11c5581bad 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_bigint.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_bigint.h @@ -18,15 +18,15 @@ #include <algorithm> #include <cstdint> #include <iostream> -#include <util/generic/string.h> +#include <util/generic/string.h> -#include "y_absl/base/config.h" +#include "y_absl/base/config.h" #include "y_absl/strings/ascii.h" #include "y_absl/strings/internal/charconv_parse.h" #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // The largest power that 5 that can be raised to, and still fit in a uint32_t. @@ -34,9 +34,9 @@ constexpr int kMaxSmallPowerOfFive = 13; // The largest power that 10 that can be raised to, and still fit in a uint32_t. constexpr int kMaxSmallPowerOfTen = 9; -ABSL_DLL extern const uint32_t - kFiveToNth[kMaxSmallPowerOfFive + 1]; -ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; +ABSL_DLL extern const uint32_t + kFiveToNth[kMaxSmallPowerOfFive + 1]; +ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; // Large, fixed-width unsigned integer. // @@ -417,7 +417,7 @@ extern template class BigUnsigned<4>; extern template class BigUnsigned<84>; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.cc index f0f78eb68c..050f1cf0af 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.cc @@ -22,7 +22,7 @@ #include "y_absl/strings/internal/memutil.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { // ParseFloat<10> will read the first 19 significant digits of the mantissa. @@ -500,5 +500,5 @@ template ParsedFloat ParseFloat<16>(const char* begin, const char* end, chars_format format_flags); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.h index 3f942cd4cb..83b74723af 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.h @@ -17,11 +17,11 @@ #include <cstdint> -#include "y_absl/base/config.h" +#include "y_absl/base/config.h" #include "y_absl/strings/charconv.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // Enum indicating whether a parsed float is a number or special value. @@ -94,6 +94,6 @@ extern template ParsedFloat ParseFloat<16>(const char* begin, const char* end, y_absl::chars_format format_flags); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.h index 82f5ac7b81..f9986faf33 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.h @@ -1,38 +1,38 @@ // Copyright 2021 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 -// -// https://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. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ -#define ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ - -#include <atomic> -#include <cassert> -#include <cstddef> -#include <cstdint> -#include <type_traits> - +// +// 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 +// +// https://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. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ +#define ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ + +#include <atomic> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <type_traits> + #include "y_absl/base/config.h" #include "y_absl/base/internal/endian.h" #include "y_absl/base/internal/invoke.h" #include "y_absl/base/optimization.h" #include "y_absl/container/internal/compressed_tuple.h" -#include "y_absl/meta/type_traits.h" -#include "y_absl/strings/string_view.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - +#include "y_absl/meta/type_traits.h" +#include "y_absl/strings/string_view.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + class CordzInfo; // Default feature enable states for cord ring buffers @@ -83,48 +83,48 @@ enum Constants { // Compact class for tracking the reference count and state flags for CordRep // instances. Data is stored in an atomic int32_t for compactness and speed. class RefcountAndFlags { - public: + public: constexpr RefcountAndFlags() : count_{kRefIncrement} {} struct Immortal {}; explicit constexpr RefcountAndFlags(Immortal) : count_(kImmortalFlag) {} struct WithCrc {}; explicit constexpr RefcountAndFlags(WithCrc) : count_(kCrcFlag | kRefIncrement) {} - + // Increments the reference count. Imposes no memory ordering. inline void Increment() { count_.fetch_add(kRefIncrement, std::memory_order_relaxed); } - - // Asserts that the current refcount is greater than 0. If the refcount is + + // Asserts that the current refcount is greater than 0. If the refcount is // greater than 1, decrements the reference count. - // - // Returns false if there are no references outstanding; true otherwise. - // Inserts barriers to ensure that state written before this method returns - // false will be visible to a thread that just observed this method returning + // + // Returns false if there are no references outstanding; true otherwise. + // Inserts barriers to ensure that state written before this method returns + // false will be visible to a thread that just observed this method returning // false. Always returns false when the immortal bit is set. - inline bool Decrement() { + inline bool Decrement() { int32_t refcount = count_.load(std::memory_order_acquire) & kRefcountMask; assert(refcount > 0 || refcount & kImmortalFlag); return refcount != kRefIncrement && (count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & kRefcountMask) != kRefIncrement; - } - - // Same as Decrement but expect that refcount is greater than 1. - inline bool DecrementExpectHighRefcount() { + } + + // Same as Decrement but expect that refcount is greater than 1. + inline bool DecrementExpectHighRefcount() { int32_t refcount = count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & kRefcountMask; assert(refcount > 0 || refcount & kImmortalFlag); return refcount != kRefIncrement; - } - - // Returns the current reference count using acquire semantics. + } + + // Returns the current reference count using acquire semantics. inline int32_t Get() const { return count_.load(std::memory_order_acquire) >> kNumFlags; } - + // Returns true if the referenced object carries a CRC value. bool HasCrc() const { return (count_.load(std::memory_order_relaxed) & kCrcFlag) != 0; @@ -155,12 +155,12 @@ class RefcountAndFlags { return (count_.load(std::memory_order_acquire) & kRefcountMask) == kRefIncrement; } - + bool IsImmortal() const { return (count_.load(std::memory_order_relaxed) & kImmortalFlag) != 0; } - private: + private: // We reserve the bottom bits for flags. // kImmortalBit indicates that this entity should never be collected; it is // used for the StringConstant constructor to avoid collecting immutable @@ -180,21 +180,21 @@ class RefcountAndFlags { kRefcountMask = ~kCrcFlag, }; - std::atomic<int32_t> count_; -}; - -// The overhead of a vtable is too much for Cord, so we roll our own subclasses -// using only a single byte to differentiate classes from each other - the "tag" -// byte. Define the subclasses first so we can provide downcasting helper -// functions in the base class. - -struct CordRepConcat; + std::atomic<int32_t> count_; +}; + +// The overhead of a vtable is too much for Cord, so we roll our own subclasses +// using only a single byte to differentiate classes from each other - the "tag" +// byte. Define the subclasses first so we can provide downcasting helper +// functions in the base class. + +struct CordRepConcat; struct CordRepExternal; struct CordRepFlat; -struct CordRepSubstring; +struct CordRepSubstring; class CordRepRing; class CordRepBtree; - + // Various representations that we allow enum CordRepKind { CONCAT = 0, @@ -224,19 +224,19 @@ static_assert(RING == BTREE + 1, "BTREE and RING not consecutive"); static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive"); static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive"); -struct CordRep { +struct CordRep { CordRep() = default; constexpr CordRep(RefcountAndFlags::Immortal immortal, size_t l) : length(l), refcount(immortal), tag(EXTERNAL), storage{} {} - // The following three fields have to be less than 32 bytes since - // that is the smallest supported flat node size. + // The following three fields have to be less than 32 bytes since + // that is the smallest supported flat node size. size_t length; RefcountAndFlags refcount; - // If tag < FLAT, it represents CordRepKind and indicates the type of node. - // Otherwise, the node type is CordRepFlat and the tag is the encoded size. - uint8_t tag; - + // If tag < FLAT, it represents CordRepKind and indicates the type of node. + // Otherwise, the node type is CordRepFlat and the tag is the encoded size. + uint8_t tag; + // `storage` provides two main purposes: // - the starting point for FlatCordRep.Data() [flexible-array-member] // - 3 bytes of additional storage for use by derived classes. @@ -257,12 +257,12 @@ struct CordRep { inline CordRepRing* ring(); inline const CordRepRing* ring() const; - inline CordRepConcat* concat(); - inline const CordRepConcat* concat() const; - inline CordRepSubstring* substring(); - inline const CordRepSubstring* substring() const; - inline CordRepExternal* external(); - inline const CordRepExternal* external() const; + inline CordRepConcat* concat(); + inline const CordRepConcat* concat() const; + inline CordRepSubstring* substring(); + inline const CordRepSubstring* substring() const; + inline CordRepExternal* external(); + inline const CordRepExternal* external() const; inline CordRepFlat* flat(); inline const CordRepFlat* flat() const; inline CordRepBtree* btree(); @@ -281,28 +281,28 @@ struct CordRep { // Decrements the reference count of `rep`. Destroys rep if count reaches // zero. Requires `rep` to be a non-null pointer value. static inline void Unref(CordRep* rep); -}; - -struct CordRepConcat : public CordRep { - CordRep* left; - CordRep* right; - +}; + +struct CordRepConcat : public CordRep { + CordRep* left; + CordRep* right; + uint8_t depth() const { return storage[0]; } void set_depth(uint8_t depth) { storage[0] = depth; } -}; - -struct CordRepSubstring : public CordRep { - size_t start; // Starting offset of substring in child - CordRep* child; -}; - +}; + +struct CordRepSubstring : public CordRep { + size_t start; // Starting offset of substring in child + CordRep* child; +}; + // Type for function pointer that will invoke the releaser function and also // delete the `CordRepExternalImpl` corresponding to the passed in // `CordRepExternal`. using ExternalReleaserInvoker = void (*)(CordRepExternal*); - -// External CordReps are allocated together with a type erased releaser. The -// releaser is stored in the memory directly following the CordRepExternal. + +// External CordReps are allocated together with a type erased releaser. The +// releaser is stored in the memory directly following the CordRepExternal. struct CordRepExternal : public CordRep { CordRepExternal() = default; explicit constexpr CordRepExternal(y_absl::string_view str) @@ -310,18 +310,18 @@ struct CordRepExternal : public CordRep { base(str.data()), releaser_invoker(nullptr) {} - const char* base; - // Pointer to function that knows how to call and destroy the releaser. - ExternalReleaserInvoker releaser_invoker; + const char* base; + // Pointer to function that knows how to call and destroy the releaser. + ExternalReleaserInvoker releaser_invoker; // Deletes (releases) the external rep. // Requires rep != nullptr and rep->IsExternal() static void Delete(CordRep* rep); -}; - +}; + struct Rank1 {}; struct Rank0 : Rank1 {}; - + template <typename Releaser, typename = ::y_absl::base_internal::invoke_result_t< Releaser, y_absl::string_view>> void InvokeReleaser(Rank0, Releaser&& releaser, y_absl::string_view data) { @@ -613,8 +613,8 @@ inline void CordRep::Unref(CordRep* rep) { } } -} // namespace cord_internal +} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl -#endif // ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ +ABSL_NAMESPACE_END +} // namespace y_absl +#endif // ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions/ya.make index 06e99346da..613da918ff 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions/ya.make @@ -17,9 +17,9 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased ) -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp-tstring -) +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp-tstring +) NO_COMPILER_WARNINGS() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping.cc index 01b8974983..36218c2bbd 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping.cc @@ -1,180 +1,180 @@ -// Copyright 2020 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 -// -// https://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. - -#include "y_absl/strings/internal/escaping.h" - -#include "y_absl/base/internal/endian.h" -#include "y_absl/base/internal/raw_logging.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace strings_internal { - -const char kBase64Chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { - // Base64 encodes three bytes of input at a time. If the input is not - // divisible by three, we pad as appropriate. - // - // (from https://tools.ietf.org/html/rfc3548) - // Special processing is performed if fewer than 24 bits are available - // at the end of the data being encoded. A full encoding quantum is - // always completed at the end of a quantity. When fewer than 24 input - // bits are available in an input group, zero bits are added (on the - // right) to form an integral number of 6-bit groups. Padding at the - // end of the data is performed using the '=' character. Since all base - // 64 input is an integral number of octets, only the following cases - // can arise: - - // Base64 encodes each three bytes of input into four bytes of output. - size_t len = (input_len / 3) * 4; - - if (input_len % 3 == 0) { - // (from https://tools.ietf.org/html/rfc3548) - // (1) the final quantum of encoding input is an integral multiple of 24 - // bits; here, the final unit of encoded output will be an integral - // multiple of 4 characters with no "=" padding, - } else if (input_len % 3 == 1) { - // (from https://tools.ietf.org/html/rfc3548) - // (2) the final quantum of encoding input is exactly 8 bits; here, the - // final unit of encoded output will be two characters followed by two - // "=" padding characters, or - len += 2; - if (do_padding) { - len += 2; - } - } else { // (input_len % 3 == 2) - // (from https://tools.ietf.org/html/rfc3548) - // (3) the final quantum of encoding input is exactly 16 bits; here, the - // final unit of encoded output will be three characters followed by one - // "=" padding character. - len += 3; - if (do_padding) { - len += 1; - } - } - - assert(len >= input_len); // make sure we didn't overflow - return len; -} - -size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, - size_t szdest, const char* base64, - bool do_padding) { - static const char kPad64 = '='; - - if (szsrc * 4 > szdest * 3) return 0; - - char* cur_dest = dest; - const unsigned char* cur_src = src; - - char* const limit_dest = dest + szdest; - const unsigned char* const limit_src = src + szsrc; - - // Three bytes of data encodes to four characters of cyphertext. - // So we can pump through three-byte chunks atomically. - if (szsrc >= 3) { // "limit_src - 3" is UB if szsrc < 3. - while (cur_src < limit_src - 3) { // While we have >= 32 bits. - uint32_t in = y_absl::big_endian::Load32(cur_src) >> 8; - - cur_dest[0] = base64[in >> 18]; - in &= 0x3FFFF; - cur_dest[1] = base64[in >> 12]; - in &= 0xFFF; - cur_dest[2] = base64[in >> 6]; - in &= 0x3F; - cur_dest[3] = base64[in]; - - cur_dest += 4; - cur_src += 3; - } - } - // To save time, we didn't update szdest or szsrc in the loop. So do it now. - szdest = limit_dest - cur_dest; - szsrc = limit_src - cur_src; - - /* now deal with the tail (<=3 bytes) */ - switch (szsrc) { - case 0: - // Nothing left; nothing more to do. - break; - case 1: { - // One byte left: this encodes to two characters, and (optionally) - // two pad characters to round out the four-character cypherblock. - if (szdest < 2) return 0; - uint32_t in = cur_src[0]; - cur_dest[0] = base64[in >> 2]; - in &= 0x3; - cur_dest[1] = base64[in << 4]; - cur_dest += 2; - szdest -= 2; - if (do_padding) { - if (szdest < 2) return 0; - cur_dest[0] = kPad64; - cur_dest[1] = kPad64; - cur_dest += 2; - szdest -= 2; - } - break; - } - case 2: { - // Two bytes left: this encodes to three characters, and (optionally) - // one pad character to round out the four-character cypherblock. - if (szdest < 3) return 0; - uint32_t in = y_absl::big_endian::Load16(cur_src); - cur_dest[0] = base64[in >> 10]; - in &= 0x3FF; - cur_dest[1] = base64[in >> 4]; - in &= 0x00F; - cur_dest[2] = base64[in << 2]; - cur_dest += 3; - szdest -= 3; - if (do_padding) { - if (szdest < 1) return 0; - cur_dest[0] = kPad64; - cur_dest += 1; - szdest -= 1; - } - break; - } - case 3: { - // Three bytes left: same as in the big loop above. We can't do this in - // the loop because the loop above always reads 4 bytes, and the fourth - // byte is past the end of the input. - if (szdest < 4) return 0; - uint32_t in = (cur_src[0] << 16) + y_absl::big_endian::Load16(cur_src + 1); - cur_dest[0] = base64[in >> 18]; - in &= 0x3FFFF; - cur_dest[1] = base64[in >> 12]; - in &= 0xFFF; - cur_dest[2] = base64[in >> 6]; - in &= 0x3F; - cur_dest[3] = base64[in]; - cur_dest += 4; - szdest -= 4; - break; - } - default: - // Should not be reached: blocks of 4 bytes are handled - // in the while loop before this switch statement. - ABSL_RAW_LOG(FATAL, "Logic problem? szsrc = %zu", szsrc); - break; - } - return (cur_dest - dest); -} - -} // namespace strings_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2020 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 +// +// https://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. + +#include "y_absl/strings/internal/escaping.h" + +#include "y_absl/base/internal/endian.h" +#include "y_absl/base/internal/raw_logging.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace strings_internal { + +const char kBase64Chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { + // Base64 encodes three bytes of input at a time. If the input is not + // divisible by three, we pad as appropriate. + // + // (from https://tools.ietf.org/html/rfc3548) + // Special processing is performed if fewer than 24 bits are available + // at the end of the data being encoded. A full encoding quantum is + // always completed at the end of a quantity. When fewer than 24 input + // bits are available in an input group, zero bits are added (on the + // right) to form an integral number of 6-bit groups. Padding at the + // end of the data is performed using the '=' character. Since all base + // 64 input is an integral number of octets, only the following cases + // can arise: + + // Base64 encodes each three bytes of input into four bytes of output. + size_t len = (input_len / 3) * 4; + + if (input_len % 3 == 0) { + // (from https://tools.ietf.org/html/rfc3548) + // (1) the final quantum of encoding input is an integral multiple of 24 + // bits; here, the final unit of encoded output will be an integral + // multiple of 4 characters with no "=" padding, + } else if (input_len % 3 == 1) { + // (from https://tools.ietf.org/html/rfc3548) + // (2) the final quantum of encoding input is exactly 8 bits; here, the + // final unit of encoded output will be two characters followed by two + // "=" padding characters, or + len += 2; + if (do_padding) { + len += 2; + } + } else { // (input_len % 3 == 2) + // (from https://tools.ietf.org/html/rfc3548) + // (3) the final quantum of encoding input is exactly 16 bits; here, the + // final unit of encoded output will be three characters followed by one + // "=" padding character. + len += 3; + if (do_padding) { + len += 1; + } + } + + assert(len >= input_len); // make sure we didn't overflow + return len; +} + +size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, + size_t szdest, const char* base64, + bool do_padding) { + static const char kPad64 = '='; + + if (szsrc * 4 > szdest * 3) return 0; + + char* cur_dest = dest; + const unsigned char* cur_src = src; + + char* const limit_dest = dest + szdest; + const unsigned char* const limit_src = src + szsrc; + + // Three bytes of data encodes to four characters of cyphertext. + // So we can pump through three-byte chunks atomically. + if (szsrc >= 3) { // "limit_src - 3" is UB if szsrc < 3. + while (cur_src < limit_src - 3) { // While we have >= 32 bits. + uint32_t in = y_absl::big_endian::Load32(cur_src) >> 8; + + cur_dest[0] = base64[in >> 18]; + in &= 0x3FFFF; + cur_dest[1] = base64[in >> 12]; + in &= 0xFFF; + cur_dest[2] = base64[in >> 6]; + in &= 0x3F; + cur_dest[3] = base64[in]; + + cur_dest += 4; + cur_src += 3; + } + } + // To save time, we didn't update szdest or szsrc in the loop. So do it now. + szdest = limit_dest - cur_dest; + szsrc = limit_src - cur_src; + + /* now deal with the tail (<=3 bytes) */ + switch (szsrc) { + case 0: + // Nothing left; nothing more to do. + break; + case 1: { + // One byte left: this encodes to two characters, and (optionally) + // two pad characters to round out the four-character cypherblock. + if (szdest < 2) return 0; + uint32_t in = cur_src[0]; + cur_dest[0] = base64[in >> 2]; + in &= 0x3; + cur_dest[1] = base64[in << 4]; + cur_dest += 2; + szdest -= 2; + if (do_padding) { + if (szdest < 2) return 0; + cur_dest[0] = kPad64; + cur_dest[1] = kPad64; + cur_dest += 2; + szdest -= 2; + } + break; + } + case 2: { + // Two bytes left: this encodes to three characters, and (optionally) + // one pad character to round out the four-character cypherblock. + if (szdest < 3) return 0; + uint32_t in = y_absl::big_endian::Load16(cur_src); + cur_dest[0] = base64[in >> 10]; + in &= 0x3FF; + cur_dest[1] = base64[in >> 4]; + in &= 0x00F; + cur_dest[2] = base64[in << 2]; + cur_dest += 3; + szdest -= 3; + if (do_padding) { + if (szdest < 1) return 0; + cur_dest[0] = kPad64; + cur_dest += 1; + szdest -= 1; + } + break; + } + case 3: { + // Three bytes left: same as in the big loop above. We can't do this in + // the loop because the loop above always reads 4 bytes, and the fourth + // byte is past the end of the input. + if (szdest < 4) return 0; + uint32_t in = (cur_src[0] << 16) + y_absl::big_endian::Load16(cur_src + 1); + cur_dest[0] = base64[in >> 18]; + in &= 0x3FFFF; + cur_dest[1] = base64[in >> 12]; + in &= 0xFFF; + cur_dest[2] = base64[in >> 6]; + in &= 0x3F; + cur_dest[3] = base64[in]; + cur_dest += 4; + szdest -= 4; + break; + } + default: + // Should not be reached: blocks of 4 bytes are handled + // in the while loop before this switch statement. + ABSL_RAW_LOG(FATAL, "Logic problem? szsrc = %zu", szsrc); + break; + } + return (cur_dest - dest); +} + +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping.h index d62fc0fbcb..be8dc4460e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping.h @@ -1,58 +1,58 @@ -// Copyright 2020 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 -// -// https://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. - -#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_H_ -#define ABSL_STRINGS_INTERNAL_ESCAPING_H_ - -#include <cassert> - -#include "y_absl/strings/internal/resize_uninitialized.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace strings_internal { - -ABSL_CONST_INIT extern const char kBase64Chars[]; - -// Calculates how long a string will be when it is base64 encoded given its -// length and whether or not the result should be padded. -size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding); - -// Base64-encodes `src` using the alphabet provided in `base64` and writes the -// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars -// until its length is a multiple of 3. Returns the length of `dest`. -size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, - size_t szdest, const char* base64, bool do_padding); - -// Base64-encodes `src` using the alphabet provided in `base64` and writes the -// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars -// until its length is a multiple of 3. -template <typename String> -void Base64EscapeInternal(const unsigned char* src, size_t szsrc, String* dest, - bool do_padding, const char* base64_chars) { - const size_t calc_escaped_size = - CalculateBase64EscapedLenInternal(szsrc, do_padding); - STLStringResizeUninitialized(dest, calc_escaped_size); - - const size_t escaped_len = Base64EscapeInternal( - src, szsrc, &(*dest)[0], dest->size(), base64_chars, do_padding); - assert(calc_escaped_size == escaped_len); - dest->erase(escaped_len); -} - -} // namespace strings_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_ESCAPING_H_ +// Copyright 2020 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 +// +// https://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. + +#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_H_ +#define ABSL_STRINGS_INTERNAL_ESCAPING_H_ + +#include <cassert> + +#include "y_absl/strings/internal/resize_uninitialized.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace strings_internal { + +ABSL_CONST_INIT extern const char kBase64Chars[]; + +// Calculates how long a string will be when it is base64 encoded given its +// length and whether or not the result should be padded. +size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding); + +// Base64-encodes `src` using the alphabet provided in `base64` and writes the +// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars +// until its length is a multiple of 3. Returns the length of `dest`. +size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, + size_t szdest, const char* base64, bool do_padding); + +// Base64-encodes `src` using the alphabet provided in `base64` and writes the +// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars +// until its length is a multiple of 3. +template <typename String> +void Base64EscapeInternal(const unsigned char* src, size_t szsrc, String* dest, + bool do_padding, const char* base64_chars) { + const size_t calc_escaped_size = + CalculateBase64EscapedLenInternal(szsrc, do_padding); + STLStringResizeUninitialized(dest, calc_escaped_size); + + const size_t escaped_len = Base64EscapeInternal( + src, szsrc, &(*dest)[0], dest->size(), base64_chars, do_padding); + assert(calc_escaped_size == escaped_len); + dest->erase(escaped_len); +} + +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_ESCAPING_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping_test_common.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping_test_common.h index f145127225..20f98e27b0 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping_test_common.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/escaping_test_common.h @@ -22,7 +22,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { struct base64_testcase { @@ -127,7 +127,7 @@ inline const std::array<base64_testcase, 5>& base64_strings() { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/memutil.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/memutil.cc index 0ba6574fdb..fcd0fd6ace 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/memutil.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/memutil.cc @@ -17,7 +17,7 @@ #include <cstdlib> namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { int memcasecmp(const char* s1, const char* s2, size_t len) { @@ -108,5 +108,5 @@ const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/memutil.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/memutil.h index ee442fe25f..050af2c345 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/memutil.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/memutil.h @@ -69,7 +69,7 @@ #include "y_absl/strings/ascii.h" // for y_absl::ascii_tolower namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { inline char* memcat(char* dest, size_t destlen, const char* src, @@ -142,7 +142,7 @@ const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, size_t neelen); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_MEMUTIL_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/numbers_test_common.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/numbers_test_common.h index 12aec3ac11..496cc1889a 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/numbers_test_common.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/numbers_test_common.h @@ -21,12 +21,12 @@ #include <array> #include <cstdint> #include <limits> -#include <util/generic/string.h> - -#include "y_absl/base/config.h" +#include <util/generic/string.h> +#include "y_absl/base/config.h" + namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { template <typename IntType> @@ -178,7 +178,7 @@ inline const std::array<uint64_test_case, 34>& strtouint64_test_cases() { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/ostringstream.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/ostringstream.cc index ba18857d83..4427d66e27 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/ostringstream.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/ostringstream.cc @@ -15,7 +15,7 @@ #include "y_absl/strings/internal/ostringstream.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { OStringStream::Buf::int_type OStringStream::overflow(int c) { @@ -32,5 +32,5 @@ std::streamsize OStringStream::xsputn(const char* s, std::streamsize n) { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/ostringstream.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/ostringstream.h index d00cef9c23..9dbcf09f57 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/ostringstream.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/ostringstream.h @@ -18,12 +18,12 @@ #include <cassert> #include <ostream> #include <streambuf> -#include <util/generic/string.h> +#include <util/generic/string.h> #include "y_absl/base/port.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // The same as std::ostringstream but appends to a user-specified TString, @@ -83,7 +83,7 @@ class OStringStream : private std::basic_streambuf<char>, public std::ostream { }; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/pow10_helper.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/pow10_helper.h index e4d41d7e4e..7b529e72a4 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/pow10_helper.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/pow10_helper.h @@ -22,10 +22,10 @@ #include <vector> -#include "y_absl/base/config.h" - +#include "y_absl/base/config.h" + namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // Computes the precise value of 10^exp. (I.e. the nearest representable @@ -34,7 +34,7 @@ namespace strings_internal { double Pow10(int exp); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_POW10_HELPER_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/resize_uninitialized.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/resize_uninitialized.h index 14860bb237..68063a1922 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/resize_uninitialized.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/resize_uninitialized.h @@ -18,7 +18,7 @@ #define ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ #include <algorithm> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <type_traits> #include <utility> @@ -26,7 +26,7 @@ #include "y_absl/meta/type_traits.h" // for void_t namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // In this type trait, we look for a __resize_default_init member function, and @@ -113,7 +113,7 @@ void STLStringResizeUninitializedAmortized(string_type* s, size_t new_size) { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/stl_type_traits.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/stl_type_traits.h index db8d4635d0..a8a79a0e7d 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/stl_type_traits.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/stl_type_traits.h @@ -40,7 +40,7 @@ #include "y_absl/meta/type_traits.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { template <typename C, template <typename...> class T> @@ -243,6 +243,6 @@ struct IsStrictlyBaseOfAndConvertibleToSTLContainer IsConvertibleToSTLContainer<C>> {}; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.cc index 8d5c3b61ac..ebe05ae232 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.cc @@ -21,7 +21,7 @@ #include <cassert> #include <cerrno> #include <cstdlib> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <type_traits> #include "y_absl/base/port.h" @@ -29,7 +29,7 @@ #include "y_absl/strings/numbers.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -334,7 +334,7 @@ template <typename T> bool ConvertFloatArg(T v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return FormatConversionCharIsFloat(conv.conversion_char()) && - ConvertFloatImpl(v, conv, sink); + ConvertFloatImpl(v, conv, sink); } inline bool ConvertStringArg(string_view v, const FormatConversionSpecImpl conv, @@ -374,7 +374,7 @@ FormatConvertImpl(const char *v, const FormatConversionSpecImpl conv, } else if (conv.precision() < 0) { len = std::strlen(v); } else { - // If precision is set, we look for the NUL-terminator on the valid range. + // If precision is set, we look for the NUL-terminator on the valid range. len = std::find(v, v + conv.precision(), '\0') - v; } return {ConvertStringArg(string_view(v, len), conv, sink)}; @@ -484,5 +484,5 @@ ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(); } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.h index 59b7bcc727..1413fc721f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.h @@ -23,7 +23,7 @@ #include <limits> #include <memory> #include <sstream> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <util/stream/str.h> #include <type_traits> @@ -34,9 +34,9 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN -class Cord; +class Cord; class FormatCountCapture; class FormatSink; @@ -157,17 +157,17 @@ StringConvertResult FormatConvertImpl(const AbslCord& value, if (space_remaining > 0 && !is_left) sink->Append(space_remaining, ' '); - for (string_view piece : value.Chunks()) { - if (piece.size() > to_write) { - piece.remove_suffix(piece.size() - to_write); - to_write = 0; - } else { - to_write -= piece.size(); - } + for (string_view piece : value.Chunks()) { + if (piece.size() > to_write) { + piece.remove_suffix(piece.size() - to_write); + to_write = 0; + } else { + to_write -= piece.size(); + } sink->Append(piece); - if (to_write == 0) { - break; - } + if (to_write == 0) { + break; + } } if (space_remaining > 0 && is_left) sink->Append(space_remaining, ' '); @@ -522,7 +522,7 @@ ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern); } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.cc index 211ce25dea..aff5aad744 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.cc @@ -17,10 +17,10 @@ #include <cerrno> #include <limits> #include <sstream> -#include <util/generic/string.h> +#include <util/generic/string.h> namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -80,21 +80,21 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound, return false; } - FormatConversionSpecImplFriend::SetWidth(width, bound); - FormatConversionSpecImplFriend::SetPrecision(precision, bound); - - if (force_left) { + FormatConversionSpecImplFriend::SetWidth(width, bound); + FormatConversionSpecImplFriend::SetPrecision(precision, bound); + + if (force_left) { FormatConversionSpecImplFriend::SetFlags(unbound->flags | Flags::kLeft, bound); - } else { - FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); - } + } else { + FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); + } } else { - FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); - FormatConversionSpecImplFriend::SetWidth(-1, bound); - FormatConversionSpecImplFriend::SetPrecision(-1, bound); + FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); + FormatConversionSpecImplFriend::SetWidth(-1, bound); + FormatConversionSpecImplFriend::SetPrecision(-1, bound); } - FormatConversionSpecImplFriend::SetConversionChar(unbound->conv, bound); + FormatConversionSpecImplFriend::SetConversionChar(unbound->conv, bound); bound->set_arg(arg); return true; } @@ -156,8 +156,8 @@ class SummarizingConverter { UntypedFormatSpecImpl spec("%d"); std::ostringstream ss; - ss << "{" << Streamable(spec, {*bound.arg()}) << ":" - << FormatConversionSpecImplFriend::FlagsToString(bound); + ss << "{" << Streamable(spec, {*bound.arg()}) << ":" + << FormatConversionSpecImplFriend::FlagsToString(bound); if (bound.width() >= 0) ss << bound.width(); if (bound.precision() >= 0) ss << "." << bound.precision(); ss << bound.conversion_char() << "}"; @@ -254,5 +254,5 @@ int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl format, } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.h index 3966610710..a2ab6ff6ff 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.h @@ -18,7 +18,7 @@ #include <array> #include <cstdio> #include <sstream> -#include <util/generic/string.h> +#include <util/generic/string.h> #include "y_absl/base/port.h" #include "y_absl/strings/internal/str_format/arg.h" @@ -27,7 +27,7 @@ #include "y_absl/types/span.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN class UntypedFormatSpec; @@ -88,7 +88,7 @@ class FormatSpecTemplate using Base = typename MakeDependent<UntypedFormatSpec, Args...>::type; public: -#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER +#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER // Honeypot overload for when the string is not constexpr. // We use the 'unavailable' attribute to give a better compiler error than @@ -211,7 +211,7 @@ class StreamedWrapper { }; } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/checker.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/checker.h index 7c530d2507..78a137029f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/checker.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/checker.h @@ -15,20 +15,20 @@ #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ -#include "y_absl/base/attributes.h" +#include "y_absl/base/attributes.h" #include "y_absl/strings/internal/str_format/arg.h" #include "y_absl/strings/internal/str_format/extension.h" // Compile time check support for entry points. #ifndef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER -#if ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) +#if ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) #define ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 1 -#endif // ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) +#endif // ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { constexpr bool AllOf() { return true; } @@ -38,7 +38,7 @@ constexpr bool AllOf(bool b, T... t) { return b && AllOf(t...); } -#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER +#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER constexpr bool ContainsChar(const char* chars, char c) { return *chars == c || (*chars && ContainsChar(chars + 1, c)); @@ -327,7 +327,7 @@ constexpr bool ValidFormatImpl(string_view format) { #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.cc index f2a4169ae7..2eafe4721d 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.cc @@ -17,10 +17,10 @@ #include <errno.h> #include <algorithm> -#include <util/generic/string.h> +#include <util/generic/string.h> namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { TString FlagsToString(Flags v) { @@ -71,5 +71,5 @@ bool FormatSinkImpl::PutPaddedString(string_view value, int width, } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.h index e5de5cb6a1..b4cd3d61f3 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.h @@ -17,19 +17,19 @@ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ #include <limits.h> - + #include <cstddef> #include <cstring> #include <ostream> -#include "y_absl/base/config.h" +#include "y_absl/base/config.h" #include "y_absl/base/port.h" #include "y_absl/meta/type_traits.h" #include "y_absl/strings/internal/str_format/output.h" #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN enum class FormatConversionChar : uint8_t; enum class FormatConversionCharSet : uint64_t; @@ -156,7 +156,7 @@ inline std::ostream& operator<<(std::ostream& os, Flags v) { } // clang-format off -#define ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ +#define ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ /* text */ \ X_VAL(c) X_SEP X_VAL(s) X_SEP \ /* ints */ \ @@ -200,21 +200,21 @@ struct FormatConversionCharInternal { #undef ABSL_INTERNAL_X_VAL static constexpr FormatConversionChar kNone = static_cast<FormatConversionChar>(Enum::kNone); -}; -// clang-format on +}; +// clang-format on -inline FormatConversionChar FormatConversionCharFromChar(char c) { - switch (c) { -#define ABSL_INTERNAL_X_VAL(id) \ - case #id[0]: \ +inline FormatConversionChar FormatConversionCharFromChar(char c) { + switch (c) { +#define ABSL_INTERNAL_X_VAL(id) \ + case #id[0]: \ return FormatConversionCharInternal::id; - ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) -#undef ABSL_INTERNAL_X_VAL + ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) +#undef ABSL_INTERNAL_X_VAL } return FormatConversionCharInternal::kNone; -} +} -inline bool FormatConversionCharIsUpper(FormatConversionChar c) { +inline bool FormatConversionCharIsUpper(FormatConversionChar c) { if (c == FormatConversionCharInternal::X || c == FormatConversionCharInternal::F || c == FormatConversionCharInternal::E || @@ -224,9 +224,9 @@ inline bool FormatConversionCharIsUpper(FormatConversionChar c) { } else { return false; } -} +} -inline bool FormatConversionCharIsFloat(FormatConversionChar c) { +inline bool FormatConversionCharIsFloat(FormatConversionChar c) { if (c == FormatConversionCharInternal::a || c == FormatConversionCharInternal::e || c == FormatConversionCharInternal::f || @@ -239,38 +239,38 @@ inline bool FormatConversionCharIsFloat(FormatConversionChar c) { } else { return false; } -} +} -inline char FormatConversionCharToChar(FormatConversionChar c) { +inline char FormatConversionCharToChar(FormatConversionChar c) { if (c == FormatConversionCharInternal::kNone) { return '\0'; #define ABSL_INTERNAL_X_VAL(e) \ } else if (c == FormatConversionCharInternal::e) { \ - return #e[0]; -#define ABSL_INTERNAL_X_SEP + return #e[0]; +#define ABSL_INTERNAL_X_SEP ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ABSL_INTERNAL_X_SEP) } else { return '\0'; } -#undef ABSL_INTERNAL_X_VAL -#undef ABSL_INTERNAL_X_SEP -} +#undef ABSL_INTERNAL_X_VAL +#undef ABSL_INTERNAL_X_SEP +} -// The associated char. -inline std::ostream& operator<<(std::ostream& os, FormatConversionChar v) { - char c = FormatConversionCharToChar(v); - if (!c) c = '?'; - return os << c; -} +// The associated char. +inline std::ostream& operator<<(std::ostream& os, FormatConversionChar v) { + char c = FormatConversionCharToChar(v); + if (!c) c = '?'; + return os << c; +} -struct FormatConversionSpecImplFriend; +struct FormatConversionSpecImplFriend; class FormatConversionSpecImpl { - public: - // Width and precison are not specified, no flags are set. + public: + // Width and precison are not specified, no flags are set. bool is_basic() const { return flags_ == Flags::kBasic; } bool has_left_flag() const { return FlagsContains(flags_, Flags::kLeft); } bool has_show_pos_flag() const { @@ -282,7 +282,7 @@ class FormatConversionSpecImpl { bool has_alt_flag() const { return FlagsContains(flags_, Flags::kAlt); } bool has_zero_flag() const { return FlagsContains(flags_, Flags::kZero); } - FormatConversionChar conversion_char() const { + FormatConversionChar conversion_char() const { // Keep this field first in the struct . It generates better code when // accessing it when ConversionSpec is passed by value in registers. static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0, ""); @@ -302,32 +302,32 @@ class FormatConversionSpecImpl { } private: - friend struct str_format_internal::FormatConversionSpecImplFriend; + friend struct str_format_internal::FormatConversionSpecImplFriend; FormatConversionChar conv_ = FormatConversionCharInternal::kNone; Flags flags_; int width_; int precision_; }; -struct FormatConversionSpecImplFriend final { +struct FormatConversionSpecImplFriend final { static void SetFlags(Flags f, FormatConversionSpecImpl* conv) { - conv->flags_ = f; - } - static void SetConversionChar(FormatConversionChar c, + conv->flags_ = f; + } + static void SetConversionChar(FormatConversionChar c, FormatConversionSpecImpl* conv) { - conv->conv_ = c; - } + conv->conv_ = c; + } static void SetWidth(int w, FormatConversionSpecImpl* conv) { conv->width_ = w; } static void SetPrecision(int p, FormatConversionSpecImpl* conv) { - conv->precision_ = p; - } + conv->precision_ = p; + } static TString FlagsToString(const FormatConversionSpecImpl& spec) { return str_format_internal::FlagsToString(spec.flags_); - } -}; - + } +}; + // Type safe OR operator. // We need this for two reasons: // 1. operator| on enums makes them decay to integers and the result is an @@ -355,9 +355,9 @@ constexpr uint64_t FormatConversionCharToConvInt(char conv) { #define ABSL_INTERNAL_CHAR_SET_CASE(c) \ conv == #c[0] \ ? FormatConversionCharToConvInt(FormatConversionCharInternal::c) \ - : - ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) -#undef ABSL_INTERNAL_CHAR_SET_CASE + : + ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) +#undef ABSL_INTERNAL_CHAR_SET_CASE conv == '*' ? 1 : 0; @@ -372,8 +372,8 @@ struct FormatConversionCharSetInternal { #define ABSL_INTERNAL_CHAR_SET_CASE(c) \ static constexpr FormatConversionCharSet c = \ FormatConversionCharToConvValue(#c[0]); - ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) -#undef ABSL_INTERNAL_CHAR_SET_CASE + ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) +#undef ABSL_INTERNAL_CHAR_SET_CASE // Used for width/precision '*' specification. static constexpr FormatConversionCharSet kStar = @@ -393,8 +393,8 @@ struct FormatConversionCharSetInternal { // 1. operator| on enums makes them decay to integers and the result is an // integer. We need the result to stay as an enum. // 2. We use "enum class" which would not work even if we accepted the decay. -constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, - FormatConversionCharSet b) { +constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, + FormatConversionCharSet b) { return FormatConversionCharSetUnion(a, b); } @@ -415,14 +415,14 @@ template <typename T> void ToFormatConversionCharSet(T) = delete; // Checks whether `c` exists in `set`. -constexpr bool Contains(FormatConversionCharSet set, char c) { +constexpr bool Contains(FormatConversionCharSet set, char c) { return (static_cast<uint64_t>(set) & static_cast<uint64_t>(FormatConversionCharToConvValue(c))) != 0; } // Checks whether all the characters in `c` are contained in `set` -constexpr bool Contains(FormatConversionCharSet set, - FormatConversionCharSet c) { +constexpr bool Contains(FormatConversionCharSet set, + FormatConversionCharSet c) { return (static_cast<uint64_t>(set) & static_cast<uint64_t>(c)) == static_cast<uint64_t>(c); } @@ -439,7 +439,7 @@ inline size_t Excess(size_t used, size_t capacity) { } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/float_conversion.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/float_conversion.cc index c49062538d..7a5f1d23a2 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/float_conversion.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/float_conversion.cc @@ -20,7 +20,7 @@ #include <cassert> #include <cmath> #include <limits> -#include <util/generic/string.h> +#include <util/generic/string.h> #include "y_absl/base/attributes.h" #include "y_absl/base/config.h" @@ -35,7 +35,7 @@ #include "y_absl/types/span.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -946,7 +946,7 @@ bool FallbackToSnprintf(const Float v, const FormatConversionSpecImpl &conv, { char *fp = fmt; *fp++ = '%'; - fp = CopyStringTo(FormatConversionSpecImplFriend::FlagsToString(conv), fp); + fp = CopyStringTo(FormatConversionSpecImplFriend::FlagsToString(conv), fp); fp = CopyStringTo("*.*", fp); if (std::is_same<long double, Float>()) { *fp++ = 'L'; @@ -1419,5 +1419,5 @@ bool ConvertFloatImpl(double v, const FormatConversionSpecImpl &conv, } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/float_conversion.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/float_conversion.h index d93a415756..c586eb4e49 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/float_conversion.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/float_conversion.h @@ -18,7 +18,7 @@ #include "y_absl/strings/internal/str_format/extension.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { bool ConvertFloatImpl(float v, const FormatConversionSpecImpl &conv, @@ -31,7 +31,7 @@ bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink); } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/output.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/output.cc index ade3f67ef2..f80aeb1214 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/output.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/output.cc @@ -18,7 +18,7 @@ #include <cstring> namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -68,5 +68,5 @@ void FILERawSink::Write(string_view v) { } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/output.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/output.h index 8fc46fbafa..2a2fa34abb 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/output.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/output.h @@ -23,13 +23,13 @@ #include <cstdio> #include <ostream> -#include <util/generic/string.h> +#include <util/generic/string.h> #include "y_absl/base/port.h" #include "y_absl/strings/string_view.h" -namespace y_absl { -ABSL_NAMESPACE_BEGIN +namespace y_absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { // RawSink implementation that writes into a char* buffer. @@ -90,7 +90,7 @@ auto InvokeFlush(T* out, string_view s) -> decltype(AbslFormatFlush(out, s)) { } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.cc index af07e32fe5..f8b7c04931 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.cc @@ -24,16 +24,16 @@ #include <initializer_list> #include <limits> #include <ostream> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <unordered_set> namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { using CC = FormatConversionCharInternal; -using LM = LengthMod; - +using LM = LengthMod; + // Abbreviations to fit in the table below. constexpr auto f_sign = Flags::kSignCol; constexpr auto f_alt = Flags::kAlt; @@ -209,11 +209,11 @@ const char *ConsumeConversion(const char *pos, const char *const end, using str_format_internal::LengthMod; LengthMod length_mod = tag.as_length(); ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); - if (c == 'h' && length_mod == LengthMod::h) { - conv->length_mod = LengthMod::hh; + if (c == 'h' && length_mod == LengthMod::h) { + conv->length_mod = LengthMod::hh; ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); - } else if (c == 'l' && length_mod == LengthMod::l) { - conv->length_mod = LengthMod::ll; + } else if (c == 'l' && length_mod == LengthMod::l) { + conv->length_mod = LengthMod::ll; ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); } else { conv->length_mod = length_mod; @@ -232,32 +232,32 @@ const char *ConsumeConversion(const char *pos, const char *const end, } // namespace -TString LengthModToString(LengthMod v) { - switch (v) { - case LengthMod::h: - return "h"; - case LengthMod::hh: - return "hh"; - case LengthMod::l: - return "l"; - case LengthMod::ll: - return "ll"; - case LengthMod::L: - return "L"; - case LengthMod::j: - return "j"; - case LengthMod::z: - return "z"; - case LengthMod::t: - return "t"; - case LengthMod::q: - return "q"; - case LengthMod::none: - return ""; - } - return ""; -} - +TString LengthModToString(LengthMod v) { + switch (v) { + case LengthMod::h: + return "h"; + case LengthMod::hh: + return "hh"; + case LengthMod::l: + return "l"; + case LengthMod::ll: + return "ll"; + case LengthMod::L: + return "L"; + case LengthMod::j: + return "j"; + case LengthMod::z: + return "z"; + case LengthMod::t: + return "t"; + case LengthMod::q: + return "q"; + case LengthMod::none: + return ""; + } + return ""; +} + const char *ConsumeUnboundConversion(const char *p, const char *end, UnboundConversion *conv, int *next_arg) { if (*next_arg < 0) return ConsumeConversion<true>(p, end, conv, next_arg); @@ -327,13 +327,13 @@ bool ParsedFormatBase::MatchesConversions( if (conv.width.is_from_arg() && !add_if_valid_conv(conv.width.get_from_arg(), '*')) return false; - if (!add_if_valid_conv(conv.arg_position, - FormatConversionCharToChar(conv.conv))) - return false; + if (!add_if_valid_conv(conv.arg_position, + FormatConversionCharToChar(conv.conv))) + return false; } return used.size() == convs.size() || allow_ignored; } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.h index ba614bb8b4..64a4a7ce59 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.h @@ -20,25 +20,25 @@ #include <stdlib.h> #include <cassert> -#include <cstdint> +#include <cstdint> #include <initializer_list> #include <iosfwd> #include <iterator> #include <memory> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <vector> #include "y_absl/strings/internal/str_format/checker.h" #include "y_absl/strings/internal/str_format/extension.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { -enum class LengthMod : std::uint8_t { h, hh, l, ll, L, j, z, t, q, none }; - -TString LengthModToString(LengthMod v); - +enum class LengthMod : std::uint8_t { h, hh, l, ll, L, j, z, t, q, none }; + +TString LengthModToString(LengthMod v); + // The analyzed properties of a single specified conversion. struct UnboundConversion { UnboundConversion() {} @@ -77,7 +77,7 @@ struct UnboundConversion { InputValue precision; Flags flags = Flags::kBasic; - LengthMod length_mod = LengthMod::none; + LengthMod length_mod = LengthMod::none; FormatConversionChar conv = FormatConversionCharInternal::kNone; }; @@ -91,12 +91,12 @@ const char* ConsumeUnboundConversion(const char* p, const char* end, // Helper tag class for the table below. // It allows fast `char -> ConversionChar/LengthMod/Flags` checking and -// conversions. +// conversions. class ConvTag { public: constexpr ConvTag(FormatConversionChar conversion_char) // NOLINT : tag_(static_cast<uint8_t>(conversion_char)) {} - constexpr ConvTag(LengthMod length_mod) // NOLINT + constexpr ConvTag(LengthMod length_mod) // NOLINT : tag_(0x80 | static_cast<uint8_t>(length_mod)) {} constexpr ConvTag(Flags flags) // NOLINT : tag_(0xc0 | static_cast<uint8_t>(flags)) {} @@ -308,7 +308,7 @@ template <FormatConversionCharSet... C> class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase { public: explicit ExtendedParsedFormat(string_view format) -#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER +#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER __attribute__(( enable_if(str_format_internal::EnsureConstexpr(format), "Format string is not constexpr."), @@ -351,7 +351,7 @@ class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase { : ParsedFormatBase(s, allow_ignored, {C...}) {} }; } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/ya.make index ff8069cd0f..63aaefb0c3 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/ya.make @@ -22,9 +22,9 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal ) -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp-tstring -) +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp-tstring +) NO_COMPILER_WARNINGS() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_join_internal.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_join_internal.h index 0a220fa33d..3e9bc53cf6 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_join_internal.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_join_internal.h @@ -34,7 +34,7 @@ #include <cstring> #include <iterator> #include <memory> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <type_traits> #include <utility> @@ -43,7 +43,7 @@ #include "y_absl/strings/str_cat.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // @@ -308,7 +308,7 @@ TString JoinRange(const Range& range, y_absl::string_view separator) { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_split_internal.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_split_internal.h index 237864c0ed..158c1ea8ab 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_split_internal.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_split_internal.h @@ -47,7 +47,7 @@ #endif // _GLIBCXX_DEBUG namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // This class is implicitly constructible from everything that y_absl::string_view @@ -424,7 +424,7 @@ class Splitter { }; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/utf8.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/utf8.cc index 06b1cae79d..f1c2c15528 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/utf8.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/utf8.cc @@ -17,7 +17,7 @@ #include "y_absl/strings/internal/utf8.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { size_t EncodeUTF8Char(char *buffer, char32_t utf8_char) { @@ -49,5 +49,5 @@ size_t EncodeUTF8Char(char *buffer, char32_t utf8_char) { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/utf8.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/utf8.h index 1b2d6abd51..53ef10c972 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/utf8.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/utf8.h @@ -20,10 +20,10 @@ #include <cstddef> #include <cstdint> -#include "y_absl/base/config.h" - +#include "y_absl/base/config.h" + namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // For Unicode code points 0 through 0x10FFFF, EncodeUTF8Char writes @@ -44,7 +44,7 @@ enum { kMaxEncodedUTF8Size = 4 }; size_t EncodeUTF8Char(char *buffer, char32_t utf8_char); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_INTERNAL_UTF8_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/match.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/match.cc index 3197bdf432..f13a2f323d 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/match.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/match.cc @@ -17,7 +17,7 @@ #include "y_absl/strings/internal/memutil.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN bool EqualsIgnoreCase(y_absl::string_view piece1, y_absl::string_view piece2) noexcept { @@ -39,5 +39,5 @@ bool EndsWithIgnoreCase(y_absl::string_view text, EqualsIgnoreCase(text.substr(text.size() - suffix.size()), suffix); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/match.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/match.h index 4709abc93f..379676bc2d 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/match.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/match.h @@ -20,7 +20,7 @@ // This file contains simple utilities for performing string matching checks. // All of these function parameters are specified as `y_absl::string_view`, // meaning that these functions can accept `TString`, `y_absl::string_view` or -// NUL-terminated C-style strings. +// NUL-terminated C-style strings. // // Examples: // TString s = "foo"; @@ -38,7 +38,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // StrContains() // @@ -94,7 +94,7 @@ bool StartsWithIgnoreCase(y_absl::string_view text, bool EndsWithIgnoreCase(y_absl::string_view text, y_absl::string_view suffix) noexcept; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_MATCH_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.cc index 528d044fa6..b8896837e1 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.cc @@ -30,7 +30,7 @@ #include <memory> #include <utility> -#include "y_absl/base/attributes.h" +#include "y_absl/base/attributes.h" #include "y_absl/base/internal/raw_logging.h" #include "y_absl/numeric/bits.h" #include "y_absl/strings/ascii.h" @@ -41,7 +41,7 @@ #include "y_absl/strings/str_cat.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN bool SimpleAtof(y_absl::string_view str, float* out) { *out = 0.0; @@ -730,8 +730,8 @@ inline bool safe_parse_sign_and_base(y_absl::string_view* text /*inout*/, // commonly used bases. template <typename IntType> struct LookupTables { - ABSL_CONST_INIT static const IntType kVmaxOverBase[]; - ABSL_CONST_INIT static const IntType kVminOverBase[]; + ABSL_CONST_INIT static const IntType kVmaxOverBase[]; + ABSL_CONST_INIT static const IntType kVminOverBase[]; }; // An array initializer macro for X/base where base in [0, 36]. @@ -755,49 +755,49 @@ struct LookupTables { // } // See https://godbolt.org/z/aneYsb // -// uint128& operator/=(uint128) is not constexpr, so hardcode the resulting -// array to avoid a static initializer. +// uint128& operator/=(uint128) is not constexpr, so hardcode the resulting +// array to avoid a static initializer. template<> -const uint128 LookupTables<uint128>::kVmaxOverBase[] = { - 0, - 0, - MakeUint128(9223372036854775807u, 18446744073709551615u), - MakeUint128(6148914691236517205u, 6148914691236517205u), - MakeUint128(4611686018427387903u, 18446744073709551615u), - MakeUint128(3689348814741910323u, 3689348814741910323u), - MakeUint128(3074457345618258602u, 12297829382473034410u), - MakeUint128(2635249153387078802u, 5270498306774157604u), - MakeUint128(2305843009213693951u, 18446744073709551615u), - MakeUint128(2049638230412172401u, 14347467612885206812u), - MakeUint128(1844674407370955161u, 11068046444225730969u), - MakeUint128(1676976733973595601u, 8384883669867978007u), - MakeUint128(1537228672809129301u, 6148914691236517205u), - MakeUint128(1418980313362273201u, 4256940940086819603u), - MakeUint128(1317624576693539401u, 2635249153387078802u), - MakeUint128(1229782938247303441u, 1229782938247303441u), - MakeUint128(1152921504606846975u, 18446744073709551615u), - MakeUint128(1085102592571150095u, 1085102592571150095u), - MakeUint128(1024819115206086200u, 16397105843297379214u), - MakeUint128(970881267037344821u, 16504981539634861972u), - MakeUint128(922337203685477580u, 14757395258967641292u), - MakeUint128(878416384462359600u, 14054662151397753612u), - MakeUint128(838488366986797800u, 13415813871788764811u), - MakeUint128(802032351030850070u, 4812194106185100421u), - MakeUint128(768614336404564650u, 12297829382473034410u), - MakeUint128(737869762948382064u, 11805916207174113034u), - MakeUint128(709490156681136600u, 11351842506898185609u), - MakeUint128(683212743470724133u, 17080318586768103348u), - MakeUint128(658812288346769700u, 10540996613548315209u), - MakeUint128(636094623231363848u, 15266270957552732371u), - MakeUint128(614891469123651720u, 9838263505978427528u), - MakeUint128(595056260442243600u, 9520900167075897608u), - MakeUint128(576460752303423487u, 18446744073709551615u), - MakeUint128(558992244657865200u, 8943875914525843207u), - MakeUint128(542551296285575047u, 9765923333140350855u), - MakeUint128(527049830677415760u, 8432797290838652167u), - MakeUint128(512409557603043100u, 8198552921648689607u), -}; - +const uint128 LookupTables<uint128>::kVmaxOverBase[] = { + 0, + 0, + MakeUint128(9223372036854775807u, 18446744073709551615u), + MakeUint128(6148914691236517205u, 6148914691236517205u), + MakeUint128(4611686018427387903u, 18446744073709551615u), + MakeUint128(3689348814741910323u, 3689348814741910323u), + MakeUint128(3074457345618258602u, 12297829382473034410u), + MakeUint128(2635249153387078802u, 5270498306774157604u), + MakeUint128(2305843009213693951u, 18446744073709551615u), + MakeUint128(2049638230412172401u, 14347467612885206812u), + MakeUint128(1844674407370955161u, 11068046444225730969u), + MakeUint128(1676976733973595601u, 8384883669867978007u), + MakeUint128(1537228672809129301u, 6148914691236517205u), + MakeUint128(1418980313362273201u, 4256940940086819603u), + MakeUint128(1317624576693539401u, 2635249153387078802u), + MakeUint128(1229782938247303441u, 1229782938247303441u), + MakeUint128(1152921504606846975u, 18446744073709551615u), + MakeUint128(1085102592571150095u, 1085102592571150095u), + MakeUint128(1024819115206086200u, 16397105843297379214u), + MakeUint128(970881267037344821u, 16504981539634861972u), + MakeUint128(922337203685477580u, 14757395258967641292u), + MakeUint128(878416384462359600u, 14054662151397753612u), + MakeUint128(838488366986797800u, 13415813871788764811u), + MakeUint128(802032351030850070u, 4812194106185100421u), + MakeUint128(768614336404564650u, 12297829382473034410u), + MakeUint128(737869762948382064u, 11805916207174113034u), + MakeUint128(709490156681136600u, 11351842506898185609u), + MakeUint128(683212743470724133u, 17080318586768103348u), + MakeUint128(658812288346769700u, 10540996613548315209u), + MakeUint128(636094623231363848u, 15266270957552732371u), + MakeUint128(614891469123651720u, 9838263505978427528u), + MakeUint128(595056260442243600u, 9520900167075897608u), + MakeUint128(576460752303423487u, 18446744073709551615u), + MakeUint128(558992244657865200u, 8943875914525843207u), + MakeUint128(542551296285575047u, 9765923333140350855u), + MakeUint128(527049830677415760u, 8432797290838652167u), + MakeUint128(512409557603043100u, 8198552921648689607u), +}; + // This kVmaxOverBase generated with // for (int base = 2; base < 37; ++base) { // y_absl::int128 max = std::numeric_limits<y_absl::int128>::max(); @@ -922,8 +922,8 @@ inline bool safe_parse_positive_int(y_absl::string_view text, int base, assert(base >= 0); assert(vmax >= static_cast<IntType>(base)); const IntType vmax_over_base = LookupTables<IntType>::kVmaxOverBase[base]; - assert(base < 2 || - std::numeric_limits<IntType>::max() / base == vmax_over_base); + assert(base < 2 || + std::numeric_limits<IntType>::max() / base == vmax_over_base); const char* start = text.data(); const char* end = start + text.size(); // loop over digits @@ -957,8 +957,8 @@ inline bool safe_parse_negative_int(y_absl::string_view text, int base, assert(vmin < 0); assert(vmin <= 0 - base); IntType vmin_over_base = LookupTables<IntType>::kVminOverBase[base]; - assert(base < 2 || - std::numeric_limits<IntType>::min() / base == vmin_over_base); + assert(base < 2 || + std::numeric_limits<IntType>::min() / base == vmin_over_base); // 2003 c++ standard [expr.mul] // "... the sign of the remainder is implementation-defined." // Although (vmin/base)*base + vmin%base is always vmin. @@ -1024,10 +1024,10 @@ inline bool safe_uint_internal(y_absl::string_view text, IntType* value_p, namespace numbers_internal { // Digit conversion. -ABSL_CONST_INIT ABSL_DLL const char kHexChar[] = - "0123456789abcdef"; +ABSL_CONST_INIT ABSL_DLL const char kHexChar[] = + "0123456789abcdef"; -ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] = +ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] = "000102030405060708090a0b0c0d0e0f" "101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f" @@ -1045,7 +1045,7 @@ ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] = "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; -ABSL_CONST_INIT ABSL_DLL const char two_ASCII_digits[100][2] = { +ABSL_CONST_INIT ABSL_DLL const char two_ASCII_digits[100][2] = { {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, @@ -1089,5 +1089,5 @@ bool safe_strtou128_base(y_absl::string_view text, uint128* value, int base) { } } // namespace numbers_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.h index ce181d8eb1..8f4776f75b 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.h @@ -40,10 +40,10 @@ #include <cstring> #include <ctime> #include <limits> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <type_traits> -#include "y_absl/base/config.h" +#include "y_absl/base/config.h" #ifdef _Y__SSE4_2__ // TODO(jorg): Remove this when we figure out the right way // to swap bytes on SSE 4.2 that works with the compilers @@ -59,24 +59,24 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // SimpleAtoi() // -// Converts the given string (optionally followed or preceded by ASCII -// whitespace) into an integer value, returning `true` if successful. The string -// must reflect a base-10 integer whose value falls within the range of the -// integer type (optionally preceded by a `+` or `-`). If any errors are -// encountered, this function returns `false`, leaving `out` in an unspecified -// state. +// Converts the given string (optionally followed or preceded by ASCII +// whitespace) into an integer value, returning `true` if successful. The string +// must reflect a base-10 integer whose value falls within the range of the +// integer type (optionally preceded by a `+` or `-`). If any errors are +// encountered, this function returns `false`, leaving `out` in an unspecified +// state. template <typename int_type> ABSL_MUST_USE_RESULT bool SimpleAtoi(y_absl::string_view str, int_type* out); // SimpleAtof() // // Converts the given string (optionally followed or preceded by ASCII -// whitespace) into a float, which may be rounded on overflow or underflow, -// returning `true` if successful. +// whitespace) into a float, which may be rounded on overflow or underflow, +// returning `true` if successful. // See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`, except SimpleAtof() is locale-independent and will // always use the "C" locale. If any errors are encountered, this function @@ -86,8 +86,8 @@ ABSL_MUST_USE_RESULT bool SimpleAtof(y_absl::string_view str, float* out); // SimpleAtod() // // Converts the given string (optionally followed or preceded by ASCII -// whitespace) into a double, which may be rounded on overflow or underflow, -// returning `true` if successful. +// whitespace) into a double, which may be rounded on overflow or underflow, +// returning `true` if successful. // See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`, except SimpleAtod is locale-independent and will // always use the "C" locale. If any errors are encountered, this function @@ -123,21 +123,21 @@ ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, y_absl::uint128* out); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl // End of public API. Implementation details follow. namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace numbers_internal { // Digit conversion. -ABSL_DLL extern const char kHexChar[17]; // 0123456789abcdef -ABSL_DLL extern const char - kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011... -ABSL_DLL extern const char - two_ASCII_digits[100][2]; // 00, 01, 02, 03... +ABSL_DLL extern const char kHexChar[17]; // 0123456789abcdef +ABSL_DLL extern const char + kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011... +ABSL_DLL extern const char + two_ASCII_digits[100][2]; // 00, 01, 02, 03... // Writes a two-character representation of 'i' to 'buf'. 'i' must be in the // range 0 <= i < 100, and buf must have space for two characters. Example: @@ -302,7 +302,7 @@ ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, return numbers_internal::safe_strtou128_base(str, out, 16); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_NUMBERS_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.cc index 9e11702eae..ebaa952be3 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.cc @@ -25,7 +25,7 @@ #include "y_absl/strings/numbers.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN AlphaNum::AlphaNum(Hex hex) { static_assert(numbers_internal::kFastToBufferSize >= 32, @@ -242,5 +242,5 @@ void StrAppend(TString* dest, const AlphaNum& a, const AlphaNum& b, assert(out == begin + dest->size()); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.h index a77c9ae906..3bcd9234b4 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.h @@ -55,7 +55,7 @@ #include <array> #include <cstdint> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <type_traits> #include <vector> @@ -64,7 +64,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // AlphaNumBuffer allows a way to pass a string to StrCat without having to do @@ -405,7 +405,7 @@ SixDigits(double d) { return result; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_STR_CAT_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_format.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_format.h index 4079f38fb4..b5da2fa822 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_format.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_format.h @@ -71,7 +71,7 @@ #define ABSL_STRINGS_STR_FORMAT_H_ #include <cstdio> -#include <util/generic/string.h> +#include <util/generic/string.h> #include "y_absl/strings/internal/str_format/arg.h" // IWYU pragma: export #include "y_absl/strings/internal/str_format/bind.h" // IWYU pragma: export @@ -80,7 +80,7 @@ #include "y_absl/strings/internal/str_format/parser.h" // IWYU pragma: export namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // UntypedFormatSpec // @@ -427,7 +427,7 @@ int FPrintF(std::FILE* output, const FormatSpec<Args...>& format, // type-safe); prefer `y_absl::SNPrintF()` over `std::snprintf()`. // // In particular, a successful call to `y_absl::SNPrintF()` writes at most `size` -// bytes of the formatted output to `output`, including a NUL-terminator, and +// bytes of the formatted output to `output`, including a NUL-terminator, and // returns the number of bytes that would have been written if truncation did // not occur. In the event of an error, a negative value is returned and `errno` // is set. @@ -806,7 +806,7 @@ struct FormatConvertResult { bool value; }; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_STR_FORMAT_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_join.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_join.h index 46a0323c6e..acb48b4540 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_join.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_join.h @@ -50,7 +50,7 @@ #include <cstring> #include <initializer_list> #include <iterator> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <tuple> #include <type_traits> #include <utility> @@ -60,7 +60,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // Concept: Formatter @@ -287,7 +287,7 @@ TString StrJoin(const std::tuple<T...>& value, return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter()); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_STR_JOIN_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_replace.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_replace.cc index 77b78c6c16..b5439a22a7 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_replace.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_replace.cc @@ -17,7 +17,7 @@ #include "y_absl/strings/str_cat.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { using FixedMapping = @@ -78,5 +78,5 @@ int StrReplaceAll(strings_internal::FixedMapping replacements, return StrReplaceAll<strings_internal::FixedMapping>(replacements, target); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_replace.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_replace.h index 42c85616a0..6640fbea39 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_replace.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_replace.h @@ -38,7 +38,7 @@ #ifndef ABSL_STRINGS_STR_REPLACE_H_ #define ABSL_STRINGS_STR_REPLACE_H_ -#include <util/generic/string.h> +#include <util/generic/string.h> #include <utility> #include <vector> @@ -46,7 +46,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // StrReplaceAll() // @@ -213,7 +213,7 @@ int StrReplaceAll(const StrToStrMapping& replacements, TString* target) { return substitutions; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_STR_REPLACE_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_split.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_split.cc index 5f9193e6ba..22a691811f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_split.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_split.cc @@ -27,7 +27,7 @@ #include "y_absl/strings/ascii.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { @@ -135,5 +135,5 @@ y_absl::string_view ByLength::Find(y_absl::string_view text, return y_absl::string_view(substr.data() + length_, 0); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_split.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_split.h index d32d54813e..8d8c54d6ff 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_split.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_split.h @@ -39,7 +39,7 @@ #include <cstddef> #include <map> #include <set> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <utility> #include <vector> @@ -50,7 +50,7 @@ #include "y_absl/strings/strip.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN //------------------------------------------------------------------------------ // Delimiters @@ -542,7 +542,7 @@ StrSplit(StringType&& text, Delimiter d, Predicate p) { std::move(text), DelimiterType(d), std::move(p)); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_STR_SPLIT_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.cc index 9893c7ab99..149897e3e0 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.cc @@ -24,7 +24,7 @@ #include "y_absl/strings/internal/memutil.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { void WritePadding(std::ostream& o, size_t pad) { @@ -224,7 +224,7 @@ constexpr string_view::size_type string_view::npos; ABSL_STRING_VIEW_SELECTANY constexpr string_view::size_type string_view::kMaxSize; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_USES_STD_STRING_VIEW diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.h index c3906fe1c5..a7879f4d38 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.h @@ -28,29 +28,29 @@ #define ABSL_STRINGS_STRING_VIEW_H_ #include <algorithm> -#include <cassert> -#include <cstddef> -#include <cstring> -#include <iosfwd> -#include <iterator> -#include <limits> -#include <util/generic/string.h> - +#include <cassert> +#include <cstddef> +#include <cstring> +#include <iosfwd> +#include <iterator> +#include <limits> +#include <util/generic/string.h> + #include "y_absl/base/attributes.h" #include "y_absl/base/config.h" -#include "y_absl/base/internal/throw_delegate.h" -#include "y_absl/base/macros.h" -#include "y_absl/base/optimization.h" -#include "y_absl/base/port.h" +#include "y_absl/base/internal/throw_delegate.h" +#include "y_absl/base/macros.h" +#include "y_absl/base/optimization.h" +#include "y_absl/base/port.h" #ifdef ABSL_USES_STD_STRING_VIEW #include <string_view> // IWYU pragma: export namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN using string_view = std::string_view; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #else // ABSL_USES_STD_STRING_VIEW @@ -71,7 +71,7 @@ ABSL_NAMESPACE_END #endif namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // y_absl::string_view // @@ -125,17 +125,17 @@ ABSL_NAMESPACE_BEGIN // provides string_view objects that point to the successive pieces of a Cord // object. // -// When constructed from a source which is NUL-terminated, the `string_view` -// itself will not include the NUL-terminator unless a specific size (including -// the NUL) is passed to the constructor. As a result, common idioms that work -// on NUL-terminated strings do not work on `string_view` objects. If you write +// When constructed from a source which is NUL-terminated, the `string_view` +// itself will not include the NUL-terminator unless a specific size (including +// the NUL) is passed to the constructor. As a result, common idioms that work +// on NUL-terminated strings do not work on `string_view` objects. If you write // code that scans a `string_view`, you must check its length rather than test // for nul, for example. Note, however, that nuls may still be embedded within // a `string_view` explicitly. // // You may create a null `string_view` in two ways: // -// y_absl::string_view sv; +// y_absl::string_view sv; // y_absl::string_view sv(nullptr, 0); // // For the above, `sv.data() == nullptr`, `sv.length() == 0`, and @@ -197,7 +197,7 @@ class string_view { // code bloat. : string_view(str.data(), str.size(), SkipCheckLengthTag{}) {} - // Implicit constructor of a `string_view` from NUL-terminated `str`. When + // Implicit constructor of a `string_view` from NUL-terminated `str`. When // accepting possibly null strings, use `y_absl::NullSafeStringView(str)` // instead (see below). // The length check is skipped since it is unnecessary and causes code bloat. @@ -296,9 +296,9 @@ class string_view { // // Returns the ith element of the `string_view` using the array operator. // Note that this operator does not perform any bounds checking. - constexpr const_reference operator[](size_type i) const { + constexpr const_reference operator[](size_type i) const { return ABSL_HARDENING_ASSERT(i < size()), ptr_[i]; - } + } // string_view::at() // @@ -316,23 +316,23 @@ class string_view { // string_view::front() // // Returns the first element of a `string_view`. - constexpr const_reference front() const { + constexpr const_reference front() const { return ABSL_HARDENING_ASSERT(!empty()), ptr_[0]; - } + } // string_view::back() // // Returns the last element of a `string_view`. - constexpr const_reference back() const { + constexpr const_reference back() const { return ABSL_HARDENING_ASSERT(!empty()), ptr_[size() - 1]; - } + } // string_view::data() // // Returns a pointer to the underlying character array (which is of course // stored elsewhere). Note that `string_view::data()` may contain embedded nul - // characters, but the returned buffer may or may not be NUL-terminated; - // therefore, do not pass `data()` to a routine that expects a NUL-terminated + // characters, but the returned buffer may or may not be NUL-terminated; + // therefore, do not pass `data()` to a routine that expects a NUL-terminated // string. constexpr const_pointer data() const noexcept { return ptr_; } @@ -412,11 +412,11 @@ class string_view { // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this` // is greater than `x`. constexpr int compare(string_view x) const noexcept { - return CompareImpl(length_, x.length_, - Min(length_, x.length_) == 0 - ? 0 - : ABSL_INTERNAL_STRING_VIEW_MEMCMP( - ptr_, x.ptr_, Min(length_, x.length_))); + return CompareImpl(length_, x.length_, + Min(length_, x.length_) == 0 + ? 0 + : ABSL_INTERNAL_STRING_VIEW_MEMCMP( + ptr_, x.ptr_, Min(length_, x.length_))); } // Overload of `string_view::compare()` for comparing a substring of the @@ -629,15 +629,15 @@ class string_view { #endif } - static constexpr size_t Min(size_type length_a, size_type length_b) { - return length_a < length_b ? length_a : length_b; - } - + static constexpr size_t Min(size_type length_a, size_type length_b) { + return length_a < length_b ? length_a : length_b; + } + static constexpr int CompareImpl(size_type length_a, size_type length_b, int compare_result) { return compare_result == 0 ? static_cast<int>(length_a > length_b) - static_cast<int>(length_a < length_b) - : (compare_result < 0 ? -1 : 1); + : (compare_result < 0 ? -1 : 1); } const char* ptr_; @@ -676,7 +676,7 @@ constexpr bool operator>=(string_view x, string_view y) noexcept { // IO Insertion Operator std::ostream& operator<<(std::ostream& o, string_view piece); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR @@ -685,7 +685,7 @@ ABSL_NAMESPACE_END #endif // ABSL_USES_STD_STRING_VIEW namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ClippedSubstr() // @@ -702,11 +702,11 @@ inline string_view ClippedSubstr(string_view s, size_t pos, // Creates an `y_absl::string_view` from a pointer `p` even if it's null-valued. // This function should be used where an `y_absl::string_view` can be created from // a possibly-null pointer. -constexpr string_view NullSafeStringView(const char* p) { +constexpr string_view NullSafeStringView(const char* p) { return p ? string_view(p) : string_view(); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_STRING_VIEW_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/strip.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/strip.h index 3164ff1ebc..204acb75df 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/strip.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/strip.h @@ -22,7 +22,7 @@ #define ABSL_STRINGS_STRIP_H_ #include <cstddef> -#include <util/generic/string.h> +#include <util/generic/string.h> #include "y_absl/base/macros.h" #include "y_absl/strings/ascii.h" @@ -30,7 +30,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ConsumePrefix() // @@ -85,7 +85,7 @@ ABSL_MUST_USE_RESULT inline y_absl::string_view StripSuffix( return str; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_STRIP_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.cc index 177fba8cbe..e02e1a263e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.cc @@ -23,7 +23,7 @@ #include "y_absl/strings/string_view.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace substitute_internal { void SubstituteAndAppendArray(TString* output, y_absl::string_view format, @@ -168,5 +168,5 @@ Arg::Arg(Dec dec) { } } // namespace substitute_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.h index c31191fbda..d5ab12648e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.h @@ -71,7 +71,7 @@ #define ABSL_STRINGS_SUBSTITUTE_H_ #include <cstring> -#include <util/generic/string.h> +#include <util/generic/string.h> #include <type_traits> #include <vector> @@ -86,7 +86,7 @@ #include "y_absl/strings/strip.h" namespace y_absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace substitute_internal { // Arg @@ -194,12 +194,12 @@ void SubstituteAndAppendArray(TString* output, y_absl::string_view format, #if defined(ABSL_BAD_CALL_IF) constexpr int CalculateOneBit(const char* format) { - // Returns: - // * 2^N for '$N' when N is in [0-9] - // * 0 for correct '$' escaping: '$$'. - // * -1 otherwise. - return (*format < '0' || *format > '9') ? (*format == '$' ? 0 : -1) - : (1 << (*format - '0')); + // Returns: + // * 2^N for '$N' when N is in [0-9] + // * 0 for correct '$' escaping: '$$'. + // * -1 otherwise. + return (*format < '0' || *format > '9') ? (*format == '$' ? 0 : -1) + : (1 << (*format - '0')); } constexpr const char* SkipNumber(const char* format) { @@ -717,7 +717,7 @@ TString Substitute( "contains an unescaped $ character (use $$ instead)"); #endif // ABSL_BAD_CALL_IF -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace y_absl #endif // ABSL_STRINGS_SUBSTITUTE_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ya.make index 77c5a47dc9..e855cade20 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ya.make @@ -21,9 +21,9 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal ) -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp-tstring -) +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp-tstring +) NO_COMPILER_WARNINGS() |