Go to the documentation of this file.
61 #ifndef ABSL_STRINGS_CORD_H_
62 #define ABSL_STRINGS_CORD_H_
71 #include <type_traits>
73 #include "absl/base/attributes.h"
74 #include "absl/base/config.h"
75 #include "absl/base/internal/endian.h"
76 #include "absl/base/internal/per_thread_tls.h"
77 #include "absl/base/macros.h"
78 #include "absl/base/port.h"
79 #include "absl/container/inlined_vector.h"
80 #include "absl/functional/function_ref.h"
81 #include "absl/meta/type_traits.h"
85 #include "absl/strings/internal/cord_internal.h"
89 #include "absl/strings/internal/cord_rep_ring.h"
90 #include "absl/strings/internal/cordz_functions.h"
91 #include "absl/strings/internal/cordz_info.h"
92 #include "absl/strings/internal/cordz_statistics.h"
93 #include "absl/strings/internal/cordz_update_scope.h"
94 #include "absl/strings/internal/cordz_update_tracker.h"
95 #include "absl/strings/internal/resize_uninitialized.h"
96 #include "absl/strings/internal/string_constant.h"
97 #include "absl/strings/string_view.h"
98 #include "absl/types/optional.h"
104 template <
typename Releaser>
152 template <
typename T>
160 constexpr
Cord() noexcept;
179 explicit
Cord(
T&& src);
181 Cord& operator=(
T&& src);
229 template <
typename Releaser>
245 template <
typename T, EnableIfString<T> = 0>
293 template <
typename T, EnableIfString<T> = 0>
743 template <
typename H>
747 return H::combine(
std::move(hash_state), *maybe_flat);
749 return c.HashFragmented(
std::move(hash_state));
757 template <
typename T>
810 const char*
data()
const;
864 template <
bool has_length>
876 memcpy(&
x,
reinterpret_cast<const char*
>(&
data_) + 8,
sizeof(
x));
877 memcpy(&
y,
reinterpret_cast<const char*
>(&other.
data_) + 8,
sizeof(
y));
878 if (
x ==
y)
return 0;
880 return absl::big_endian::FromHost64(
x) < absl::big_endian::FromHost64(
y)
954 size_t size_to_compare)
const;
956 size_t size_to_compare)
const;
961 template <
typename ResultType,
typename RHS>
963 size_t size_to_compare);
996 typename H::AbslInternalPiecewiseCombiner combiner;
998 hash_state = combiner.add_buffer(
std::move(hash_state), chunk.
data(),
1001 return H::combine(combiner.finalize(
std::move(hash_state)),
size());
1012 extern std::ostream&
operator<<(std::ostream&
out,
const Cord& cord);
1017 namespace cord_internal {
1022 template <
bool nullify_tail = false>
1035 }
else if (
n >= 4) {
1049 dst[
n / 2] = src[
n / 2];
1050 dst[
n - 1] = src[
n - 1];
1065 template <
typename Releaser>
1068 assert(!
data.empty());
1071 std::forward<Releaser>(releaser), 0);
1086 template <
typename Releaser>
1091 data, std::forward<Releaser>(releaser)),
1092 Cord::MethodIdentifier::kMakeCordFromExternal);
1123 if (!is_tree() && !src.
is_tree()) {
1149 return is_tree() ? nullptr :
data_.as_chars();
1153 assert(!
data_.is_tree());
1154 return data_.as_chars();
1158 assert(
data_.is_tree());
1159 return data_.as_tree();
1173 return is_tree() ? as_tree()->length : inline_size();
1202 assert(
data_.is_tree());
1209 assert(
data_.is_tree());
1222 SetTree(
rep, scope);
1239 size_t n = inline_size();
1249 template <
typename T>
1254 strings_internal::StringConstant<
T>::
value)
1256 &cord_internal::ConstInitExternalStorage<
1257 strings_internal::StringConstant<
T>>::
value)) {}
1264 template <
typename T, Cord::EnableIfString<T>>
1310 if (
rep ==
nullptr) {
1317 return absl::nullopt;
1322 if (
rep ==
nullptr) {
1327 return already_flat_contents;
1380 size_t rhs_size = rhs.
size();
1381 if (
size() < rhs_size)
return false;
1386 size_t rhs_size = rhs.
size();
1387 if (
size() < rhs_size)
return false;
1402 bytes_remaining_ = tree->
length;
1408 bytes_remaining_ = tree->length;
1412 current_chunk_ = {cord->
contents_.
data(), bytes_remaining_};
1417 current_chunk_ = btree_reader_.Next();
1422 assert(
n >= current_chunk_.size());
1423 bytes_remaining_ -=
n;
1424 if (bytes_remaining_) {
1425 if (
n == current_chunk_.size()) {
1426 current_chunk_ = btree_reader_.Next();
1428 size_t offset = btree_reader_.length() - bytes_remaining_;
1429 current_chunk_ = btree_reader_.Seek(
offset);
1432 current_chunk_ = {};
1438 "Attempted to iterate past `end()`");
1439 assert(bytes_remaining_ >= current_chunk_.size());
1440 bytes_remaining_ -= current_chunk_.size();
1441 if (bytes_remaining_ > 0) {
1442 if (btree_reader_) {
1443 return AdvanceBtree();
1445 assert(!current_chunk_.empty());
1447 current_chunk_ = {};
1463 return !(*
this == other);
1468 return current_chunk_;
1473 return ¤t_chunk_;
1477 assert(
n < current_chunk_.size());
1478 current_chunk_.remove_prefix(
n);
1479 bytes_remaining_ -=
n;
1483 assert(bytes_remaining_ >=
n);
1485 RemoveChunkPrefix(
n);
1486 }
else if (
n != 0) {
1487 if (btree_reader_) {
1488 AdvanceBytesBtree(
n);
1490 bytes_remaining_ = 0;
1502 return cord_->chunk_begin();
1506 return cord_->chunk_end();
1513 chunk_iterator_.RemoveChunkPrefix(1);
1531 return !(*
this == other);
1535 return *chunk_iterator_->data();
1539 return chunk_iterator_->data();
1543 assert(
it !=
nullptr);
1544 return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes);
1548 assert(
it !=
nullptr);
1549 it->chunk_iterator_.AdvanceBytes(n_bytes);
1553 return *
it.chunk_iterator_;
1563 return cord_->char_begin();
1567 return cord_->char_end();
1575 if (
rep ==
nullptr) {
1585 size_t rhs_size = rhs.
size();
1586 if (lhs.
size() != rhs_size)
return false;
1594 return x.Compare(
y) <= 0;
1597 return x.Compare(
y) >= 0;
1605 size_t lhs_size = lhs.
size();
1606 size_t rhs_size = rhs.
size();
1607 if (lhs_size != rhs_size)
return false;
1615 return x.Compare(
y) < 0;
1618 return y.Compare(
x) > 0;
1628 namespace strings_internal {
1631 static size_t FlatOverhead();
1632 static size_t MaxFlatLength();
1633 static size_t SizeofCordRepExternal();
1634 static size_t SizeofCordRepSubstring();
1636 static uint8_t LengthToTag(
size_t s);
1642 #endif // ABSL_STRINGS_CORD_H_
#define ABSL_PREDICT_FALSE(x)
absl::string_view Init(CordRepBtree *tree)
typename std::decay< T >::type decay_t
reference operator*() const
cord_internal::InlineData data_
void set_cordz_info(CordzInfo *cordz_info)
void reduce_size(size_t n)
absl::enable_if_t< std::is_same< T, std::string >::value, int > EnableIfString
void swap(Cord &other) noexcept
friend Cord MakeCordFromExternal(absl::string_view data, Releaser &&releaser)
absl::string_view FindFlatStartPiece() const
return memset(p, 0, total)
absl::string_view EdgeData(const CordRep *edge)
Cord & operator=(const Cord &x)
static absl::string_view ChunkRemaining(const CharIterator &it)
static CordRepFlat * New(size_t len)
ABSL_NAMESPACE_BEGIN std::ostream & operator<<(std::ostream &os, absl::LogSeverity s)
void Swap(InlineRep *rhs)
CharIterator(const Cord *cord)
void PrependArray(absl::string_view src, MethodIdentifier method)
const char * data() const
int Compare(absl::string_view rhs) const
absl::string_view FlattenSlowPath()
void InitTree(cord_internal::CordRep *tree)
CordBuffer GetAppendBuffer(size_t capacity, size_t min_capacity=16)
Cord MakeCordFromExternal(absl::string_view, Releaser &&)
void PrependTreeToInlined(CordRep *tree, MethodIdentifier method)
ChunkIterator end() const
static constexpr unsigned char kMaxInline
static void Advance(CharIterator *it, size_t n_bytes)
CharIterator char_begin() const
bool StartsWith(const Cord &rhs) const
pointer operator->() const
void set_inline_size(size_t size)
CordBuffer GetAppendBufferSlowPath(size_t capacity, size_t min_capacity)
typename std::enable_if< B, T >::type enable_if_t
std::input_iterator_tag iterator_category
absl::optional< absl::string_view > TryFlat() const
#define ABSL_NAMESPACE_END
bool operator>(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
int BitwiseCompare(const InlineRep &other) const
void InitializeCordRepExternal(absl::string_view data, CordRepExternal *rep)
#define ABSL_HARDENING_ASSERT(expr)
#define T(upbtypeconst, upbtype, ctype, default_value)
bool operator==(const CharIterator &other) const
void RemoveSuffix(size_t n)
ChunkIterator chunk_iterator_
void set_inline_size(size_t size)
void AdvanceBytes(size_t n)
absl::cord_internal::CordRep * clear()
void AppendTreeToInlined(CordRep *tree, MethodIdentifier method)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
absl::cord_internal::CordRep * as_tree() const
#define ABSL_NAMESPACE_BEGIN
ChunkRange Chunks() const
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
char operator[](size_t i) const
absl::optional< uint32_t > ExpectedChecksum() const
friend void swap(Cord &x, Cord &y) noexcept
ptrdiff_t difference_type
void PrependPrecise(absl::string_view src, MethodIdentifier method)
constexpr size_type size() const noexcept
void SetCordRep(CordRep *rep) const
constexpr bool has_value() const noexcept
static void * tag(intptr_t t)
bool IsSame(const InlineRep &other) const
void set_data(const char *data, size_t n)
static bool GetFlatAux(absl::cord_internal::CordRep *rep, absl::string_view *fragment)
void CopyTo(std::string *dst) const
static void MaybeUntrackCord(CordzInfo *info)
size_t EstimatedMemoryUsage() const
ChunkIterator begin() const
absl::cord_internal::CordRep * current_leaf_
void InvokeReleaser(Rank0, Releaser &&releaser, absl::string_view data)
unsigned __int64 uint64_t
size_t remaining_inline_capacity() const
friend void AbslFormatFlush(absl::Cord *cord, absl::string_view part)
void AssignSlow(const InlineRep &src)
void Prepend(const Cord &src)
void AppendArray(absl::string_view src, MethodIdentifier method)
void AdvanceBytesBtree(size_t n)
ABSL_ATTRIBUTE_REINITIALIZES void Clear()
bool EqualsImpl(absl::string_view rhs, size_t size_to_compare) const
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
size_t GetEstimatedFairShareMemoryUsage(const CordRep *rep)
absl::cord_internal::CordRep * TakeRep() const &
void CopyToArray(char *dst) const
void AppendPrecise(absl::string_view src, MethodIdentifier method)
static void callback(void *arg, int status, int timeouts, struct hostent *host)
static absl::string_view GetFirstChunk(const Cord &c)
std::input_iterator_tag iterator_category
int CompareSlowPath(absl::string_view rhs, size_t compared_size, size_t size_to_compare) const
bool operator!=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
void RemovePrefix(size_t n)
#define ABSL_PREDICT_TRUE(x)
static void operator++(Engine &e, int unused)
const value_type & const_reference
int CompareImpl(const Cord &rhs) const
void RemoveChunkPrefix(size_t n)
pointer operator->() const
InlineRep(InlineData::DefaultInitType init)
Cord Subcord(size_t pos, size_t new_size) const
void PrependTree(CordRep *tree, MethodIdentifier method)
ChunkIterator & AdvanceBtree()
CordRep * NewExternalRep(absl::string_view data, Releaser &&releaser)
CharIterator char_end() const
static CordBuffer CreateWithDefaultLimit(size_t capacity)
Cord AdvanceAndReadBytes(size_t n)
void SetExpectedChecksum(uint32_t crc)
static void MaybeTrackCord(InlineData &cord, MethodIdentifier method)
absl::cord_internal::CordzInfo * cordz_info() const
absl::string_view value_type
void SmallMemmove(char *dst, const char *src, size_t n)
bool operator>=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
bool operator!=(const ChunkIterator &other) const
static void ForEachChunkAux(absl::cord_internal::CordRep *rep, absl::FunctionRef< void(absl::string_view)> callback)
absl::cord_internal::CordRep * tree() const
void STLStringResizeUninitialized(string_type *s, size_t new_size)
friend H AbslHashValue(H hash_state, const absl::Cord &c)
void CopyCordToString(const Cord &src, std::string *dst)
bool operator<=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
InlineRep & operator=(const InlineRep &src)
reference operator*() const
Cord & AssignLargeString(std::string &&src)
void GetAppendRegion(char **region, size_t *size, size_t length)
CharIterator begin() const
absl::string_view current_chunk_
void CommitTree(const CordRep *old_rep, CordRep *rep, const CordzUpdateScope &scope, MethodIdentifier method)
friend ResultType GenericCompare(const Cord &lhs, const RHS &rhs, size_t size_to_compare)
ChunkIterator chunk_end() const
absl::string_view string_view
absl::string_view Flatten()
CordRepFlat * MakeFlatWithExtraCapacity(size_t extra)
ptrdiff_t difference_type
friend void CopyCordToString(const Cord &src, std::string *dst)
static CordRep * Ref(CordRep *rep)
size_t GetEstimatedMemoryUsage(const CordRep *rep)
void SetTreeOrEmpty(CordRep *rep, const CordzUpdateScope &scope)
ChunkIterator & operator++()
constexpr Cord() noexcept
CharRange(const Cord *cord)
CordzInfo * cordz_info() const
void PrependTreeToTree(CordRep *tree, MethodIdentifier method)
#define ABSL_ATTRIBUTE_REINITIALIZES
size_t inline_size() const
CordRepBtreeReader btree_reader_
H HashFragmented(H hash_state) const
static Cord AdvanceAndRead(CharIterator *it, size_t n_bytes)
void AppendTreeToTree(CordRep *tree, MethodIdentifier method)
bool operator!=(const CharIterator &other) const
void EmplaceTree(CordRep *rep, MethodIdentifier method)
void ForEachChunk(absl::FunctionRef< void(absl::string_view)>) const
const friend CordzInfo * GetCordzInfoForTesting(const Cord &cord)
bool operator==(const ChunkIterator &other) const
void set_cordz_info(cord_internal::CordzInfo *cordz_info)
ChunkRange(const Cord *cord)
void AppendTree(CordRep *tree, MethodIdentifier method)
static constexpr size_t kMinFlatLength
bool operator<(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
ChunkIterator chunk_begin() const
void CopyToArraySlowPath(char *dst) const
void SetTree(CordRep *rep, const CordzUpdateScope &scope)
CordRep * SkipCrcNode(CordRep *rep)
size_t inline_size() const
friend bool operator==(const Cord &lhs, const Cord &rhs)
bool EndsWith(absl::string_view rhs) const
constexpr const_pointer data() const noexcept
const char * as_chars() const
CharIterator & operator++()
void remove_prefix(size_t n)
void Append(const Cord &src)
grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:02