[libcxx-commits] [libcxx] [libc++] P2255R2: Add deleted tuple constructor overloads (PR #205379)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Aug 16 05:22:56 PDT 2026
================
@@ -614,21 +614,77 @@ public:
: _And<_Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
is_constructible<_Tp, _Up>... > {};
- template <class... _Up,
- __enable_if_t< _And< _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, _EnableUTypesCtor<_Up...> >::value,
- int> = 0>
+ template <class... _Up>
+ struct _EnableUTypesCtorBase : _And<_BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, _EnableUTypesCtor<_Up...> > {};
+
+ template <bool, class... _Up>
+ struct _EnableUTypesCtorNoDangling : false_type {};
+
+# if _LIBCPP_STD_VER >= 23
+ template <class... _Up>
+ static constexpr bool __has_danglings() {
+ if constexpr (sizeof...(_Up) == sizeof...(_Tp))
+ return (__reference_constructs_from_temporary_v<_Tp, _Up&&> || ...);
+ else
+ return false;
+ }
+
+ template <class _Source, class _DecayedSource = __remove_cvref_t<_Source> >
+ static constexpr bool __has_danglings_from_tuple_like = false;
+
+ template <class _Source, class... _Up>
+ static constexpr bool __has_danglings_from_tuple_like<_Source, tuple<_Up...> > =
+ __has_danglings<__copy_cvref_t<_Source, _Up>...>();
+
+ template <class _Source, class _U1, class _U2>
+ static constexpr bool __has_danglings_from_tuple_like<_Source, pair<_U1, _U2> > =
+ __has_danglings<__copy_cvref_t<_Source, _U1>, __copy_cvref_t<_Source, _U2> >();
+
+ template <bool __dangles, class _CtorEnabled>
+ static constexpr bool __check_danglings_from_constructor = false;
+
+ template <class _CtorEnabled>
+ static constexpr bool __check_danglings_from_constructor<true, _CtorEnabled> = _CtorEnabled::value;
+
+ template <bool __dangles, class _CtorEnabled>
+ static constexpr bool __check_no_danglings_from_constructor = _CtorEnabled::value;
+
+ template <class _CtorEnabled>
+ static constexpr bool __check_no_danglings_from_constructor<true, _CtorEnabled> = false;
+
+ template <class... _Up>
+ static constexpr bool __has_danglings_from_utypes =
+ __check_danglings_from_constructor<__has_danglings<_Up...>(), _EnableUTypesCtorBase<_Up...> >;
+
+ template <class... _Up>
+ static constexpr bool __has_no_danglings_from_utypes =
+ __check_no_danglings_from_constructor<__has_danglings<_Up...>(), _EnableUTypesCtorBase<_Up...> >;
+# else
+ template <class... _Up>
+ static constexpr bool __has_no_danglings_from_utypes = _EnableUTypesCtorBase<_Up...>::value;
+# endif // _LIBCPP_STD_VER >= 23
+
+ template <class... _Up, __enable_if_t< __has_no_danglings_from_utypes<_Up...>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_And<is_convertible<_Up, _Tp>...>::value)
tuple(_Up&&... __u) noexcept(_And<is_nothrow_constructible<_Tp, _Up>...>::value)
: __base_(__forward_args{}, std::forward<_Up>(__u)...) {}
- template <class _Alloc,
- class... _Up,
- __enable_if_t< _And< _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, _EnableUTypesCtor<_Up...> >::value,
- int> = 0>
+ template <class _Alloc, class... _Up, __enable_if_t< __has_no_danglings_from_utypes<_Up...>, int> = 0>
----------------
philnik777 wrote:
If you constrain them in the same way you get the same behaviour: https://godbolt.org/z/qoET3j5cc.
https://github.com/llvm/llvm-project/pull/205379
More information about the libcxx-commits
mailing list