[libcxx-commits] [libcxx] [libc++] Require fancy pointer to be correctly convertible (PR #152989)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Aug 11 03:21:09 PDT 2025
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/152989
This patch removes a bunch of code that works around incorrect implementations of fancy pointers. It's possible that this breaks user code. However, any breakage is likely to catch serious latent bugs.
>From 19c6b7d52baa9cd07338f1a5351304dc92e0b665 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 11 Aug 2025 12:19:39 +0200
Subject: [PATCH] [libc++] Require fancy pointer to be correctly convertible
---
libcxx/include/__hash_table | 10 +-
libcxx/include/__memory/pointer_traits.h | 12 --
libcxx/include/__tree | 145 +++++++++++------------
libcxx/include/forward_list | 38 +++---
libcxx/test/support/min_allocator.h | 7 ++
5 files changed, 98 insertions(+), 114 deletions(-)
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index dacc152030e14..dbc41fdf0f459 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -96,7 +96,7 @@ struct __hash_node_base {
__next_pointer __next_;
_LIBCPP_HIDE_FROM_ABI __next_pointer __ptr() _NOEXCEPT {
- return static_cast<__next_pointer>(pointer_traits<__node_base_pointer>::pointer_to(*this));
+ return pointer_traits<__node_base_pointer>::pointer_to(*this);
}
_LIBCPP_HIDE_FROM_ABI __node_pointer __upcast() _NOEXCEPT {
@@ -1499,9 +1499,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(const_iterator __p
while (__pp->__next_ != __np)
__pp = __pp->__next_;
__cp->__next_ = __np;
- __pp->__next_ = static_cast<__next_pointer>(__cp);
+ __pp->__next_ = __cp;
++size();
- return iterator(static_cast<__next_pointer>(__cp));
+ return iterator(__cp);
}
return __node_insert_multi(__cp);
}
@@ -1547,9 +1547,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
__bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] = __h.get()->__ptr();
} else {
__h->__next_ = __pn->__next_;
- __pn->__next_ = static_cast<__next_pointer>(__h.get());
+ __pn->__next_ = __h.get();
}
- __nd = static_cast<__next_pointer>(__h.release());
+ __nd = __h.release();
// increment size
++size();
__inserted = true;
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
index 8c7f8dff1b76b..336422befb6ee 100644
--- a/libcxx/include/__memory/pointer_traits.h
+++ b/libcxx/include/__memory/pointer_traits.h
@@ -252,18 +252,6 @@ concept __resettable_smart_pointer_with_args = requires(_Smart __s, _Pointer __p
#endif
-// This function ensures safe conversions between fancy pointers at compile-time, where we avoid casts from/to
-// `__void_pointer` by obtaining the underlying raw pointer from the fancy pointer using `std::to_address`,
-// then dereferencing it to retrieve the pointed-to object, and finally constructing the target fancy pointer
-// to that object using the `std::pointer_traits<>::pinter_to` function.
-template <class _PtrTo, class _PtrFrom>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _PtrTo __static_fancy_pointer_cast(const _PtrFrom& __p) {
- using __ptr_traits = pointer_traits<_PtrTo>;
- using __element_type = typename __ptr_traits::element_type;
- return __p ? __ptr_traits::pointer_to(*static_cast<__element_type*>(std::addressof(*__p)))
- : static_cast<_PtrTo>(nullptr);
-}
-
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 6dadd0915c984..b804a542bbd8d 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -171,10 +171,10 @@ template <class _EndNodePtr, class _NodePtr>
inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
if (__x->__right_ != nullptr)
- return static_cast<_EndNodePtr>(std::__tree_min(__x->__right_));
+ return std::__tree_min(__x->__right_);
while (!std::__tree_is_left_child(__x))
__x = __x->__parent_unsafe();
- return static_cast<_EndNodePtr>(__x->__parent_);
+ return __x->__parent_;
}
// Returns: pointer to the previous in-order node before __x.
@@ -541,7 +541,7 @@ public:
_LIBCPP_HIDE_FROM_ABI pointer __parent_unsafe() const { return static_cast<pointer>(__parent_); }
- _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) { __parent_ = static_cast<__end_node_pointer>(__p); }
+ _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) { __parent_ = __p; }
~__tree_node_base() = delete;
__tree_node_base(__tree_node_base const&) = delete;
@@ -635,7 +635,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI __tree_iterator& operator--() {
- __ptr_ = static_cast<__end_node_pointer>(std::__tree_prev_iter<__node_base_pointer>(__ptr_));
+ __ptr_ = std::__tree_prev_iter<__node_base_pointer>(__ptr_);
return *this;
}
_LIBCPP_HIDE_FROM_ABI __tree_iterator operator--(int) {
@@ -698,7 +698,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator--() {
- __ptr_ = static_cast<__end_node_pointer>(std::__tree_prev_iter<__node_base_pointer>(__ptr_));
+ __ptr_ = std::__tree_prev_iter<__node_base_pointer>(__ptr_);
return *this;
}
@@ -1212,12 +1212,12 @@ private:
__node_pointer __new_node_ptr = __new_node.release();
__new_node_ptr->__is_black_ = __src->__is_black_;
- __new_node_ptr->__left_ = static_cast<__node_base_pointer>(__left.release());
- __new_node_ptr->__right_ = static_cast<__node_base_pointer>(__right);
+ __new_node_ptr->__left_ = __left.release();
+ __new_node_ptr->__right_ = __right;
if (__new_node_ptr->__left_)
- __new_node_ptr->__left_->__parent_ = static_cast<__end_node_pointer>(__new_node_ptr);
+ __new_node_ptr->__left_->__parent_ = __new_node_ptr;
if (__new_node_ptr->__right_)
- __new_node_ptr->__right_->__parent_ = static_cast<__end_node_pointer>(__new_node_ptr);
+ __new_node_ptr->__right_->__parent_ = __new_node_ptr;
return __new_node_ptr;
}
@@ -1239,24 +1239,24 @@ private:
// If we already have a left node in the destination tree, reuse it and copy-assign recursively
if (__dest->__left_) {
- __dest->__left_ = static_cast<__node_base_pointer>(__copy_assign_tree(
- static_cast<__node_pointer>(__dest->__left_), static_cast<__node_pointer>(__src->__left_)));
+ __dest->__left_ =
+ __copy_assign_tree(static_cast<__node_pointer>(__dest->__left_), static_cast<__node_pointer>(__src->__left_));
// Otherwise, we must create new nodes; copy-construct from here on
} else if (__src->__left_) {
auto __new_left = __copy_construct_tree(static_cast<__node_pointer>(__src->__left_));
- __dest->__left_ = static_cast<__node_base_pointer>(__new_left);
- __new_left->__parent_ = static_cast<__end_node_pointer>(__dest);
+ __dest->__left_ = __new_left;
+ __new_left->__parent_ = __dest;
}
// Identical to the left case above, just for the right nodes
if (__dest->__right_) {
- __dest->__right_ = static_cast<__node_base_pointer>(__copy_assign_tree(
- static_cast<__node_pointer>(__dest->__right_), static_cast<__node_pointer>(__src->__right_)));
+ __dest->__right_ = __copy_assign_tree(
+ static_cast<__node_pointer>(__dest->__right_), static_cast<__node_pointer>(__src->__right_));
} else if (__src->__right_) {
auto __new_right = __copy_construct_tree(static_cast<__node_pointer>(__src->__right_));
- __dest->__right_ = static_cast<__node_base_pointer>(__new_right);
- __new_right->__parent_ = static_cast<__end_node_pointer>(__dest);
+ __dest->__right_ = __new_right;
+ __new_right->__parent_ = __dest;
}
return __dest;
@@ -1332,15 +1332,14 @@ __tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(
__copy_assign_alloc(__t);
if (__size_ != 0) {
- *__root_ptr() = static_cast<__node_base_pointer>(__copy_assign_tree(__root(), __t.__root()));
+ *__root_ptr() = __copy_assign_tree(__root(), __t.__root());
} else {
- *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
+ *__root_ptr() = __copy_construct_tree(__t.__root());
if (__root())
__root()->__parent_ = __end_node();
}
- __begin_node_ =
- __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node();
- __size_ = __t.size();
+ __begin_node_ = __end_node()->__left_ ? std::__tree_min(__end_node()->__left_) : __end_node();
+ __size_ = __t.size();
return *this;
}
@@ -1394,9 +1393,9 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
if (__t.size() == 0)
return;
- *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
+ *__root_ptr() = __copy_construct_tree(__t.__root());
__root()->__parent_ = __end_node();
- __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
+ __begin_node_ = std::__tree_min(__end_node()->__left_);
__size_ = __t.size();
}
@@ -1411,7 +1410,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
if (__size_ == 0)
__begin_node_ = __end_node();
else {
- __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
+ __end_node()->__left_->__parent_ = __end_node();
__t.__begin_node_ = __t.__end_node();
__t.__end_node()->__left_ = nullptr;
__t.__size_ = 0;
@@ -1427,7 +1426,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __
else {
__begin_node_ = __t.__begin_node_;
__end_node()->__left_ = __t.__end_node()->__left_;
- __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
+ __end_node()->__left_->__parent_ = __end_node();
__size_ = __t.__size_;
__t.__begin_node_ = __t.__end_node();
__t.__end_node()->__left_ = nullptr;
@@ -1450,7 +1449,7 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
if (__size_ == 0)
__begin_node_ = __end_node();
else {
- __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
+ __end_node()->__left_->__parent_ = __end_node();
__t.__begin_node_ = __t.__end_node();
__t.__end_node()->__left_ = nullptr;
__t.__size_ = 0;
@@ -1545,14 +1544,14 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__end_node_pointer& __parent,
if (__nd->__right_ != nullptr)
__nd = static_cast<__node_pointer>(__nd->__right_);
else {
- __parent = static_cast<__end_node_pointer>(__nd);
+ __parent = __nd;
return __nd->__right_;
}
} else {
if (__nd->__left_ != nullptr)
__nd = static_cast<__node_pointer>(__nd->__left_);
else {
- __parent = static_cast<__end_node_pointer>(__nd);
+ __parent = __nd;
return __parent->__left_;
}
}
@@ -1575,14 +1574,14 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__end_node_pointer& __parent
if (__nd->__left_ != nullptr)
__nd = static_cast<__node_pointer>(__nd->__left_);
else {
- __parent = static_cast<__end_node_pointer>(__nd);
+ __parent = __nd;
return __parent->__left_;
}
} else {
if (__nd->__right_ != nullptr)
__nd = static_cast<__node_pointer>(__nd->__right_);
else {
- __parent = static_cast<__end_node_pointer>(__nd);
+ __parent = __nd;
return __nd->__right_;
}
}
@@ -1608,10 +1607,10 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Co
if (__prior == begin() || !value_comp()(__v, *--__prior)) {
// *prev(__hint) <= __v <= *__hint
if (__hint.__ptr_->__left_ == nullptr) {
- __parent = static_cast<__end_node_pointer>(__hint.__ptr_);
+ __parent = __hint.__ptr_;
return __parent->__left_;
} else {
- __parent = static_cast<__end_node_pointer>(__prior.__ptr_);
+ __parent = __prior.__ptr_;
return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
}
}
@@ -1639,7 +1638,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(__end_node_pointer& __parent, co
__nd_ptr = std::addressof(__nd->__left_);
__nd = static_cast<__node_pointer>(__nd->__left_);
} else {
- __parent = static_cast<__end_node_pointer>(__nd);
+ __parent = __nd;
return __parent->__left_;
}
} else if (value_comp()(__nd->__value_, __v)) {
@@ -1647,11 +1646,11 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(__end_node_pointer& __parent, co
__nd_ptr = std::addressof(__nd->__right_);
__nd = static_cast<__node_pointer>(__nd->__right_);
} else {
- __parent = static_cast<__end_node_pointer>(__nd);
+ __parent = __nd;
return __nd->__right_;
}
} else {
- __parent = static_cast<__end_node_pointer>(__nd);
+ __parent = __nd;
return *__nd_ptr;
}
}
@@ -1719,7 +1718,7 @@ void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
// __new_node->__is_black_ is initialized in __tree_balance_after_insert
__child = __new_node;
if (__begin_node_->__left_ != nullptr)
- __begin_node_ = static_cast<__end_node_pointer>(__begin_node_->__left_);
+ __begin_node_ = __begin_node_->__left_;
std::__tree_balance_after_insert(__end_node()->__left_, __child);
++__size_;
}
@@ -1734,7 +1733,7 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _A
bool __inserted = false;
if (__child == nullptr) {
__node_holder __h = __construct_node(std::forward<_Args>(__args)...);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+ __insert_node_at(__parent, __child, __h.get());
__r = __h.release();
__inserted = true;
}
@@ -1753,7 +1752,7 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
bool __inserted = false;
if (__child == nullptr) {
__node_holder __h = __construct_node(std::forward<_Args>(__args)...);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+ __insert_node_at(__parent, __child, __h.get());
__r = __h.release();
__inserted = true;
}
@@ -1781,7 +1780,7 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) {
__node_pointer __r = static_cast<__node_pointer>(__child);
bool __inserted = false;
if (__child == nullptr) {
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+ __insert_node_at(__parent, __child, __h.get());
__r = __h.release();
__inserted = true;
}
@@ -1798,7 +1797,7 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p
__node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
__node_pointer __r = static_cast<__node_pointer>(__child);
if (__child == nullptr) {
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+ __insert_node_at(__parent, __child, __h.get());
__r = __h.release();
}
return iterator(__r);
@@ -1811,8 +1810,8 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) {
__node_holder __h = __construct_node(std::forward<_Args>(__args)...);
__end_node_pointer __parent;
__node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
- return iterator(static_cast<__node_pointer>(__h.release()));
+ __insert_node_at(__parent, __child, __h.get());
+ return iterator(__h.release());
}
template <class _Tp, class _Compare, class _Allocator>
@@ -1822,8 +1821,8 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Arg
__node_holder __h = __construct_node(std::forward<_Args>(__args)...);
__end_node_pointer __parent;
__node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
- return iterator(static_cast<__node_pointer>(__h.release()));
+ __insert_node_at(__parent, __child, __h.get());
+ return iterator(__h.release());
}
template <class _Tp, class _Compare, class _Allocator>
@@ -1835,7 +1834,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const value_type& __v, _
bool __inserted = false;
if (__child == nullptr) {
__assign_value(__nd->__value_, __v);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
+ __insert_node_at(__parent, __child, __nd);
__r = __nd;
__inserted = true;
}
@@ -1847,7 +1846,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) {
__end_node_pointer __parent;
__node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
+ __insert_node_at(__parent, __child, __nd);
return iterator(__nd);
}
@@ -1856,7 +1855,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) {
__end_node_pointer __parent;
__node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
+ __insert_node_at(__parent, __child, __nd);
return iterator(__nd);
}
@@ -1886,7 +1885,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __n
if (__child != nullptr)
return _InsertReturnType{iterator(static_cast<__node_pointer>(__child)), false, std::move(__nh)};
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+ __insert_node_at(__parent, __child, __ptr);
__nh.__release_ptr();
return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
}
@@ -1904,7 +1903,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __
__node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, __ptr->__value_);
__node_pointer __r = static_cast<__node_pointer>(__child);
if (__child == nullptr) {
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+ __insert_node_at(__parent, __child, __ptr);
__r = __ptr;
__nh.__release_ptr();
}
@@ -1941,7 +1940,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merg
if (__child != nullptr)
continue;
__source.__remove_node_pointer(__src_ptr);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr));
+ __insert_node_at(__parent, __child, __src_ptr);
}
}
@@ -1954,7 +1953,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh
__node_pointer __ptr = __nh.__ptr_;
__end_node_pointer __parent;
__node_base_pointer& __child = __find_leaf_high(__parent, __ptr->__value_);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+ __insert_node_at(__parent, __child, __ptr);
__nh.__release_ptr();
return iterator(__ptr);
}
@@ -1969,7 +1968,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(const_iterator __h
__node_pointer __ptr = __nh.__ptr_;
__end_node_pointer __parent;
__node_base_pointer& __child = __find_leaf(__hint, __parent, __ptr->__value_);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+ __insert_node_at(__parent, __child, __ptr);
__nh.__release_ptr();
return iterator(__ptr);
}
@@ -1985,7 +1984,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merg
__node_base_pointer& __child = __find_leaf_high(__parent, __src_ptr->__value_);
++__i;
__source.__remove_node_pointer(__src_ptr);
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr));
+ __insert_node_at(__parent, __child, __src_ptr);
}
}
@@ -2074,13 +2073,13 @@ __tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const {
__node_pointer __rt = __root();
while (__rt != nullptr) {
if (value_comp()(__k, __rt->__value_)) {
- __result = static_cast<__end_node_pointer>(__rt);
+ __result = __rt;
__rt = static_cast<__node_pointer>(__rt->__left_);
} else if (value_comp()(__rt->__value_, __k))
__rt = static_cast<__node_pointer>(__rt->__right_);
else
return std::distance(
- __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
+ __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),
__upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
}
return 0;
@@ -2092,7 +2091,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
while (__root != nullptr) {
if (!value_comp()(__root->__value_, __v)) {
- __result = static_cast<__end_node_pointer>(__root);
+ __result = __root;
__root = static_cast<__node_pointer>(__root->__left_);
} else
__root = static_cast<__node_pointer>(__root->__right_);
@@ -2106,7 +2105,7 @@ typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare,
const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
while (__root != nullptr) {
if (!value_comp()(__root->__value_, __v)) {
- __result = static_cast<__end_node_pointer>(__root);
+ __result = __root;
__root = static_cast<__node_pointer>(__root->__left_);
} else
__root = static_cast<__node_pointer>(__root->__right_);
@@ -2120,7 +2119,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
while (__root != nullptr) {
if (value_comp()(__v, __root->__value_)) {
- __result = static_cast<__end_node_pointer>(__root);
+ __result = __root;
__root = static_cast<__node_pointer>(__root->__left_);
} else
__root = static_cast<__node_pointer>(__root->__right_);
@@ -2134,7 +2133,7 @@ typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare,
const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
while (__root != nullptr) {
if (value_comp()(__v, __root->__value_)) {
- __result = static_cast<__end_node_pointer>(__root);
+ __result = __root;
__root = static_cast<__node_pointer>(__root->__left_);
} else
__root = static_cast<__node_pointer>(__root->__right_);
@@ -2151,14 +2150,12 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) {
__node_pointer __rt = __root();
while (__rt != nullptr) {
if (value_comp()(__k, __rt->__value_)) {
- __result = static_cast<__end_node_pointer>(__rt);
+ __result = __rt;
__rt = static_cast<__node_pointer>(__rt->__left_);
} else if (value_comp()(__rt->__value_, __k))
__rt = static_cast<__node_pointer>(__rt->__right_);
else
- return _Pp(iterator(__rt),
- iterator(__rt->__right_ != nullptr ? static_cast<__end_node_pointer>(std::__tree_min(__rt->__right_))
- : __result));
+ return _Pp(iterator(__rt), iterator(__rt->__right_ != nullptr ? std::__tree_min(__rt->__right_) : __result));
}
return _Pp(iterator(__result), iterator(__result));
}
@@ -2173,15 +2170,13 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const {
__node_pointer __rt = __root();
while (__rt != nullptr) {
if (value_comp()(__k, __rt->__value_)) {
- __result = static_cast<__end_node_pointer>(__rt);
+ __result = __rt;
__rt = static_cast<__node_pointer>(__rt->__left_);
} else if (value_comp()(__rt->__value_, __k))
__rt = static_cast<__node_pointer>(__rt->__right_);
else
- return _Pp(
- const_iterator(__rt),
- const_iterator(
- __rt->__right_ != nullptr ? static_cast<__end_node_pointer>(std::__tree_min(__rt->__right_)) : __result));
+ return _Pp(const_iterator(__rt),
+ const_iterator(__rt->__right_ != nullptr ? std::__tree_min(__rt->__right_) : __result));
}
return _Pp(const_iterator(__result), const_iterator(__result));
}
@@ -2195,12 +2190,12 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) {
__node_pointer __rt = __root();
while (__rt != nullptr) {
if (value_comp()(__k, __rt->__value_)) {
- __result = static_cast<__end_node_pointer>(__rt);
+ __result = __rt;
__rt = static_cast<__node_pointer>(__rt->__left_);
} else if (value_comp()(__rt->__value_, __k))
__rt = static_cast<__node_pointer>(__rt->__right_);
else
- return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
+ return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),
__upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
}
return _Pp(iterator(__result), iterator(__result));
@@ -2216,12 +2211,12 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const {
__node_pointer __rt = __root();
while (__rt != nullptr) {
if (value_comp()(__k, __rt->__value_)) {
- __result = static_cast<__end_node_pointer>(__rt);
+ __result = __rt;
__rt = static_cast<__node_pointer>(__rt->__left_);
} else if (value_comp()(__rt->__value_, __k))
__rt = static_cast<__node_pointer>(__rt->__right_);
else
- return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
+ return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),
__upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
}
return _Pp(const_iterator(__result), const_iterator(__result));
@@ -2233,9 +2228,9 @@ __tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT {
__node_pointer __np = __p.__get_np();
if (__begin_node_ == __p.__ptr_) {
if (__np->__right_ != nullptr)
- __begin_node_ = static_cast<__end_node_pointer>(__np->__right_);
+ __begin_node_ = __np->__right_;
else
- __begin_node_ = static_cast<__end_node_pointer>(__np->__parent_);
+ __begin_node_ = __np->__parent_;
}
--__size_;
std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np));
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 6daa7fbbc03c2..c783ff4a96460 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -363,7 +363,7 @@ class __forward_list_iterator {
_LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
- : __ptr_(std::__static_fancy_pointer_cast<__begin_node_pointer>(__p)) {}
+ : __ptr_(__p) {}
template <class, class>
friend class forward_list;
@@ -380,14 +380,14 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference operator*() const {
- return std::__static_fancy_pointer_cast<__node_pointer>(__ptr_)->__get_value();
+ return static_cast<__node_pointer>(__ptr_)->__get_value();
}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
- return pointer_traits<pointer>::pointer_to(std::__static_fancy_pointer_cast<__node_pointer>(__ptr_)->__get_value());
+ return pointer_traits<pointer>::pointer_to(static_cast<__node_pointer>(__ptr_)->__get_value());
}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __forward_list_iterator& operator++() {
- __ptr_ = std::__static_fancy_pointer_cast<__begin_node_pointer>(__ptr_->__next_);
+ __ptr_ = __ptr_->__next_;
return *this;
}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __forward_list_iterator operator++(int) {
@@ -425,10 +425,6 @@ class __forward_list_const_iterator {
_LIBCPP_CONSTEXPR_SINCE_CXX26
_LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
- _LIBCPP_CONSTEXPR_SINCE_CXX26
- _LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
- : __ptr_(std::__static_fancy_pointer_cast<__begin_node_pointer>(__p)) {}
-
template <class, class>
friend class forward_list;
@@ -444,14 +440,14 @@ public:
__forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference operator*() const {
- return std::__static_fancy_pointer_cast<__node_pointer>(__ptr_)->__get_value();
+ return static_cast<__node_pointer>(__ptr_)->__get_value();
}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
- return pointer_traits<pointer>::pointer_to(std::__static_fancy_pointer_cast<__node_pointer>(__ptr_)->__get_value());
+ return pointer_traits<pointer>::pointer_to(static_cast<__node_pointer>(__ptr_)->__get_value());
}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator& operator++() {
- __ptr_ = std::__static_fancy_pointer_cast<__begin_node_pointer>(__ptr_->__next_);
+ __ptr_ = __ptr_->__next_;
return *this;
}
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator operator++(int) {
@@ -943,8 +939,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 inline forward_list<_Tp, _Alloc>::forward_list(con
template <class _Tp, class _Alloc>
_LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type __n) {
if (__n > 0) {
- for (__begin_node_pointer __p = __base::__before_begin(); __n > 0;
- --__n, __p = std::__static_fancy_pointer_cast<__begin_node_pointer>(__p->__next_)) {
+ for (__begin_node_pointer __p = __base::__before_begin(); __n > 0; --__n, __p = __p->__next_) {
__p->__next_ = this->__create_node(/* next = */ nullptr);
}
}
@@ -955,8 +950,7 @@ template <class _Tp, class _Alloc>
_LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __base_alloc)
: __base(__base_alloc) {
if (__n > 0) {
- for (__begin_node_pointer __p = __base::__before_begin(); __n > 0;
- --__n, __p = std::__static_fancy_pointer_cast<__begin_node_pointer>(__p->__next_)) {
+ for (__begin_node_pointer __p = __base::__before_begin(); __n > 0; --__n, __p = __p->__next_) {
__p->__next_ = this->__create_node(/* next = */ nullptr);
}
}
@@ -1198,7 +1192,7 @@ forward_list<_Tp, _Alloc>::__insert_after(const_iterator __p, size_type __n, _Ar
# endif // _LIBCPP_HAS_EXCEPTIONS
__last->__next_ = __r->__next_;
__r->__next_ = __first;
- __r = std::__static_fancy_pointer_cast<__begin_node_pointer>(__last);
+ __r = __last;
}
return iterator(__r);
}
@@ -1239,7 +1233,7 @@ forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _Inp
__last->__next_ = __r->__next_;
__r->__next_ = __first;
- __r = std::__static_fancy_pointer_cast<__begin_node_pointer>(__last);
+ __r = __last;
}
return iterator(__r);
@@ -1258,7 +1252,7 @@ forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) {
template <class _Tp, class _Alloc>
_LIBCPP_CONSTEXPR_SINCE_CXX26 typename forward_list<_Tp, _Alloc>::iterator
forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) {
- __node_pointer __e = std::__static_fancy_pointer_cast<__node_pointer>(__l.__ptr_);
+ __node_pointer __e = static_cast<__node_pointer>(__l.__ptr_);
if (__f != __l) {
__begin_node_pointer __bp = __f.__ptr_;
@@ -1324,7 +1318,7 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list& /*__ot
if (__p != __i && __p != __lm1) {
__i.__ptr_->__next_ = __lm1.__ptr_->__next_;
__lm1.__ptr_->__next_ = __p.__ptr_->__next_;
- __p.__ptr_->__next_ = std::__static_fancy_pointer_cast<__node_pointer>(__lm1.__ptr_);
+ __p.__ptr_->__next_ = static_cast<__node_pointer>(__lm1.__ptr_);
}
}
@@ -1338,7 +1332,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void forward_list<_Tp, _Alloc>::splice_after(
if (__f != __lm1) {
__lm1.__ptr_->__next_ = __p.__ptr_->__next_;
__p.__ptr_->__next_ = __f.__ptr_->__next_;
- __f.__ptr_->__next_ = std::__static_fancy_pointer_cast<__node_pointer>(__l.__ptr_);
+ __f.__ptr_->__next_ = static_cast<__node_pointer>(__l.__ptr_);
}
}
}
@@ -1418,7 +1412,7 @@ forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) {
iterator __j = std::next(__i);
for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
++__count_removed;
- if (__i.__ptr_->__next_ != std::__static_fancy_pointer_cast<__node_pointer>(__j.__ptr_))
+ if (__i.__ptr_->__next_ != static_cast<__node_pointer>(__j.__ptr_))
__deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
__i = __j;
}
@@ -1498,7 +1492,7 @@ forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, _Co
}
difference_type __sz1 = __sz / 2;
difference_type __sz2 = __sz - __sz1;
- __node_pointer __t = std::__static_fancy_pointer_cast<__node_pointer>(std::next(iterator(__f1), __sz1 - 1).__ptr_);
+ __node_pointer __t = static_cast<__node_pointer>(std::next(iterator(__f1), __sz1 - 1).__ptr_);
__node_pointer __f2 = __t->__next_;
__t->__next_ = nullptr;
return __merge(__sort(__f1, __sz1, __comp), __sort(__f2, __sz2, __comp), __comp);
diff --git a/libcxx/test/support/min_allocator.h b/libcxx/test/support/min_allocator.h
index 16775649f55cf..f4b8cf17cc2de 100644
--- a/libcxx/test/support/min_allocator.h
+++ b/libcxx/test/support/min_allocator.h
@@ -221,6 +221,13 @@ class min_pointer {
TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
TEST_CONSTEXPR_CXX14 explicit min_pointer(min_pointer<void, ID> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {}
+ template <class U, std::enable_if<std::is_convertible<U*, T*>::value, int>::type = 0>
+ TEST_CONSTEXPR_CXX14 min_pointer(min_pointer<U, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
+
+ template <class U,
+ std::enable_if<!std::is_convertible<U*, T*>::value && std::is_constructible<U*, T*>::value, int>::type = 0>
+ explicit TEST_CONSTEXPR_CXX14 min_pointer(min_pointer<U, ID> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {}
+
TEST_CONSTEXPR_CXX14 explicit operator bool() const { return ptr_ != nullptr; }
typedef std::ptrdiff_t difference_type;
More information about the libcxx-commits
mailing list