diff options
author | Abseil Team <absl-team@google.com> | 2023-12-20 09:50:32 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-12-20 09:51:29 -0800 |
commit | 299dbc588e4d2a6e23a4f99d5d224c042ab4a9a5 (patch) | |
tree | 2c5a1f7bb7358b3aa431c5d2880c5eea22bbe8ac /absl/container | |
parent | b559abcbbe27402b6d6d47db38c23f69ca99aff2 (diff) |
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
Diffstat (limited to 'absl/container')
-rw-r--r-- | absl/container/internal/btree.h | 32 |
1 files 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<N> is the Nth type in the Layout definition. template <size_type N> @@ -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<EmptyNodeType *>(&empty_node)); + alignas(node_type::Alignment()) static constexpr EmptyNodeType empty_node; return const_cast<EmptyNodeType *>(&empty_node); -#endif } enum : uint32_t { |