aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/include/bits/ranges_base.h2
-rw-r--r--libstdc++-v3/include/std/tuple16
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/dangling_ref.cc5
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/tuple_like.cc43
4 files changed, 61 insertions, 5 deletions
diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h
index 26b3a98..86952b3 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -34,7 +34,7 @@
#if __cplusplus > 201703L
#include <initializer_list>
-#include <bits/iterator_concepts.h>
+#include <bits/stl_iterator.h>
#include <ext/numeric_traits.h>
#include <bits/max_size_type.h>
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 3d82ed1..c773b3a 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -37,10 +37,11 @@
#include <bits/stl_pair.h> // for std::pair
#include <bits/uses_allocator.h> // for std::allocator_arg_t
-#include <bits/utility.h> // for std::get, std::tuple_size etc.
+#include <bits/utility.h> // for std::tuple_size etc.
#include <bits/invoke.h> // for std::__invoke
#if __cplusplus > 201703L
# include <compare>
+# include <bits/ranges_util.h> // for std::ranges::subrange
# define __cpp_lib_constexpr_tuple 201811L
#endif
@@ -2312,9 +2313,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
make_from_tuple(_Tuple&& __t)
noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
{
- return __make_from_tuple_impl<_Tp>(
- std::forward<_Tuple>(__t),
- make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{});
+ constexpr size_t __n = tuple_size_v<remove_reference_t<_Tuple>>;
+#if __has_builtin(__reference_constructs_from_temporary)
+ if constexpr (__n == 1)
+ {
+ using _Elt = decltype(std::get<0>(std::declval<_Tuple>()));
+ static_assert(!__reference_constructs_from_temporary(_Tp, _Elt));
+ }
+#endif
+ return __make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
+ make_index_sequence<__n>{});
}
#endif // C++17
diff --git a/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/dangling_ref.cc b/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/dangling_ref.cc
new file mode 100644
index 0000000..7958ec8
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/dangling_ref.cc
@@ -0,0 +1,5 @@
+// { dg-do compile { target c++17 } }
+#include <tuple>
+std::tuple<short> f();
+auto t = std::make_from_tuple<const int&>(f()); // { dg-error "here" }
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/tuple_like.cc b/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/tuple_like.cc
new file mode 100644
index 0000000..de69455
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/tuple_like.cc
@@ -0,0 +1,43 @@
+// { dg-do compile { target c++17 } }
+
+#include <tuple>
+#include <utility>
+
+struct Two
+{
+ Two(const char*, int);
+};
+
+void
+test_pair()
+{
+ auto two = std::make_from_tuple<Two>(std::pair("one", 2));
+ static_assert(std::is_same_v<decltype(two), Two>, "make from pair");
+}
+
+#include <array>
+
+struct Three
+{
+ Three(int, int, int);
+};
+
+void
+test_array()
+{
+ Three three = std::make_from_tuple<Three>(std::array<int, 3>{{1, 2, 3}});
+ static_assert(std::is_same_v<decltype(three), Three>, "make from array");
+}
+
+#if __cplusplus >= 202002L
+#include <vector>
+#include <ranges>
+
+void
+test_subrange() // PR libstdc++/102301
+{
+ auto r = std::views::iota(0, 5);
+ auto v = std::make_from_tuple<std::vector<int>>(std::ranges::subrange(r));
+ static_assert(std::is_same_v<decltype(v), std::vector<int>>, "from subrange");
+}
+#endif