[libcxx-commits] [libcxx] 57bf5dd - [libc++][tuple.apply] Implement P2255R2 make_from_tuple part. (#152867)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Aug 19 03:14:16 PDT 2025
Author: yronglin
Date: 2025-08-19T18:14:13+08:00
New Revision: 57bf5dd7a01f87cab3d659e91a2a5dc42e8eaf53
URL: https://github.com/llvm/llvm-project/commit/57bf5dd7a01f87cab3d659e91a2a5dc42e8eaf53
DIFF: https://github.com/llvm/llvm-project/commit/57bf5dd7a01f87cab3d659e91a2a5dc42e8eaf53.diff
LOG: [libc++][tuple.apply] Implement P2255R2 make_from_tuple part. (#152867)
Implement P2255R2 tuple.apply part wording for `std::make_from_tuple`.
```
Mandates: If tuple_size_v<remove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false.
```
Fixes #154274
---------
Signed-off-by: yronglin <yronglin777 at gmail.com>
Added:
libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp
Modified:
libcxx/include/tuple
libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index be30ab5b2173d..b046e2aed43e2 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -1432,6 +1432,7 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t,
enable_if_t<is_constructible_v<_Tp, decltype(std::get<_Idx>(std::forward<_Tuple>(__t)))...>> * = nullptr)
_LIBCPP_NOEXCEPT_RETURN(_Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...))
#endif // _LIBCPP_STD_VER >= 20
+#undef _LIBCPP_NOEXCEPT_RETURN
template <class _Tp, class _Tuple,
class _Seq = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>, class = void>
@@ -1451,10 +1452,19 @@ template <class _Tp, class _Tuple>
#else
template <class _Tp, class _Tuple, class = enable_if_t<__can_make_from_tuple<_Tp, _Tuple>>> // strengthen
#endif // _LIBCPP_STD_VER >= 20
+
inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp make_from_tuple(_Tuple&& __t)
- _LIBCPP_NOEXCEPT_RETURN(std::__make_from_tuple_impl<_Tp>(
- std::forward<_Tuple>(__t), make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>()))
-# undef _LIBCPP_NOEXCEPT_RETURN
+ noexcept(noexcept(std::__make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
+ make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>()))) {
+#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
+ if constexpr (tuple_size_v<remove_reference_t<_Tuple>> == 1) {
+ static_assert(!std::reference_constructs_from_temporary_v<_Tp, decltype(std::get<0>(std::declval<_Tuple>()))>,
+ "Attempted construction of reference element binds to a temporary whose lifetime has ended");
+ }
+#endif // _LIBCPP_STD_VER >= 23
+ return std::__make_from_tuple_impl<_Tp>(
+ std::forward<_Tuple>(__t), make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>());
+}
# endif // _LIBCPP_STD_VER >= 17
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
index 2c14de8c796c1..8b9e94a1c1ad9 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
@@ -286,6 +286,8 @@ LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<float, std::tuple<double>>);
} // namespace LWG3528
+static_assert(LWG3528::can_make_from_tuple<int, std::tuple<>>);
+
int main(int, char**)
{
test_constexpr_construction();
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp
new file mode 100644
index 0000000000000..2dfbae9138864
--- /dev/null
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// <tuple>
+
+// template <class T, class Tuple> constexpr T make_from_tuple(Tuple&&);
+// Mandates: If tuple_size_v<remove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false.
+
+#include <tuple>
+#include <utility>
+
+#include "test_macros.h"
+
+void test() {
+ // FreeBSD ci use clang 19.1.1, which hasn't implement __reference_constructs_from_temporary.
+ // The static_assert inner std::make_from_tuple will not triggered.
+#if __has_builtin(__reference_constructs_from_temporary)
+ // expected-error@*:* {{static assertion failed}}
+#endif
+
+ // Turns to an error since C++26 (Disallow Binding a Returned Glvalue to a Temporary https://wg21.link/P2748R5).
+#if TEST_STD_VER >= 26
+ // expected-error at tuple:* {{returning reference to local temporary object}}
+#else
+ // expected-warning at tuple:* {{returning reference to local temporary object}}
+#endif
+ std::ignore = std::make_from_tuple<const int&>(std::tuple<char>{});
+}
More information about the libcxx-commits
mailing list