[libc++] Simplify unique_ptr constructor SFINAE#201305
Merged
Merged
Conversation
|
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesThis patch does a couple of things:
1 Files Affected:
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 8fba2a4a1509d..32f9459f9fc2c 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -27,7 +27,6 @@
#include <__type_traits/add_reference.h>
#include <__type_traits/common_type.h>
#include <__type_traits/conditional.h>
-#include <__type_traits/dependent_type.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_array.h>
@@ -43,7 +42,7 @@
#include <__type_traits/is_trivially_relocatable.h>
#include <__type_traits/is_void.h>
#include <__type_traits/remove_extent.h>
-#include <__type_traits/type_identity.h>
+#include <__type_traits/remove_reference.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
#include <__utility/move.h>
@@ -95,28 +94,6 @@ inline const bool __is_default_deleter_v = false;
template <class _Tp>
inline const bool __is_default_deleter_v<default_delete<_Tp> > = true;
-template <class _Deleter>
-struct __unique_ptr_deleter_sfinae {
- static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
- typedef const _Deleter& __lval_ref_type;
- typedef _Deleter&& __good_rval_ref_type;
- typedef true_type __enable_rval_overload;
-};
-
-template <class _Deleter>
-struct __unique_ptr_deleter_sfinae<_Deleter const&> {
- typedef const _Deleter& __lval_ref_type;
- typedef const _Deleter&& __bad_rval_ref_type;
- typedef false_type __enable_rval_overload;
-};
-
-template <class _Deleter>
-struct __unique_ptr_deleter_sfinae<_Deleter&> {
- typedef _Deleter& __lval_ref_type;
- typedef _Deleter&& __bad_rval_ref_type;
- typedef false_type __enable_rval_overload;
-};
-
template <class, class = void>
inline const bool __can_dereference = false;
@@ -152,24 +129,6 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
private:
_LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);
- using _DeleterSFINAE _LIBCPP_NODEBUG = __unique_ptr_deleter_sfinae<_Dp>;
-
- template <bool _Dummy>
- using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
-
- template <bool _Dummy>
- using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
-
- template <bool _Dummy>
- using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
-
- template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>
- using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =
- __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;
-
- template <class _ArgType>
- using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;
-
template <class _UPtr, class _Up>
using _EnableIfMoveConvertible _LIBCPP_NODEBUG =
__enable_if_t< is_convertible<typename _UPtr::pointer, pointer>::value && !is_array<_Up>::value >;
@@ -183,31 +142,33 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;
public:
- template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+ template <class _Deleter = deleter_type,
+ __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(), __deleter_() {}
- template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+ template <class _Deleter = deleter_type,
+ __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(), __deleter_() {}
- template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+ template <class _Deleter = deleter_type,
+ __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT
: __ptr_(__p),
__deleter_() {}
- template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
+ template <class _Deleter = deleter_type, __enable_if_t<is_copy_constructible<_Deleter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, const deleter_type& __d) _NOEXCEPT
: __ptr_(__p),
__deleter_(__d) {}
- template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+ template <class _Deleter = deleter_type,
+ __enable_if_t<!is_reference<_Deleter>::value && is_move_constructible<_Deleter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, deleter_type&& __d) _NOEXCEPT
: __ptr_(__p),
- __deleter_(std::move(__d)) {
- static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
- }
+ __deleter_(std::move(__d)) {}
- template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
- _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
+ template <class _Deleter = deleter_type, __enable_if_t<is_reference<_Deleter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer, __libcpp_remove_reference_t<deleter_type>&&) = delete;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
: __ptr_(__u.release()),
@@ -441,27 +402,6 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> {
(is_same<pointer, element_type*>::value &&
is_convertible<_FromElem (*)[], element_type (*)[]>::value) > {};
- typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
-
- template <bool _Dummy>
- using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
-
- template <bool _Dummy>
- using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
-
- template <bool _Dummy>
- using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
-
- template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>
- using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =
- __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;
-
- template <class _ArgType>
- using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;
-
- template <class _Pp>
- using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< _CheckArrayPointerConversion<_Pp>::value >;
-
template <class _UPtr, class _Up, class _ElemT = typename _UPtr::element_type>
using _EnableIfMoveConvertible _LIBCPP_NODEBUG =
__enable_if_t< is_array<_Up>::value && is_same<pointer, element_type*>::value &&
@@ -477,17 +417,19 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> {
using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;
public:
- template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+ template <class _Deleter = deleter_type,
+ __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(), __deleter_() {}
- template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+ template <class _Deleter = deleter_type,
+ __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(), __deleter_() {}
- template <class _Pp,
- bool _Dummy = true,
- class = _EnableIfDeleterDefaultConstructible<_Dummy>,
- class = _EnableIfPointerConvertible<_Pp> >
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __ptr) _NOEXCEPT
+ template <class _Ptr,
+ class _Deleter = deleter_type,
+ __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value, int> = 0,
+ __enable_if_t<_CheckArrayPointerConversion<_Ptr>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Ptr __ptr) _NOEXCEPT
: __ptr_(__ptr),
__deleter_() {}
@@ -497,43 +439,38 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> {
: __ptr_(__ptr),
__checker_(__size) {}
- template <class _Pp,
- bool _Dummy = true,
- class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
- class = _EnableIfPointerConvertible<_Pp> >
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __ptr, _LValRefType<_Dummy> __deleter) _NOEXCEPT
+ template <class _Ptr,
+ class _Deleter = deleter_type,
+ __enable_if_t<is_copy_constructible<_Deleter>::value, int> = 0,
+ __enable_if_t<_CheckArrayPointerConversion<_Ptr>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Ptr __ptr, const deleter_type& __deleter) _NOEXCEPT
: __ptr_(__ptr),
__deleter_(__deleter) {}
- template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __deleter) _NOEXCEPT
+ template <class _Deleter = deleter_type, __enable_if_t<is_copy_constructible<_Deleter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, const deleter_type& __deleter) _NOEXCEPT
: __ptr_(nullptr),
__deleter_(__deleter) {}
- template <class _Pp,
- bool _Dummy = true,
- class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
- class = _EnableIfPointerConvertible<_Pp> >
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
- unique_ptr(_Pp __ptr, _GoodRValRefType<_Dummy> __deleter) _NOEXCEPT
+ template <class _Ptr,
+ class _Deleter = deleter_type,
+ __enable_if_t<!is_reference<_Deleter>::value && is_move_constructible<_Deleter>::value, int> = 0,
+ __enable_if_t<_CheckArrayPointerConversion<_Ptr>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Ptr __ptr, deleter_type&& __deleter) _NOEXCEPT
: __ptr_(__ptr),
- __deleter_(std::move(__deleter)) {
- static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
- }
+ __deleter_(std::move(__deleter)) {}
- template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
- unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __deleter) _NOEXCEPT
+ template <class _Deleter = deleter_type,
+ __enable_if_t<!is_reference<_Deleter>::value && is_move_constructible<_Deleter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, deleter_type&& __deleter) _NOEXCEPT
: __ptr_(nullptr),
- __deleter_(std::move(__deleter)) {
- static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
- }
+ __deleter_(std::move(__deleter)) {}
- template <class _Pp,
- bool _Dummy = true,
- class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
- class = _EnableIfPointerConvertible<_Pp> >
- _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __ptr, _BadRValRefType<_Dummy> __deleter) = delete;
+ template <class _Ptr,
+ class _Deleter = deleter_type,
+ __enable_if_t<is_reference<_Deleter>::value, int> = 0,
+ __enable_if_t<_CheckArrayPointerConversion<_Ptr>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI unique_ptr(_Ptr, __libcpp_remove_reference_t<deleter_type>&&) = delete;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
: __ptr_(__u.release()),
|
frederick-vs-ja
approved these changes
Jun 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This patch does a couple of things:
__enable_if_ts, making it easier to understand what's actually going onenable_ifs dependent via aclass _Deleter = deleter_typeinstead of abooland__dependent_type, reducing the number of instantiated classes__unique_ptr_deleter_sfinae