From 299dbc588e4d2a6e23a4f99d5d224c042ab4a9a5 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 20 Dec 2023 09:50:32 -0800 Subject: Unify btree EmptyNode allocation code across compilers. We currently have a workaround for MSVC, which has constexpr pointer arithmetic bugs. The bug seems to still exist and the existing code for non-MSVC compilers doesn't build. This alternative constexpr constructor avoids pointer arithmetic and seems to be working for all, including MSVC. PiperOrigin-RevId: 592586957 Change-Id: Ic585693c3a7abaab5fbbc0954b8ee924994f8dbf --- absl/container/internal/btree.h | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index ef630aea..3526471d 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -572,13 +572,6 @@ class btree_node { btree_node(btree_node const &) = delete; btree_node &operator=(btree_node const &) = delete; - // Public for EmptyNodeType. - constexpr static size_type Alignment() { - static_assert(LeafLayout(1).Alignment() == InternalLayout().Alignment(), - "Alignment of all nodes must be equal."); - return InternalLayout().Alignment(); - } - protected: btree_node() = default; @@ -653,6 +646,12 @@ class btree_node { return InternalLayout().AllocSize(); } + constexpr static size_type Alignment() { + static_assert(LeafLayout(1).Alignment() == InternalLayout().Alignment(), + "Alignment of all nodes must be equal."); + return InternalLayout().Alignment(); + } + // N is the index of the type in the Layout definition. // ElementType is the Nth type in the Layout definition. template @@ -1321,7 +1320,7 @@ class btree { // We use a static empty node for the root/leftmost/rightmost of empty btrees // in order to avoid branching in begin()/end(). - struct alignas(node_type::Alignment()) EmptyNodeType : node_type { + struct EmptyNodeType : node_type { using field_type = typename node_type::field_type; node_type *parent; #ifdef ABSL_BTREE_ENABLE_GENERATIONS @@ -1334,25 +1333,12 @@ class btree { // as a leaf node). max_count() is never called when the tree is empty. field_type max_count = node_type::kInternalNodeMaxCount + 1; -#ifdef _MSC_VER - // MSVC has constexpr code generations bugs here. - EmptyNodeType() : parent(this) {} -#else - explicit constexpr EmptyNodeType(node_type *p) : parent(p) {} -#endif + constexpr EmptyNodeType() : parent(this) {} }; static node_type *EmptyNode() { -#ifdef _MSC_VER - static EmptyNodeType *empty_node = new EmptyNodeType; - // This assert fails on some other construction methods. - assert(empty_node->parent == empty_node); - return empty_node; -#else - static constexpr EmptyNodeType empty_node( - const_cast(&empty_node)); + alignas(node_type::Alignment()) static constexpr EmptyNodeType empty_node; return const_cast(&empty_node); -#endif } enum : uint32_t { -- cgit v1.2.3