summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2023-12-20 09:50:32 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2023-12-20 09:51:29 -0800
commit299dbc588e4d2a6e23a4f99d5d224c042ab4a9a5 (patch)
tree2c5a1f7bb7358b3aa431c5d2880c5eea22bbe8ac
parentb559abcbbe27402b6d6d47db38c23f69ca99aff2 (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
-rw-r--r--absl/container/internal/btree.h32
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 {