cord.h 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521
  1. // Copyright 2020 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // -----------------------------------------------------------------------------
  16. // File: cord.h
  17. // -----------------------------------------------------------------------------
  18. //
  19. // This file defines the `absl::Cord` data structure and operations on that data
  20. // structure. A Cord is a string-like sequence of characters optimized for
  21. // specific use cases. Unlike a `std::string`, which stores an array of
  22. // contiguous characters, Cord data is stored in a structure consisting of
  23. // separate, reference-counted "chunks." (Currently, this implementation is a
  24. // tree structure, though that implementation may change.)
  25. //
  26. // Because a Cord consists of these chunks, data can be added to or removed from
  27. // a Cord during its lifetime. Chunks may also be shared between Cords. Unlike a
  28. // `std::string`, a Cord can therefore accommodate data that changes over its
  29. // lifetime, though it's not quite "mutable"; it can change only in the
  30. // attachment, detachment, or rearrangement of chunks of its constituent data.
  31. //
  32. // A Cord provides some benefit over `std::string` under the following (albeit
  33. // narrow) circumstances:
  34. //
  35. // * Cord data is designed to grow and shrink over a Cord's lifetime. Cord
  36. // provides efficient insertions and deletions at the start and end of the
  37. // character sequences, avoiding copies in those cases. Static data should
  38. // generally be stored as strings.
  39. // * External memory consisting of string-like data can be directly added to
  40. // a Cord without requiring copies or allocations.
  41. // * Cord data may be shared and copied cheaply. Cord provides a copy-on-write
  42. // implementation and cheap sub-Cord operations. Copying a Cord is an O(1)
  43. // operation.
  44. //
  45. // As a consequence to the above, Cord data is generally large. Small data
  46. // should generally use strings, as construction of a Cord requires some
  47. // overhead. Small Cords (<= 15 bytes) are represented inline, but most small
  48. // Cords are expected to grow over their lifetimes.
  49. //
  50. // Note that because a Cord is made up of separate chunked data, random access
  51. // to character data within a Cord is slower than within a `std::string`.
  52. //
  53. // Thread Safety
  54. //
  55. // Cord has the same thread-safety properties as many other types like
  56. // std::string, std::vector<>, int, etc -- it is thread-compatible. In
  57. // particular, if threads do not call non-const methods, then it is safe to call
  58. // const methods without synchronization. Copying a Cord produces a new instance
  59. // that can be used concurrently with the original in arbitrary ways.
  60. #ifndef ABSL_STRINGS_CORD_H_
  61. #define ABSL_STRINGS_CORD_H_
  62. #include <algorithm>
  63. #include <cstddef>
  64. #include <cstdint>
  65. #include <cstring>
  66. #include <iosfwd>
  67. #include <iterator>
  68. #include <string>
  69. #include <type_traits>
  70. #include "absl/base/config.h"
  71. #include "absl/base/internal/endian.h"
  72. #include "absl/base/internal/per_thread_tls.h"
  73. #include "absl/base/macros.h"
  74. #include "absl/base/port.h"
  75. #include "absl/container/inlined_vector.h"
  76. #include "absl/functional/function_ref.h"
  77. #include "absl/meta/type_traits.h"
  78. #include "absl/strings/internal/cord_internal.h"
  79. #include "absl/strings/internal/cord_rep_btree.h"
  80. #include "absl/strings/internal/cord_rep_btree_reader.h"
  81. #include "absl/strings/internal/cord_rep_ring.h"
  82. #include "absl/strings/internal/cordz_functions.h"
  83. #include "absl/strings/internal/cordz_info.h"
  84. #include "absl/strings/internal/cordz_statistics.h"
  85. #include "absl/strings/internal/cordz_update_scope.h"
  86. #include "absl/strings/internal/cordz_update_tracker.h"
  87. #include "absl/strings/internal/resize_uninitialized.h"
  88. #include "absl/strings/internal/string_constant.h"
  89. #include "absl/strings/string_view.h"
  90. #include "absl/types/optional.h"
  91. namespace absl {
  92. ABSL_NAMESPACE_BEGIN
  93. class Cord;
  94. class CordTestPeer;
  95. template <typename Releaser>
  96. Cord MakeCordFromExternal(absl::string_view, Releaser&&);
  97. void CopyCordToString(const Cord& src, std::string* dst);
  98. // Cord
  99. //
  100. // A Cord is a sequence of characters, designed to be more efficient than a
  101. // `std::string` in certain circumstances: namely, large string data that needs
  102. // to change over its lifetime or shared, especially when such data is shared
  103. // across API boundaries.
  104. //
  105. // A Cord stores its character data in a structure that allows efficient prepend
  106. // and append operations. This makes a Cord useful for large string data sent
  107. // over in a wire format that may need to be prepended or appended at some point
  108. // during the data exchange (e.g. HTTP, protocol buffers). For example, a
  109. // Cord is useful for storing an HTTP request, and prepending an HTTP header to
  110. // such a request.
  111. //
  112. // Cords should not be used for storing general string data, however. They
  113. // require overhead to construct and are slower than strings for random access.
  114. //
  115. // The Cord API provides the following common API operations:
  116. //
  117. // * Create or assign Cords out of existing string data, memory, or other Cords
  118. // * Append and prepend data to an existing Cord
  119. // * Create new Sub-Cords from existing Cord data
  120. // * Swap Cord data and compare Cord equality
  121. // * Write out Cord data by constructing a `std::string`
  122. //
  123. // Additionally, the API provides iterator utilities to iterate through Cord
  124. // data via chunks or character bytes.
  125. //
  126. class Cord {
  127. private:
  128. template <typename T>
  129. using EnableIfString =
  130. absl::enable_if_t<std::is_same<T, std::string>::value, int>;
  131. public:
  132. // Cord::Cord() Constructors.
  133. // Creates an empty Cord.
  134. constexpr Cord() noexcept;
  135. // Creates a Cord from an existing Cord. Cord is copyable and efficiently
  136. // movable. The moved-from state is valid but unspecified.
  137. Cord(const Cord& src);
  138. Cord(Cord&& src) noexcept;
  139. Cord& operator=(const Cord& x);
  140. Cord& operator=(Cord&& x) noexcept;
  141. // Creates a Cord from a `src` string. This constructor is marked explicit to
  142. // prevent implicit Cord constructions from arguments convertible to an
  143. // `absl::string_view`.
  144. explicit Cord(absl::string_view src);
  145. Cord& operator=(absl::string_view src);
  146. // Creates a Cord from a `std::string&&` rvalue. These constructors are
  147. // templated to avoid ambiguities for types that are convertible to both
  148. // `absl::string_view` and `std::string`, such as `const char*`.
  149. template <typename T, EnableIfString<T> = 0>
  150. explicit Cord(T&& src);
  151. template <typename T, EnableIfString<T> = 0>
  152. Cord& operator=(T&& src);
  153. // Cord::~Cord()
  154. //
  155. // Destructs the Cord.
  156. ~Cord() {
  157. if (contents_.is_tree()) DestroyCordSlow();
  158. }
  159. // MakeCordFromExternal()
  160. //
  161. // Creates a Cord that takes ownership of external string memory. The
  162. // contents of `data` are not copied to the Cord; instead, the external
  163. // memory is added to the Cord and reference-counted. This data may not be
  164. // changed for the life of the Cord, though it may be prepended or appended
  165. // to.
  166. //
  167. // `MakeCordFromExternal()` takes a callable "releaser" that is invoked when
  168. // the reference count for `data` reaches zero. As noted above, this data must
  169. // remain live until the releaser is invoked. The callable releaser also must:
  170. //
  171. // * be move constructible
  172. // * support `void operator()(absl::string_view) const` or `void operator()`
  173. //
  174. // Example:
  175. //
  176. // Cord MakeCord(BlockPool* pool) {
  177. // Block* block = pool->NewBlock();
  178. // FillBlock(block);
  179. // return absl::MakeCordFromExternal(
  180. // block->ToStringView(),
  181. // [pool, block](absl::string_view v) {
  182. // pool->FreeBlock(block, v);
  183. // });
  184. // }
  185. //
  186. // WARNING: Because a Cord can be reference-counted, it's likely a bug if your
  187. // releaser doesn't do anything. For example, consider the following:
  188. //
  189. // void Foo(const char* buffer, int len) {
  190. // auto c = absl::MakeCordFromExternal(absl::string_view(buffer, len),
  191. // [](absl::string_view) {});
  192. //
  193. // // BUG: If Bar() copies its cord for any reason, including keeping a
  194. // // substring of it, the lifetime of buffer might be extended beyond
  195. // // when Foo() returns.
  196. // Bar(c);
  197. // }
  198. template <typename Releaser>
  199. friend Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser);
  200. // Cord::Clear()
  201. //
  202. // Releases the Cord data. Any nodes that share data with other Cords, if
  203. // applicable, will have their reference counts reduced by 1.
  204. void Clear();
  205. // Cord::Append()
  206. //
  207. // Appends data to the Cord, which may come from another Cord or other string
  208. // data.
  209. void Append(const Cord& src);
  210. void Append(Cord&& src);
  211. void Append(absl::string_view src);
  212. template <typename T, EnableIfString<T> = 0>
  213. void Append(T&& src);
  214. // Cord::Prepend()
  215. //
  216. // Prepends data to the Cord, which may come from another Cord or other string
  217. // data.
  218. void Prepend(const Cord& src);
  219. void Prepend(absl::string_view src);
  220. template <typename T, EnableIfString<T> = 0>
  221. void Prepend(T&& src);
  222. // Cord::RemovePrefix()
  223. //
  224. // Removes the first `n` bytes of a Cord.
  225. void RemovePrefix(size_t n);
  226. void RemoveSuffix(size_t n);
  227. // Cord::Subcord()
  228. //
  229. // Returns a new Cord representing the subrange [pos, pos + new_size) of
  230. // *this. If pos >= size(), the result is empty(). If
  231. // (pos + new_size) >= size(), the result is the subrange [pos, size()).
  232. Cord Subcord(size_t pos, size_t new_size) const;
  233. // Cord::swap()
  234. //
  235. // Swaps the contents of the Cord with `other`.
  236. void swap(Cord& other) noexcept;
  237. // swap()
  238. //
  239. // Swaps the contents of two Cords.
  240. friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); }
  241. // Cord::size()
  242. //
  243. // Returns the size of the Cord.
  244. size_t size() const;
  245. // Cord::empty()
  246. //
  247. // Determines whether the given Cord is empty, returning `true` is so.
  248. bool empty() const;
  249. // Cord::EstimatedMemoryUsage()
  250. //
  251. // Returns the *approximate* number of bytes held in full or in part by this
  252. // Cord (which may not remain the same between invocations). Note that Cords
  253. // that share memory could each be "charged" independently for the same shared
  254. // memory.
  255. size_t EstimatedMemoryUsage() const;
  256. // Cord::Compare()
  257. //
  258. // Compares 'this' Cord with rhs. This function and its relatives treat Cords
  259. // as sequences of unsigned bytes. The comparison is a straightforward
  260. // lexicographic comparison. `Cord::Compare()` returns values as follows:
  261. //
  262. // -1 'this' Cord is smaller
  263. // 0 two Cords are equal
  264. // 1 'this' Cord is larger
  265. int Compare(absl::string_view rhs) const;
  266. int Compare(const Cord& rhs) const;
  267. // Cord::StartsWith()
  268. //
  269. // Determines whether the Cord starts with the passed string data `rhs`.
  270. bool StartsWith(const Cord& rhs) const;
  271. bool StartsWith(absl::string_view rhs) const;
  272. // Cord::EndsWith()
  273. //
  274. // Determines whether the Cord ends with the passed string data `rhs`.
  275. bool EndsWith(absl::string_view rhs) const;
  276. bool EndsWith(const Cord& rhs) const;
  277. // Cord::operator std::string()
  278. //
  279. // Converts a Cord into a `std::string()`. This operator is marked explicit to
  280. // prevent unintended Cord usage in functions that take a string.
  281. explicit operator std::string() const;
  282. // CopyCordToString()
  283. //
  284. // Copies the contents of a `src` Cord into a `*dst` string.
  285. //
  286. // This function optimizes the case of reusing the destination string since it
  287. // can reuse previously allocated capacity. However, this function does not
  288. // guarantee that pointers previously returned by `dst->data()` remain valid
  289. // even if `*dst` had enough capacity to hold `src`. If `*dst` is a new
  290. // object, prefer to simply use the conversion operator to `std::string`.
  291. friend void CopyCordToString(const Cord& src, std::string* dst);
  292. class CharIterator;
  293. //----------------------------------------------------------------------------
  294. // Cord::ChunkIterator
  295. //----------------------------------------------------------------------------
  296. //
  297. // A `Cord::ChunkIterator` allows iteration over the constituent chunks of its
  298. // Cord. Such iteration allows you to perform non-const operatons on the data
  299. // of a Cord without modifying it.
  300. //
  301. // Generally, you do not instantiate a `Cord::ChunkIterator` directly;
  302. // instead, you create one implicitly through use of the `Cord::Chunks()`
  303. // member function.
  304. //
  305. // The `Cord::ChunkIterator` has the following properties:
  306. //
  307. // * The iterator is invalidated after any non-const operation on the
  308. // Cord object over which it iterates.
  309. // * The `string_view` returned by dereferencing a valid, non-`end()`
  310. // iterator is guaranteed to be non-empty.
  311. // * Two `ChunkIterator` objects can be compared equal if and only if they
  312. // remain valid and iterate over the same Cord.
  313. // * The iterator in this case is a proxy iterator; the `string_view`
  314. // returned by the iterator does not live inside the Cord, and its
  315. // lifetime is limited to the lifetime of the iterator itself. To help
  316. // prevent lifetime issues, `ChunkIterator::reference` is not a true
  317. // reference type and is equivalent to `value_type`.
  318. // * The iterator keeps state that can grow for Cords that contain many
  319. // nodes and are imbalanced due to sharing. Prefer to pass this type by
  320. // const reference instead of by value.
  321. class ChunkIterator {
  322. public:
  323. using iterator_category = std::input_iterator_tag;
  324. using value_type = absl::string_view;
  325. using difference_type = ptrdiff_t;
  326. using pointer = const value_type*;
  327. using reference = value_type;
  328. ChunkIterator() = default;
  329. ChunkIterator& operator++();
  330. ChunkIterator operator++(int);
  331. bool operator==(const ChunkIterator& other) const;
  332. bool operator!=(const ChunkIterator& other) const;
  333. reference operator*() const;
  334. pointer operator->() const;
  335. friend class Cord;
  336. friend class CharIterator;
  337. private:
  338. using CordRep = absl::cord_internal::CordRep;
  339. using CordRepBtree = absl::cord_internal::CordRepBtree;
  340. using CordRepBtreeReader = absl::cord_internal::CordRepBtreeReader;
  341. // Stack of right children of concat nodes that we have to visit.
  342. // Keep this at the end of the structure to avoid cache-thrashing.
  343. // TODO(jgm): Benchmark to see if there's a more optimal value than 47 for
  344. // the inlined vector size (47 exists for backward compatibility).
  345. using Stack = absl::InlinedVector<absl::cord_internal::CordRep*, 47>;
  346. // Constructs a `begin()` iterator from `tree`. `tree` must not be null.
  347. explicit ChunkIterator(cord_internal::CordRep* tree);
  348. // Constructs a `begin()` iterator from `cord`.
  349. explicit ChunkIterator(const Cord* cord);
  350. // Initializes this instance from a tree. Invoked by constructors.
  351. void InitTree(cord_internal::CordRep* tree);
  352. // Removes `n` bytes from `current_chunk_`. Expects `n` to be smaller than
  353. // `current_chunk_.size()`.
  354. void RemoveChunkPrefix(size_t n);
  355. Cord AdvanceAndReadBytes(size_t n);
  356. void AdvanceBytes(size_t n);
  357. // Stack specific operator++
  358. ChunkIterator& AdvanceStack();
  359. // Btree specific operator++
  360. ChunkIterator& AdvanceBtree();
  361. void AdvanceBytesBtree(size_t n);
  362. // Iterates `n` bytes, where `n` is expected to be greater than or equal to
  363. // `current_chunk_.size()`.
  364. void AdvanceBytesSlowPath(size_t n);
  365. // A view into bytes of the current `CordRep`. It may only be a view to a
  366. // suffix of bytes if this is being used by `CharIterator`.
  367. absl::string_view current_chunk_;
  368. // The current leaf, or `nullptr` if the iterator points to short data.
  369. // If the current chunk is a substring node, current_leaf_ points to the
  370. // underlying flat or external node.
  371. absl::cord_internal::CordRep* current_leaf_ = nullptr;
  372. // The number of bytes left in the `Cord` over which we are iterating.
  373. size_t bytes_remaining_ = 0;
  374. // Cord reader for cord btrees. Empty if not traversing a btree.
  375. CordRepBtreeReader btree_reader_;
  376. // See 'Stack' alias definition.
  377. Stack stack_of_right_children_;
  378. };
  379. // Cord::ChunkIterator::chunk_begin()
  380. //
  381. // Returns an iterator to the first chunk of the `Cord`.
  382. //
  383. // Generally, prefer using `Cord::Chunks()` within a range-based for loop for
  384. // iterating over the chunks of a Cord. This method may be useful for getting
  385. // a `ChunkIterator` where range-based for-loops are not useful.
  386. //
  387. // Example:
  388. //
  389. // absl::Cord::ChunkIterator FindAsChunk(const absl::Cord& c,
  390. // absl::string_view s) {
  391. // return std::find(c.chunk_begin(), c.chunk_end(), s);
  392. // }
  393. ChunkIterator chunk_begin() const;
  394. // Cord::ChunkItertator::chunk_end()
  395. //
  396. // Returns an iterator one increment past the last chunk of the `Cord`.
  397. //
  398. // Generally, prefer using `Cord::Chunks()` within a range-based for loop for
  399. // iterating over the chunks of a Cord. This method may be useful for getting
  400. // a `ChunkIterator` where range-based for-loops may not be available.
  401. ChunkIterator chunk_end() const;
  402. //----------------------------------------------------------------------------
  403. // Cord::ChunkIterator::ChunkRange
  404. //----------------------------------------------------------------------------
  405. //
  406. // `ChunkRange` is a helper class for iterating over the chunks of the `Cord`,
  407. // producing an iterator which can be used within a range-based for loop.
  408. // Construction of a `ChunkRange` will return an iterator pointing to the
  409. // first chunk of the Cord. Generally, do not construct a `ChunkRange`
  410. // directly; instead, prefer to use the `Cord::Chunks()` method.
  411. //
  412. // Implementation note: `ChunkRange` is simply a convenience wrapper over
  413. // `Cord::chunk_begin()` and `Cord::chunk_end()`.
  414. class ChunkRange {
  415. public:
  416. // Fulfill minimum c++ container requirements [container.requirements]
  417. // Theses (partial) container type definitions allow ChunkRange to be used
  418. // in various utilities expecting a subset of [container.requirements].
  419. // For example, the below enables using `::testing::ElementsAre(...)`
  420. using value_type = absl::string_view;
  421. using reference = value_type&;
  422. using const_reference = const value_type&;
  423. using iterator = ChunkIterator;
  424. using const_iterator = ChunkIterator;
  425. explicit ChunkRange(const Cord* cord) : cord_(cord) {}
  426. ChunkIterator begin() const;
  427. ChunkIterator end() const;
  428. private:
  429. const Cord* cord_;
  430. };
  431. // Cord::Chunks()
  432. //
  433. // Returns a `Cord::ChunkIterator::ChunkRange` for iterating over the chunks
  434. // of a `Cord` with a range-based for-loop. For most iteration tasks on a
  435. // Cord, use `Cord::Chunks()` to retrieve this iterator.
  436. //
  437. // Example:
  438. //
  439. // void ProcessChunks(const Cord& cord) {
  440. // for (absl::string_view chunk : cord.Chunks()) { ... }
  441. // }
  442. //
  443. // Note that the ordinary caveats of temporary lifetime extension apply:
  444. //
  445. // void Process() {
  446. // for (absl::string_view chunk : CordFactory().Chunks()) {
  447. // // The temporary Cord returned by CordFactory has been destroyed!
  448. // }
  449. // }
  450. ChunkRange Chunks() const;
  451. //----------------------------------------------------------------------------
  452. // Cord::CharIterator
  453. //----------------------------------------------------------------------------
  454. //
  455. // A `Cord::CharIterator` allows iteration over the constituent characters of
  456. // a `Cord`.
  457. //
  458. // Generally, you do not instantiate a `Cord::CharIterator` directly; instead,
  459. // you create one implicitly through use of the `Cord::Chars()` member
  460. // function.
  461. //
  462. // A `Cord::CharIterator` has the following properties:
  463. //
  464. // * The iterator is invalidated after any non-const operation on the
  465. // Cord object over which it iterates.
  466. // * Two `CharIterator` objects can be compared equal if and only if they
  467. // remain valid and iterate over the same Cord.
  468. // * The iterator keeps state that can grow for Cords that contain many
  469. // nodes and are imbalanced due to sharing. Prefer to pass this type by
  470. // const reference instead of by value.
  471. // * This type cannot act as a forward iterator because a `Cord` can reuse
  472. // sections of memory. This fact violates the requirement for forward
  473. // iterators to compare equal if dereferencing them returns the same
  474. // object.
  475. class CharIterator {
  476. public:
  477. using iterator_category = std::input_iterator_tag;
  478. using value_type = char;
  479. using difference_type = ptrdiff_t;
  480. using pointer = const char*;
  481. using reference = const char&;
  482. CharIterator() = default;
  483. CharIterator& operator++();
  484. CharIterator operator++(int);
  485. bool operator==(const CharIterator& other) const;
  486. bool operator!=(const CharIterator& other) const;
  487. reference operator*() const;
  488. pointer operator->() const;
  489. friend Cord;
  490. private:
  491. explicit CharIterator(const Cord* cord) : chunk_iterator_(cord) {}
  492. ChunkIterator chunk_iterator_;
  493. };
  494. // Cord::CharIterator::AdvanceAndRead()
  495. //
  496. // Advances the `Cord::CharIterator` by `n_bytes` and returns the bytes
  497. // advanced as a separate `Cord`. `n_bytes` must be less than or equal to the
  498. // number of bytes within the Cord; otherwise, behavior is undefined. It is
  499. // valid to pass `char_end()` and `0`.
  500. static Cord AdvanceAndRead(CharIterator* it, size_t n_bytes);
  501. // Cord::CharIterator::Advance()
  502. //
  503. // Advances the `Cord::CharIterator` by `n_bytes`. `n_bytes` must be less than
  504. // or equal to the number of bytes remaining within the Cord; otherwise,
  505. // behavior is undefined. It is valid to pass `char_end()` and `0`.
  506. static void Advance(CharIterator* it, size_t n_bytes);
  507. // Cord::CharIterator::ChunkRemaining()
  508. //
  509. // Returns the longest contiguous view starting at the iterator's position.
  510. //
  511. // `it` must be dereferenceable.
  512. static absl::string_view ChunkRemaining(const CharIterator& it);
  513. // Cord::CharIterator::char_begin()
  514. //
  515. // Returns an iterator to the first character of the `Cord`.
  516. //
  517. // Generally, prefer using `Cord::Chars()` within a range-based for loop for
  518. // iterating over the chunks of a Cord. This method may be useful for getting
  519. // a `CharIterator` where range-based for-loops may not be available.
  520. CharIterator char_begin() const;
  521. // Cord::CharIterator::char_end()
  522. //
  523. // Returns an iterator to one past the last character of the `Cord`.
  524. //
  525. // Generally, prefer using `Cord::Chars()` within a range-based for loop for
  526. // iterating over the chunks of a Cord. This method may be useful for getting
  527. // a `CharIterator` where range-based for-loops are not useful.
  528. CharIterator char_end() const;
  529. // Cord::CharIterator::CharRange
  530. //
  531. // `CharRange` is a helper class for iterating over the characters of a
  532. // producing an iterator which can be used within a range-based for loop.
  533. // Construction of a `CharRange` will return an iterator pointing to the first
  534. // character of the Cord. Generally, do not construct a `CharRange` directly;
  535. // instead, prefer to use the `Cord::Chars()` method show below.
  536. //
  537. // Implementation note: `CharRange` is simply a convenience wrapper over
  538. // `Cord::char_begin()` and `Cord::char_end()`.
  539. class CharRange {
  540. public:
  541. // Fulfill minimum c++ container requirements [container.requirements]
  542. // Theses (partial) container type definitions allow CharRange to be used
  543. // in various utilities expecting a subset of [container.requirements].
  544. // For example, the below enables using `::testing::ElementsAre(...)`
  545. using value_type = char;
  546. using reference = value_type&;
  547. using const_reference = const value_type&;
  548. using iterator = CharIterator;
  549. using const_iterator = CharIterator;
  550. explicit CharRange(const Cord* cord) : cord_(cord) {}
  551. CharIterator begin() const;
  552. CharIterator end() const;
  553. private:
  554. const Cord* cord_;
  555. };
  556. // Cord::CharIterator::Chars()
  557. //
  558. // Returns a `Cord::CharIterator` for iterating over the characters of a
  559. // `Cord` with a range-based for-loop. For most character-based iteration
  560. // tasks on a Cord, use `Cord::Chars()` to retrieve this iterator.
  561. //
  562. // Example:
  563. //
  564. // void ProcessCord(const Cord& cord) {
  565. // for (char c : cord.Chars()) { ... }
  566. // }
  567. //
  568. // Note that the ordinary caveats of temporary lifetime extension apply:
  569. //
  570. // void Process() {
  571. // for (char c : CordFactory().Chars()) {
  572. // // The temporary Cord returned by CordFactory has been destroyed!
  573. // }
  574. // }
  575. CharRange Chars() const;
  576. // Cord::operator[]
  577. //
  578. // Gets the "i"th character of the Cord and returns it, provided that
  579. // 0 <= i < Cord.size().
  580. //
  581. // NOTE: This routine is reasonably efficient. It is roughly
  582. // logarithmic based on the number of chunks that make up the cord. Still,
  583. // if you need to iterate over the contents of a cord, you should
  584. // use a CharIterator/ChunkIterator rather than call operator[] or Get()
  585. // repeatedly in a loop.
  586. char operator[](size_t i) const;
  587. // Cord::TryFlat()
  588. //
  589. // If this cord's representation is a single flat array, returns a
  590. // string_view referencing that array. Otherwise returns nullopt.
  591. absl::optional<absl::string_view> TryFlat() const;
  592. // Cord::Flatten()
  593. //
  594. // Flattens the cord into a single array and returns a view of the data.
  595. //
  596. // If the cord was already flat, the contents are not modified.
  597. absl::string_view Flatten();
  598. // Supports absl::Cord as a sink object for absl::Format().
  599. friend void AbslFormatFlush(absl::Cord* cord, absl::string_view part) {
  600. cord->Append(part);
  601. }
  602. template <typename H>
  603. friend H AbslHashValue(H hash_state, const absl::Cord& c) {
  604. absl::optional<absl::string_view> maybe_flat = c.TryFlat();
  605. if (maybe_flat.has_value()) {
  606. return H::combine(std::move(hash_state), *maybe_flat);
  607. }
  608. return c.HashFragmented(std::move(hash_state));
  609. }
  610. // Create a Cord with the contents of StringConstant<T>::value.
  611. // No allocations will be done and no data will be copied.
  612. // This is an INTERNAL API and subject to change or removal. This API can only
  613. // be used by spelling absl::strings_internal::MakeStringConstant, which is
  614. // also an internal API.
  615. template <typename T>
  616. explicit constexpr Cord(strings_internal::StringConstant<T>);
  617. private:
  618. using CordRep = absl::cord_internal::CordRep;
  619. using CordRepFlat = absl::cord_internal::CordRepFlat;
  620. using CordzInfo = cord_internal::CordzInfo;
  621. using CordzUpdateScope = cord_internal::CordzUpdateScope;
  622. using CordzUpdateTracker = cord_internal::CordzUpdateTracker;
  623. using InlineData = cord_internal::InlineData;
  624. using MethodIdentifier = CordzUpdateTracker::MethodIdentifier;
  625. // Creates a cord instance with `method` representing the originating
  626. // public API call causing the cord to be created.
  627. explicit Cord(absl::string_view src, MethodIdentifier method);
  628. friend class CordTestPeer;
  629. friend bool operator==(const Cord& lhs, const Cord& rhs);
  630. friend bool operator==(const Cord& lhs, absl::string_view rhs);
  631. friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord);
  632. // Calls the provided function once for each cord chunk, in order. Unlike
  633. // Chunks(), this API will not allocate memory.
  634. void ForEachChunk(absl::FunctionRef<void(absl::string_view)>) const;
  635. // Allocates new contiguous storage for the contents of the cord. This is
  636. // called by Flatten() when the cord was not already flat.
  637. absl::string_view FlattenSlowPath();
  638. // Actual cord contents are hidden inside the following simple
  639. // class so that we can isolate the bulk of cord.cc from changes
  640. // to the representation.
  641. //
  642. // InlineRep holds either a tree pointer, or an array of kMaxInline bytes.
  643. class InlineRep {
  644. public:
  645. static constexpr unsigned char kMaxInline = cord_internal::kMaxInline;
  646. static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), "");
  647. constexpr InlineRep() : data_() {}
  648. explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {}
  649. InlineRep(const InlineRep& src);
  650. InlineRep(InlineRep&& src);
  651. InlineRep& operator=(const InlineRep& src);
  652. InlineRep& operator=(InlineRep&& src) noexcept;
  653. explicit constexpr InlineRep(cord_internal::InlineData data);
  654. void Swap(InlineRep* rhs);
  655. bool empty() const;
  656. size_t size() const;
  657. const char* data() const; // Returns nullptr if holding pointer
  658. void set_data(const char* data, size_t n,
  659. bool nullify_tail); // Discards pointer, if any
  660. char* set_data(size_t n); // Write data to the result
  661. // Returns nullptr if holding bytes
  662. absl::cord_internal::CordRep* tree() const;
  663. absl::cord_internal::CordRep* as_tree() const;
  664. // Returns non-null iff was holding a pointer
  665. absl::cord_internal::CordRep* clear();
  666. // Converts to pointer if necessary.
  667. void reduce_size(size_t n); // REQUIRES: holding data
  668. void remove_prefix(size_t n); // REQUIRES: holding data
  669. void AppendArray(absl::string_view src, MethodIdentifier method);
  670. absl::string_view FindFlatStartPiece() const;
  671. // Creates a CordRepFlat instance from the current inlined data with `extra'
  672. // bytes of desired additional capacity.
  673. CordRepFlat* MakeFlatWithExtraCapacity(size_t extra);
  674. // Sets the tree value for this instance. `rep` must not be null.
  675. // Requires the current instance to hold a tree, and a lock to be held on
  676. // any CordzInfo referenced by this instance. The latter is enforced through
  677. // the CordzUpdateScope argument. If the current instance is sampled, then
  678. // the CordzInfo instance is updated to reference the new `rep` value.
  679. void SetTree(CordRep* rep, const CordzUpdateScope& scope);
  680. // Identical to SetTree(), except that `rep` is allowed to be null, in
  681. // which case the current instance is reset to an empty value.
  682. void SetTreeOrEmpty(CordRep* rep, const CordzUpdateScope& scope);
  683. // Sets the tree value for this instance, and randomly samples this cord.
  684. // This function disregards existing contents in `data_`, and should be
  685. // called when a Cord is 'promoted' from an 'uninitialized' or 'inlined'
  686. // value to a non-inlined (tree / ring) value.
  687. void EmplaceTree(CordRep* rep, MethodIdentifier method);
  688. // Identical to EmplaceTree, except that it copies the parent stack from
  689. // the provided `parent` data if the parent is sampled.
  690. void EmplaceTree(CordRep* rep, const InlineData& parent,
  691. MethodIdentifier method);
  692. // Commits the change of a newly created, or updated `rep` root value into
  693. // this cord. `old_rep` indicates the old (inlined or tree) value of the
  694. // cord, and determines if the commit invokes SetTree() or EmplaceTree().
  695. void CommitTree(const CordRep* old_rep, CordRep* rep,
  696. const CordzUpdateScope& scope, MethodIdentifier method);
  697. void AppendTreeToInlined(CordRep* tree, MethodIdentifier method);
  698. void AppendTreeToTree(CordRep* tree, MethodIdentifier method);
  699. void AppendTree(CordRep* tree, MethodIdentifier method);
  700. void PrependTreeToInlined(CordRep* tree, MethodIdentifier method);
  701. void PrependTreeToTree(CordRep* tree, MethodIdentifier method);
  702. void PrependTree(CordRep* tree, MethodIdentifier method);
  703. template <bool has_length>
  704. void GetAppendRegion(char** region, size_t* size, size_t length);
  705. bool IsSame(const InlineRep& other) const {
  706. return memcmp(&data_, &other.data_, sizeof(data_)) == 0;
  707. }
  708. int BitwiseCompare(const InlineRep& other) const {
  709. uint64_t x, y;
  710. // Use memcpy to avoid aliasing issues.
  711. memcpy(&x, &data_, sizeof(x));
  712. memcpy(&y, &other.data_, sizeof(y));
  713. if (x == y) {
  714. memcpy(&x, reinterpret_cast<const char*>(&data_) + 8, sizeof(x));
  715. memcpy(&y, reinterpret_cast<const char*>(&other.data_) + 8, sizeof(y));
  716. if (x == y) return 0;
  717. }
  718. return absl::big_endian::FromHost64(x) < absl::big_endian::FromHost64(y)
  719. ? -1
  720. : 1;
  721. }
  722. void CopyTo(std::string* dst) const {
  723. // memcpy is much faster when operating on a known size. On most supported
  724. // platforms, the small string optimization is large enough that resizing
  725. // to 15 bytes does not cause a memory allocation.
  726. absl::strings_internal::STLStringResizeUninitialized(dst,
  727. sizeof(data_) - 1);
  728. memcpy(&(*dst)[0], &data_, sizeof(data_) - 1);
  729. // erase is faster than resize because the logic for memory allocation is
  730. // not needed.
  731. dst->erase(inline_size());
  732. }
  733. // Copies the inline contents into `dst`. Assumes the cord is not empty.
  734. void CopyToArray(char* dst) const;
  735. bool is_tree() const { return data_.is_tree(); }
  736. // Returns true if the Cord is being profiled by cordz.
  737. bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); }
  738. // Returns the profiled CordzInfo, or nullptr if not sampled.
  739. absl::cord_internal::CordzInfo* cordz_info() const {
  740. return data_.cordz_info();
  741. }
  742. // Sets the profiled CordzInfo. `cordz_info` must not be null.
  743. void set_cordz_info(cord_internal::CordzInfo* cordz_info) {
  744. assert(cordz_info != nullptr);
  745. data_.set_cordz_info(cordz_info);
  746. }
  747. // Resets the current cordz_info to null / empty.
  748. void clear_cordz_info() { data_.clear_cordz_info(); }
  749. private:
  750. friend class Cord;
  751. void AssignSlow(const InlineRep& src);
  752. // Unrefs the tree and stops profiling.
  753. void UnrefTree();
  754. void ResetToEmpty() { data_ = {}; }
  755. void set_inline_size(size_t size) { data_.set_inline_size(size); }
  756. size_t inline_size() const { return data_.inline_size(); }
  757. cord_internal::InlineData data_;
  758. };
  759. InlineRep contents_;
  760. // Helper for MemoryUsage().
  761. static size_t MemoryUsageAux(const absl::cord_internal::CordRep* rep);
  762. // Helper for GetFlat() and TryFlat().
  763. static bool GetFlatAux(absl::cord_internal::CordRep* rep,
  764. absl::string_view* fragment);
  765. // Helper for ForEachChunk().
  766. static void ForEachChunkAux(
  767. absl::cord_internal::CordRep* rep,
  768. absl::FunctionRef<void(absl::string_view)> callback);
  769. // The destructor for non-empty Cords.
  770. void DestroyCordSlow();
  771. // Out-of-line implementation of slower parts of logic.
  772. void CopyToArraySlowPath(char* dst) const;
  773. int CompareSlowPath(absl::string_view rhs, size_t compared_size,
  774. size_t size_to_compare) const;
  775. int CompareSlowPath(const Cord& rhs, size_t compared_size,
  776. size_t size_to_compare) const;
  777. bool EqualsImpl(absl::string_view rhs, size_t size_to_compare) const;
  778. bool EqualsImpl(const Cord& rhs, size_t size_to_compare) const;
  779. int CompareImpl(const Cord& rhs) const;
  780. template <typename ResultType, typename RHS>
  781. friend ResultType GenericCompare(const Cord& lhs, const RHS& rhs,
  782. size_t size_to_compare);
  783. static absl::string_view GetFirstChunk(const Cord& c);
  784. static absl::string_view GetFirstChunk(absl::string_view sv);
  785. // Returns a new reference to contents_.tree(), or steals an existing
  786. // reference if called on an rvalue.
  787. absl::cord_internal::CordRep* TakeRep() const&;
  788. absl::cord_internal::CordRep* TakeRep() &&;
  789. // Helper for Append().
  790. template <typename C>
  791. void AppendImpl(C&& src);
  792. // Prepends the provided data to this instance. `method` contains the public
  793. // API method for this action which is tracked for Cordz sampling purposes.
  794. void PrependArray(absl::string_view src, MethodIdentifier method);
  795. // Assigns the value in 'src' to this instance, 'stealing' its contents.
  796. // Requires src.length() > kMaxBytesToCopy.
  797. Cord& AssignLargeString(std::string&& src);
  798. // Helper for AbslHashValue().
  799. template <typename H>
  800. H HashFragmented(H hash_state) const {
  801. typename H::AbslInternalPiecewiseCombiner combiner;
  802. ForEachChunk([&combiner, &hash_state](absl::string_view chunk) {
  803. hash_state = combiner.add_buffer(std::move(hash_state), chunk.data(),
  804. chunk.size());
  805. });
  806. return H::combine(combiner.finalize(std::move(hash_state)), size());
  807. }
  808. };
  809. ABSL_NAMESPACE_END
  810. } // namespace absl
  811. namespace absl {
  812. ABSL_NAMESPACE_BEGIN
  813. // allow a Cord to be logged
  814. extern std::ostream& operator<<(std::ostream& out, const Cord& cord);
  815. // ------------------------------------------------------------------
  816. // Internal details follow. Clients should ignore.
  817. namespace cord_internal {
  818. // Fast implementation of memmove for up to 15 bytes. This implementation is
  819. // safe for overlapping regions. If nullify_tail is true, the destination is
  820. // padded with '\0' up to 16 bytes.
  821. inline void SmallMemmove(char* dst, const char* src, size_t n,
  822. bool nullify_tail = false) {
  823. if (n >= 8) {
  824. assert(n <= 16);
  825. uint64_t buf1;
  826. uint64_t buf2;
  827. memcpy(&buf1, src, 8);
  828. memcpy(&buf2, src + n - 8, 8);
  829. if (nullify_tail) {
  830. memset(dst + 8, 0, 8);
  831. }
  832. memcpy(dst, &buf1, 8);
  833. memcpy(dst + n - 8, &buf2, 8);
  834. } else if (n >= 4) {
  835. uint32_t buf1;
  836. uint32_t buf2;
  837. memcpy(&buf1, src, 4);
  838. memcpy(&buf2, src + n - 4, 4);
  839. if (nullify_tail) {
  840. memset(dst + 4, 0, 4);
  841. memset(dst + 8, 0, 8);
  842. }
  843. memcpy(dst, &buf1, 4);
  844. memcpy(dst + n - 4, &buf2, 4);
  845. } else {
  846. if (n != 0) {
  847. dst[0] = src[0];
  848. dst[n / 2] = src[n / 2];
  849. dst[n - 1] = src[n - 1];
  850. }
  851. if (nullify_tail) {
  852. memset(dst + 8, 0, 8);
  853. memset(dst + n, 0, 8);
  854. }
  855. }
  856. }
  857. // Does non-template-specific `CordRepExternal` initialization.
  858. // Expects `data` to be non-empty.
  859. void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep);
  860. // Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer
  861. // to it, or `nullptr` if `data` was empty.
  862. template <typename Releaser>
  863. // NOLINTNEXTLINE - suppress clang-tidy raw pointer return.
  864. CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) {
  865. using ReleaserType = absl::decay_t<Releaser>;
  866. if (data.empty()) {
  867. // Never create empty external nodes.
  868. InvokeReleaser(Rank0{}, ReleaserType(std::forward<Releaser>(releaser)),
  869. data);
  870. return nullptr;
  871. }
  872. CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>(
  873. std::forward<Releaser>(releaser), 0);
  874. InitializeCordRepExternal(data, rep);
  875. return rep;
  876. }
  877. // Overload for function reference types that dispatches using a function
  878. // pointer because there are no `alignof()` or `sizeof()` a function reference.
  879. // NOLINTNEXTLINE - suppress clang-tidy raw pointer return.
  880. inline CordRep* NewExternalRep(absl::string_view data,
  881. void (&releaser)(absl::string_view)) {
  882. return NewExternalRep(data, &releaser);
  883. }
  884. } // namespace cord_internal
  885. template <typename Releaser>
  886. Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) {
  887. Cord cord;
  888. if (auto* rep = ::absl::cord_internal::NewExternalRep(
  889. data, std::forward<Releaser>(releaser))) {
  890. cord.contents_.EmplaceTree(rep,
  891. Cord::MethodIdentifier::kMakeCordFromExternal);
  892. }
  893. return cord;
  894. }
  895. constexpr Cord::InlineRep::InlineRep(cord_internal::InlineData data)
  896. : data_(data) {}
  897. inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src)
  898. : data_(InlineData::kDefaultInit) {
  899. if (CordRep* tree = src.tree()) {
  900. EmplaceTree(CordRep::Ref(tree), src.data_,
  901. CordzUpdateTracker::kConstructorCord);
  902. } else {
  903. data_ = src.data_;
  904. }
  905. }
  906. inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) {
  907. src.ResetToEmpty();
  908. }
  909. inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) {
  910. if (this == &src) {
  911. return *this;
  912. }
  913. if (!is_tree() && !src.is_tree()) {
  914. data_ = src.data_;
  915. return *this;
  916. }
  917. AssignSlow(src);
  918. return *this;
  919. }
  920. inline Cord::InlineRep& Cord::InlineRep::operator=(
  921. Cord::InlineRep&& src) noexcept {
  922. if (is_tree()) {
  923. UnrefTree();
  924. }
  925. data_ = src.data_;
  926. src.ResetToEmpty();
  927. return *this;
  928. }
  929. inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) {
  930. if (rhs == this) {
  931. return;
  932. }
  933. std::swap(data_, rhs->data_);
  934. }
  935. inline const char* Cord::InlineRep::data() const {
  936. return is_tree() ? nullptr : data_.as_chars();
  937. }
  938. inline absl::cord_internal::CordRep* Cord::InlineRep::as_tree() const {
  939. assert(data_.is_tree());
  940. return data_.as_tree();
  941. }
  942. inline absl::cord_internal::CordRep* Cord::InlineRep::tree() const {
  943. if (is_tree()) {
  944. return as_tree();
  945. } else {
  946. return nullptr;
  947. }
  948. }
  949. inline bool Cord::InlineRep::empty() const { return data_.is_empty(); }
  950. inline size_t Cord::InlineRep::size() const {
  951. return is_tree() ? as_tree()->length : inline_size();
  952. }
  953. inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity(
  954. size_t extra) {
  955. static_assert(cord_internal::kMinFlatLength >= sizeof(data_), "");
  956. size_t len = data_.inline_size();
  957. auto* result = CordRepFlat::New(len + extra);
  958. result->length = len;
  959. memcpy(result->Data(), data_.as_chars(), sizeof(data_));
  960. return result;
  961. }
  962. inline void Cord::InlineRep::EmplaceTree(CordRep* rep,
  963. MethodIdentifier method) {
  964. assert(rep);
  965. data_.make_tree(rep);
  966. CordzInfo::MaybeTrackCord(data_, method);
  967. }
  968. inline void Cord::InlineRep::EmplaceTree(CordRep* rep, const InlineData& parent,
  969. MethodIdentifier method) {
  970. data_.make_tree(rep);
  971. CordzInfo::MaybeTrackCord(data_, parent, method);
  972. }
  973. inline void Cord::InlineRep::SetTree(CordRep* rep,
  974. const CordzUpdateScope& scope) {
  975. assert(rep);
  976. assert(data_.is_tree());
  977. data_.set_tree(rep);
  978. scope.SetCordRep(rep);
  979. }
  980. inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep,
  981. const CordzUpdateScope& scope) {
  982. assert(data_.is_tree());
  983. if (rep) {
  984. data_.set_tree(rep);
  985. } else {
  986. data_ = {};
  987. }
  988. scope.SetCordRep(rep);
  989. }
  990. inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep,
  991. const CordzUpdateScope& scope,
  992. MethodIdentifier method) {
  993. if (old_rep) {
  994. SetTree(rep, scope);
  995. } else {
  996. EmplaceTree(rep, method);
  997. }
  998. }
  999. inline absl::cord_internal::CordRep* Cord::InlineRep::clear() {
  1000. if (is_tree()) {
  1001. CordzInfo::MaybeUntrackCord(cordz_info());
  1002. }
  1003. absl::cord_internal::CordRep* result = tree();
  1004. ResetToEmpty();
  1005. return result;
  1006. }
  1007. inline void Cord::InlineRep::CopyToArray(char* dst) const {
  1008. assert(!is_tree());
  1009. size_t n = inline_size();
  1010. assert(n != 0);
  1011. cord_internal::SmallMemmove(dst, data_.as_chars(), n);
  1012. }
  1013. constexpr inline Cord::Cord() noexcept {}
  1014. inline Cord::Cord(absl::string_view src)
  1015. : Cord(src, CordzUpdateTracker::kConstructorString) {}
  1016. template <typename T>
  1017. constexpr Cord::Cord(strings_internal::StringConstant<T>)
  1018. : contents_(strings_internal::StringConstant<T>::value.size() <=
  1019. cord_internal::kMaxInline
  1020. ? cord_internal::InlineData(
  1021. strings_internal::StringConstant<T>::value)
  1022. : cord_internal::InlineData(
  1023. &cord_internal::ConstInitExternalStorage<
  1024. strings_internal::StringConstant<T>>::value)) {}
  1025. inline Cord& Cord::operator=(const Cord& x) {
  1026. contents_ = x.contents_;
  1027. return *this;
  1028. }
  1029. template <typename T, Cord::EnableIfString<T>>
  1030. Cord& Cord::operator=(T&& src) {
  1031. if (src.size() <= cord_internal::kMaxBytesToCopy) {
  1032. return operator=(absl::string_view(src));
  1033. } else {
  1034. return AssignLargeString(std::forward<T>(src));
  1035. }
  1036. }
  1037. inline Cord::Cord(const Cord& src) : contents_(src.contents_) {}
  1038. inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {}
  1039. inline void Cord::swap(Cord& other) noexcept {
  1040. contents_.Swap(&other.contents_);
  1041. }
  1042. inline Cord& Cord::operator=(Cord&& x) noexcept {
  1043. contents_ = std::move(x.contents_);
  1044. return *this;
  1045. }
  1046. extern template Cord::Cord(std::string&& src);
  1047. inline size_t Cord::size() const {
  1048. // Length is 1st field in str.rep_
  1049. return contents_.size();
  1050. }
  1051. inline bool Cord::empty() const { return contents_.empty(); }
  1052. inline size_t Cord::EstimatedMemoryUsage() const {
  1053. size_t result = sizeof(Cord);
  1054. if (const absl::cord_internal::CordRep* rep = contents_.tree()) {
  1055. result += MemoryUsageAux(rep);
  1056. }
  1057. return result;
  1058. }
  1059. inline absl::optional<absl::string_view> Cord::TryFlat() const {
  1060. absl::cord_internal::CordRep* rep = contents_.tree();
  1061. if (rep == nullptr) {
  1062. return absl::string_view(contents_.data(), contents_.size());
  1063. }
  1064. absl::string_view fragment;
  1065. if (GetFlatAux(rep, &fragment)) {
  1066. return fragment;
  1067. }
  1068. return absl::nullopt;
  1069. }
  1070. inline absl::string_view Cord::Flatten() {
  1071. absl::cord_internal::CordRep* rep = contents_.tree();
  1072. if (rep == nullptr) {
  1073. return absl::string_view(contents_.data(), contents_.size());
  1074. } else {
  1075. absl::string_view already_flat_contents;
  1076. if (GetFlatAux(rep, &already_flat_contents)) {
  1077. return already_flat_contents;
  1078. }
  1079. }
  1080. return FlattenSlowPath();
  1081. }
  1082. inline void Cord::Append(absl::string_view src) {
  1083. contents_.AppendArray(src, CordzUpdateTracker::kAppendString);
  1084. }
  1085. inline void Cord::Prepend(absl::string_view src) {
  1086. PrependArray(src, CordzUpdateTracker::kPrependString);
  1087. }
  1088. extern template void Cord::Append(std::string&& src);
  1089. extern template void Cord::Prepend(std::string&& src);
  1090. inline int Cord::Compare(const Cord& rhs) const {
  1091. if (!contents_.is_tree() && !rhs.contents_.is_tree()) {
  1092. return contents_.BitwiseCompare(rhs.contents_);
  1093. }
  1094. return CompareImpl(rhs);
  1095. }
  1096. // Does 'this' cord start/end with rhs
  1097. inline bool Cord::StartsWith(const Cord& rhs) const {
  1098. if (contents_.IsSame(rhs.contents_)) return true;
  1099. size_t rhs_size = rhs.size();
  1100. if (size() < rhs_size) return false;
  1101. return EqualsImpl(rhs, rhs_size);
  1102. }
  1103. inline bool Cord::StartsWith(absl::string_view rhs) const {
  1104. size_t rhs_size = rhs.size();
  1105. if (size() < rhs_size) return false;
  1106. return EqualsImpl(rhs, rhs_size);
  1107. }
  1108. inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) {
  1109. if (tree->tag == cord_internal::BTREE) {
  1110. current_chunk_ = btree_reader_.Init(tree->btree());
  1111. return;
  1112. }
  1113. stack_of_right_children_.push_back(tree);
  1114. operator++();
  1115. }
  1116. inline Cord::ChunkIterator::ChunkIterator(cord_internal::CordRep* tree)
  1117. : bytes_remaining_(tree->length) {
  1118. InitTree(tree);
  1119. }
  1120. inline Cord::ChunkIterator::ChunkIterator(const Cord* cord)
  1121. : bytes_remaining_(cord->size()) {
  1122. if (cord->contents_.is_tree()) {
  1123. InitTree(cord->contents_.as_tree());
  1124. } else {
  1125. current_chunk_ =
  1126. absl::string_view(cord->contents_.data(), bytes_remaining_);
  1127. }
  1128. }
  1129. inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() {
  1130. current_chunk_ = btree_reader_.Next();
  1131. return *this;
  1132. }
  1133. inline void Cord::ChunkIterator::AdvanceBytesBtree(size_t n) {
  1134. assert(n >= current_chunk_.size());
  1135. bytes_remaining_ -= n;
  1136. if (bytes_remaining_) {
  1137. if (n == current_chunk_.size()) {
  1138. current_chunk_ = btree_reader_.Next();
  1139. } else {
  1140. size_t offset = btree_reader_.length() - bytes_remaining_;
  1141. current_chunk_ = btree_reader_.Seek(offset);
  1142. }
  1143. } else {
  1144. current_chunk_ = {};
  1145. }
  1146. }
  1147. inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() {
  1148. ABSL_HARDENING_ASSERT(bytes_remaining_ > 0 &&
  1149. "Attempted to iterate past `end()`");
  1150. assert(bytes_remaining_ >= current_chunk_.size());
  1151. bytes_remaining_ -= current_chunk_.size();
  1152. if (bytes_remaining_ > 0) {
  1153. return btree_reader_ ? AdvanceBtree() : AdvanceStack();
  1154. } else {
  1155. current_chunk_ = {};
  1156. }
  1157. return *this;
  1158. }
  1159. inline Cord::ChunkIterator Cord::ChunkIterator::operator++(int) {
  1160. ChunkIterator tmp(*this);
  1161. operator++();
  1162. return tmp;
  1163. }
  1164. inline bool Cord::ChunkIterator::operator==(const ChunkIterator& other) const {
  1165. return bytes_remaining_ == other.bytes_remaining_;
  1166. }
  1167. inline bool Cord::ChunkIterator::operator!=(const ChunkIterator& other) const {
  1168. return !(*this == other);
  1169. }
  1170. inline Cord::ChunkIterator::reference Cord::ChunkIterator::operator*() const {
  1171. ABSL_HARDENING_ASSERT(bytes_remaining_ != 0);
  1172. return current_chunk_;
  1173. }
  1174. inline Cord::ChunkIterator::pointer Cord::ChunkIterator::operator->() const {
  1175. ABSL_HARDENING_ASSERT(bytes_remaining_ != 0);
  1176. return &current_chunk_;
  1177. }
  1178. inline void Cord::ChunkIterator::RemoveChunkPrefix(size_t n) {
  1179. assert(n < current_chunk_.size());
  1180. current_chunk_.remove_prefix(n);
  1181. bytes_remaining_ -= n;
  1182. }
  1183. inline void Cord::ChunkIterator::AdvanceBytes(size_t n) {
  1184. assert(bytes_remaining_ >= n);
  1185. if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) {
  1186. RemoveChunkPrefix(n);
  1187. } else if (n != 0) {
  1188. btree_reader_ ? AdvanceBytesBtree(n) : AdvanceBytesSlowPath(n);
  1189. }
  1190. }
  1191. inline Cord::ChunkIterator Cord::chunk_begin() const {
  1192. return ChunkIterator(this);
  1193. }
  1194. inline Cord::ChunkIterator Cord::chunk_end() const { return ChunkIterator(); }
  1195. inline Cord::ChunkIterator Cord::ChunkRange::begin() const {
  1196. return cord_->chunk_begin();
  1197. }
  1198. inline Cord::ChunkIterator Cord::ChunkRange::end() const {
  1199. return cord_->chunk_end();
  1200. }
  1201. inline Cord::ChunkRange Cord::Chunks() const { return ChunkRange(this); }
  1202. inline Cord::CharIterator& Cord::CharIterator::operator++() {
  1203. if (ABSL_PREDICT_TRUE(chunk_iterator_->size() > 1)) {
  1204. chunk_iterator_.RemoveChunkPrefix(1);
  1205. } else {
  1206. ++chunk_iterator_;
  1207. }
  1208. return *this;
  1209. }
  1210. inline Cord::CharIterator Cord::CharIterator::operator++(int) {
  1211. CharIterator tmp(*this);
  1212. operator++();
  1213. return tmp;
  1214. }
  1215. inline bool Cord::CharIterator::operator==(const CharIterator& other) const {
  1216. return chunk_iterator_ == other.chunk_iterator_;
  1217. }
  1218. inline bool Cord::CharIterator::operator!=(const CharIterator& other) const {
  1219. return !(*this == other);
  1220. }
  1221. inline Cord::CharIterator::reference Cord::CharIterator::operator*() const {
  1222. return *chunk_iterator_->data();
  1223. }
  1224. inline Cord::CharIterator::pointer Cord::CharIterator::operator->() const {
  1225. return chunk_iterator_->data();
  1226. }
  1227. inline Cord Cord::AdvanceAndRead(CharIterator* it, size_t n_bytes) {
  1228. assert(it != nullptr);
  1229. return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes);
  1230. }
  1231. inline void Cord::Advance(CharIterator* it, size_t n_bytes) {
  1232. assert(it != nullptr);
  1233. it->chunk_iterator_.AdvanceBytes(n_bytes);
  1234. }
  1235. inline absl::string_view Cord::ChunkRemaining(const CharIterator& it) {
  1236. return *it.chunk_iterator_;
  1237. }
  1238. inline Cord::CharIterator Cord::char_begin() const {
  1239. return CharIterator(this);
  1240. }
  1241. inline Cord::CharIterator Cord::char_end() const { return CharIterator(); }
  1242. inline Cord::CharIterator Cord::CharRange::begin() const {
  1243. return cord_->char_begin();
  1244. }
  1245. inline Cord::CharIterator Cord::CharRange::end() const {
  1246. return cord_->char_end();
  1247. }
  1248. inline Cord::CharRange Cord::Chars() const { return CharRange(this); }
  1249. inline void Cord::ForEachChunk(
  1250. absl::FunctionRef<void(absl::string_view)> callback) const {
  1251. absl::cord_internal::CordRep* rep = contents_.tree();
  1252. if (rep == nullptr) {
  1253. callback(absl::string_view(contents_.data(), contents_.size()));
  1254. } else {
  1255. return ForEachChunkAux(rep, callback);
  1256. }
  1257. }
  1258. // Nonmember Cord-to-Cord relational operarators.
  1259. inline bool operator==(const Cord& lhs, const Cord& rhs) {
  1260. if (lhs.contents_.IsSame(rhs.contents_)) return true;
  1261. size_t rhs_size = rhs.size();
  1262. if (lhs.size() != rhs_size) return false;
  1263. return lhs.EqualsImpl(rhs, rhs_size);
  1264. }
  1265. inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); }
  1266. inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; }
  1267. inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; }
  1268. inline bool operator<=(const Cord& x, const Cord& y) {
  1269. return x.Compare(y) <= 0;
  1270. }
  1271. inline bool operator>=(const Cord& x, const Cord& y) {
  1272. return x.Compare(y) >= 0;
  1273. }
  1274. // Nonmember Cord-to-absl::string_view relational operators.
  1275. //
  1276. // Due to implicit conversions, these also enable comparisons of Cord with
  1277. // with std::string, ::string, and const char*.
  1278. inline bool operator==(const Cord& lhs, absl::string_view rhs) {
  1279. size_t lhs_size = lhs.size();
  1280. size_t rhs_size = rhs.size();
  1281. if (lhs_size != rhs_size) return false;
  1282. return lhs.EqualsImpl(rhs, rhs_size);
  1283. }
  1284. inline bool operator==(absl::string_view x, const Cord& y) { return y == x; }
  1285. inline bool operator!=(const Cord& x, absl::string_view y) { return !(x == y); }
  1286. inline bool operator!=(absl::string_view x, const Cord& y) { return !(x == y); }
  1287. inline bool operator<(const Cord& x, absl::string_view y) {
  1288. return x.Compare(y) < 0;
  1289. }
  1290. inline bool operator<(absl::string_view x, const Cord& y) {
  1291. return y.Compare(x) > 0;
  1292. }
  1293. inline bool operator>(const Cord& x, absl::string_view y) { return y < x; }
  1294. inline bool operator>(absl::string_view x, const Cord& y) { return y < x; }
  1295. inline bool operator<=(const Cord& x, absl::string_view y) { return !(y < x); }
  1296. inline bool operator<=(absl::string_view x, const Cord& y) { return !(y < x); }
  1297. inline bool operator>=(const Cord& x, absl::string_view y) { return !(x < y); }
  1298. inline bool operator>=(absl::string_view x, const Cord& y) { return !(x < y); }
  1299. // Some internals exposed to test code.
  1300. namespace strings_internal {
  1301. class CordTestAccess {
  1302. public:
  1303. static size_t FlatOverhead();
  1304. static size_t MaxFlatLength();
  1305. static size_t SizeofCordRepConcat();
  1306. static size_t SizeofCordRepExternal();
  1307. static size_t SizeofCordRepSubstring();
  1308. static size_t FlatTagToLength(uint8_t tag);
  1309. static uint8_t LengthToTag(size_t s);
  1310. };
  1311. } // namespace strings_internal
  1312. ABSL_NAMESPACE_END
  1313. } // namespace absl
  1314. #endif // ABSL_STRINGS_CORD_H_