diff options
author | Abseil Team <absl-team@google.com> | 2022-02-23 06:56:15 -0800 |
---|---|---|
committer | rogeeff <rogeeff@google.com> | 2022-02-23 10:24:01 -0500 |
commit | 0ad7994f10624cd1538b1287e56cae5ac9c0cb40 (patch) | |
tree | 2b8d698744e29cacfa524aee77930f69a27794e3 /absl/strings/internal/cord_internal.h | |
parent | 808bc202fc13e85a7948db0d7fb58f0f051200b1 (diff) |
Export of internal Abseil changes
--
91d76b3ac9edff91f206d9eee60423c39eeeaf93 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 430442277
--
9f8a87bcc5cc5b0fd8b7f0318f37d152fd8bea06 by Evan Brown <ezb@google.com>:
Small refactoring to work towards allowing for node_btree_* containers.
- Change common_params::transfer to rely on slot_policy transfer instead of manually doing construct/destruct. Transfer is not construct/destruct for node containers.
- Move maps' value_compare into btree.h from btree_map.h so it can be reused for node_btree_map.h.
- Also add a test for maps' value_compare protected members.
PiperOrigin-RevId: 430245542
--
0126e0b6295342317d9c9f0a66e2d7009b858426 by Martijn Vels <mvels@google.com>:
Add CordRepSubString::Create function with hard checks on IsFlat() | IsExternal()
This hardens internal invariants, IsFlat() || IsExternal() is a cheap, single predicted branch, and removes boilerplate code from cord.cc
PiperOrigin-RevId: 429676041
--
ed98a92af49d9e238d9f1d1b69fb4eddcd1ccbc7 by Abseil Team <absl-team@google.com>:
tweaks to status.h documentation to reflect general-purpose communication
PiperOrigin-RevId: 429584104
GitOrigin-RevId: 91d76b3ac9edff91f206d9eee60423c39eeeaf93
Change-Id: I54d6d116a564f86a842b983ca76559bf9b388f72
Diffstat (limited to 'absl/strings/internal/cord_internal.h')
-rw-r--r-- | absl/strings/internal/cord_internal.h | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index 8db6aa6d..ece3db15 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -21,6 +21,7 @@ #include <cstdint> #include <type_traits> +#include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/internal/endian.h" #include "absl/base/internal/invoke.h" @@ -33,6 +34,19 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace cord_internal { +// 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 CordRep; +struct CordRepConcat; +struct CordRepExternal; +struct CordRepFlat; +struct CordRepSubstring; +struct CordRepCrc; +class CordRepRing; +class CordRepBtree; + class CordzInfo; // Default feature enable states for cord ring buffers @@ -74,6 +88,9 @@ enum Constants { kMaxBytesToCopy = 511 }; +// Emits a fatal error "Unexpected node type: xyz" and aborts the program. +ABSL_ATTRIBUTE_NORETURN void LogFatalNodeType(CordRep* rep); + // 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 { @@ -156,19 +173,6 @@ class RefcountAndFlags { 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 CordRepCrc; -class CordRepRing; -class CordRepBtree; - // Various representations that we allow enum CordRepKind { UNUSED_0 = 0, @@ -276,6 +280,12 @@ struct CordRep { struct CordRepSubstring : public CordRep { size_t start; // Starting offset of substring in child CordRep* child; + + // Creates a substring on `child`, adopting a reference on `child`. + // Requires `child` to be either a flat or external node, and `pos` and `n` to + // form a non-empty partial sub range of `'child`, i.e.: + // `n > 0 && n < length && n + pos <= length` + static inline CordRepSubstring* Create(CordRep* child, size_t pos, size_t n); }; // Type for function pointer that will invoke the releaser function and also @@ -339,6 +349,28 @@ struct CordRepExternalImpl } }; +inline CordRepSubstring* CordRepSubstring::Create(CordRep* child, size_t pos, + size_t n) { + assert(child != nullptr); + assert(n > 0); + assert(n < child->length); + assert(pos < child->length); + assert(n <= child->length - pos); + + // TODO(b/217376272): Harden internal logic. + // Move to strategical places inside the Cord logic and make this an assert. + if (ABSL_PREDICT_FALSE(!(child->IsExternal() || child->IsFlat()))) { + LogFatalNodeType(child); + } + + CordRepSubstring* rep = new CordRepSubstring(); + rep->length = n; + rep->tag = SUBSTRING; + rep->start = pos; + rep->child = child; + return rep; +} + inline void CordRepExternal::Delete(CordRep* rep) { assert(rep != nullptr && rep->IsExternal()); auto* rep_external = static_cast<CordRepExternal*>(rep); |