From e4e2e57e1a4308cf4ba008d9c1f2d478b3349201 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 22 Jan 2021 03:53:23 -0800 Subject: Export of internal Abseil changes -- cfd7ee2487ed9b5636d8f83d3850c02e3b4a5cb0 by Jorg Brown : Add union padding to AsTree, to avoid issues on 32-bit MSVC 2015 compilers alignas() causes compiler errors as per https://godbolt.org/z/vaTKjn This change uses explicit padding to achieve what we want: https://godbolt.org/z/Mfjhhj PiperOrigin-RevId: 353211413 -- b1ac7430ffdefe58c01b29e9acd182cda4630e1d by Jorg Brown : Make the casting functions flat() and ring() be static_cast, rather than reinterpret_cast. PiperOrigin-RevId: 353149543 -- c37a6761c31720317c8b0b7db62b693643a88586 by Abseil Team : Integrate CordRepRing logic into cord (but do not enable it) PiperOrigin-RevId: 353135656 -- 2007fd3045ed6285106795cf8f2e6d792922f5e8 by Abseil Team : Fix a typo in the description of ::equal_range(). The correct return is actually a half-open range [first, last). PiperOrigin-RevId: 353122213 -- 6683fa2ba7271dd1f575bd7742d97f47a034c9d2 by Abseil Team : Integrate CordRepRing logic into cord (but do not enable it) PiperOrigin-RevId: 353121763 GitOrigin-RevId: cfd7ee2487ed9b5636d8f83d3850c02e3b4a5cb0 Change-Id: I6635163cd634706f5462c4065aa278e6bf193a72 --- absl/container/btree_map.h | 7 +++---- absl/strings/internal/cord_internal.h | 30 ++++++++---------------------- absl/strings/internal/cord_rep_flat.h | 11 +++++++++++ absl/strings/internal/cord_rep_ring.h | 11 +++++++++++ 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h index abc09b0a..ea49d446 100644 --- a/absl/container/btree_map.h +++ b/absl/container/btree_map.h @@ -384,9 +384,8 @@ class btree_map // btree_map::equal_range() // - // Returns a closed range [first, last], defined by a `std::pair` of two - // iterators, containing all elements with the passed key in the - // `btree_map`. + // Returns a half-open range [first, last), defined by a `std::pair` of two + // iterators, containing all elements with the passed key in the `btree_map`. using Base::equal_range; // btree_map::find() @@ -709,7 +708,7 @@ class btree_multimap // btree_multimap::equal_range() // - // Returns a closed range [first, last], defined by a `std::pair` of two + // Returns a half-open range [first, last), defined by a `std::pair` of two // iterators, containing all elements with the passed key in the // `btree_multimap`. using Base::equal_range; diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index 7a1ef6b1..96502433 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -456,8 +456,14 @@ class InlineData { struct AsTree { explicit constexpr AsTree(absl::cord_internal::CordRep* tree) : rep(tree), cordz_info(kNullCordzInfo) {} - absl::cord_internal::CordRep* rep; - alignas(sizeof(cordz_info_t)) cordz_info_t cordz_info; + // This union uses up extra space so that whether rep is 32 or 64 bits, + // cordz_info will still start at the eighth byte, and the last + // byte of cordz_info will still be the last byte of InlineData. + union { + absl::cord_internal::CordRep* rep; + cordz_info_t unused_aligner; + }; + cordz_info_t cordz_info; }; char& tag() { return reinterpret_cast(this)[kMaxInline]; } @@ -505,26 +511,6 @@ inline const CordRepExternal* CordRep::external() const { return static_cast(this); } -inline CordRepFlat* CordRep::flat() { - assert(tag >= FLAT && tag <= MAX_FLAT_TAG); - return reinterpret_cast(this); -} - -inline const CordRepFlat* CordRep::flat() const { - assert(tag >= FLAT && tag <= MAX_FLAT_TAG); - return reinterpret_cast(this); -} - -inline CordRepRing* CordRep::ring() { - assert(tag == RING); - return reinterpret_cast(this); -} - -inline const CordRepRing* CordRep::ring() const { - assert(tag == RING); - return reinterpret_cast(this); -} - inline CordRep* CordRep::Ref(CordRep* rep) { assert(rep != nullptr); rep->refcount.Increment(); diff --git a/absl/strings/internal/cord_rep_flat.h b/absl/strings/internal/cord_rep_flat.h index 5f7d55ce..55418153 100644 --- a/absl/strings/internal/cord_rep_flat.h +++ b/absl/strings/internal/cord_rep_flat.h @@ -127,6 +127,17 @@ struct CordRepFlat : public CordRep { size_t AllocatedSize() const { return TagToAllocatedSize(tag); } }; +// Now that CordRepFlat is defined, we can define CordRep's helper casts: +inline CordRepFlat* CordRep::flat() { + assert(tag >= FLAT && tag <= MAX_FLAT_TAG); + return reinterpret_cast(this); +} + +inline const CordRepFlat* CordRep::flat() const { + assert(tag >= FLAT && tag <= MAX_FLAT_TAG); + return reinterpret_cast(this); +} + } // namespace cord_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/cord_rep_ring.h b/absl/strings/internal/cord_rep_ring.h index e6f6b59c..55cba8b4 100644 --- a/absl/strings/internal/cord_rep_ring.h +++ b/absl/strings/internal/cord_rep_ring.h @@ -563,6 +563,17 @@ inline CordRepRing::Position CordRepRing::FindTail(index_type head, return (offset == length) ? Position{tail_, 0} : FindTailSlow(head, offset); } +// Now that CordRepRing is defined, we can define CordRep's helper casts: +inline CordRepRing* CordRep::ring() { + assert(tag == RING); + return static_cast(this); +} + +inline const CordRepRing* CordRep::ring() const { + assert(tag == RING); + return static_cast(this); +} + std::ostream& operator<<(std::ostream& s, const CordRepRing& rep); #ifdef __clang__ -- cgit v1.2.3