#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 "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/internal/invoke.h"
#include "absl/base/optimization.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/container/internal/container_memory.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/string_view.h"
#if defined(ABSL_HAVE_CONSTANT_EVALUATED) && \
(defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
defined(ABSL_HAVE_MEMORY_SANITIZER))
#define ABSL_INTERNAL_CORD_HAVE_SANITIZER …
#endif
#define ABSL_CORD_INTERNAL_NO_SANITIZE …
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
struct CordRep;
struct CordRepConcat;
struct CordRepExternal;
struct CordRepFlat;
struct CordRepSubstring;
struct CordRepCrc;
class CordRepBtree;
class CordzInfo;
enum CordFeatureDefaults { … };
extern std::atomic<bool> shallow_subcords_enabled;
inline void enable_shallow_subcords(bool enable) { … }
enum Constants { … };
[[noreturn]] void LogFatalNodeType(CordRep* rep);
template <bool nullify_tail = false>
inline void SmallMemmove(char* dst, const char* src, size_t n) { … }
class RefcountAndFlags { … };
enum CordRepKind { … };
static_assert …;
struct CordRep { … };
struct CordRepSubstring : public CordRep { … };
ExternalReleaserInvoker;
struct CordRepExternal : public CordRep { … };
struct Rank0 { … };
struct Rank1 : Rank0 { … };
template <typename Releaser, typename = ::absl::base_internal::invoke_result_t<
Releaser, absl::string_view>>
void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view data) { … }
template <typename Releaser,
typename = ::absl::base_internal::invoke_result_t<Releaser>>
void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view) { … }
template <typename Releaser>
struct CordRepExternalImpl
: public CordRepExternal,
public ::absl::container_internal::CompressedTuple<Releaser> { … };
inline CordRepSubstring* CordRepSubstring::Create(CordRep* child, size_t pos,
size_t n) { … }
inline CordRep* CordRepSubstring::Substring(CordRep* rep, size_t pos,
size_t n) { … }
inline void CordRepExternal::Delete(CordRep* rep) { … }
template <typename Str>
struct ConstInitExternalStorage { … };
template <typename Str>
ABSL_CONST_INIT CordRepExternal
ConstInitExternalStorage<Str>::value(Str::value);
enum { … };
constexpr char GetOrNull(absl::string_view data, size_t pos) { … }
cordz_info_t;
static_assert …;
static_assert …;
static constexpr cordz_info_t LittleEndianByte(unsigned char value) { … }
class InlineData { … };
static_assert …;
#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
constexpr InlineData::InlineData(const InlineData& rhs) noexcept
: rep_(rhs.rep_.SanitizerSafeCopy()) {
poison();
}
inline InlineData& InlineData::operator=(const InlineData& rhs) noexcept {
unpoison();
rep_ = rhs.rep_.SanitizerSafeCopy();
poison();
return *this;
}
constexpr void InlineData::poison_this() {
if (!absl::is_constant_evaluated()) {
container_internal::SanitizerPoisonObject(this);
}
}
constexpr void InlineData::unpoison() {
if (!absl::is_constant_evaluated()) {
container_internal::SanitizerUnpoisonObject(this);
}
}
constexpr void InlineData::poison() {
if (!absl::is_constant_evaluated()) {
if (is_tree()) {
container_internal::SanitizerUnpoisonObject(this);
} else if (const size_t size = inline_size()) {
if (size < kMaxInline) {
const char* end = rep_.as_chars() + size;
container_internal::SanitizerPoisonMemoryRegion(end, kMaxInline - size);
}
} else {
container_internal::SanitizerPoisonObject(this);
}
}
}
#else
constexpr InlineData::InlineData(const InlineData&) noexcept = default;
inline InlineData& InlineData::operator=(const InlineData&) noexcept = default;
constexpr void InlineData::poison_this() { … }
constexpr void InlineData::unpoison() { … }
constexpr void InlineData::poison() { … }
#endif
inline CordRepSubstring* CordRep::substring() { … }
inline const CordRepSubstring* CordRep::substring() const { … }
inline CordRepExternal* CordRep::external() { … }
inline const CordRepExternal* CordRep::external() const { … }
inline CordRep* CordRep::Ref(CordRep* rep) { … }
inline void CordRep::Unref(CordRep* rep) { … }
inline void swap(InlineData& lhs, InlineData& rhs) noexcept { … }
}
ABSL_NAMESPACE_END
}
#endif