[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