aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite
diff options
context:
space:
mode:
authorYihan Wang <yronglin777@gmail.com>2025-06-09 11:07:51 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2025-06-10 14:28:55 +0100
commit73edc003c0a8f0badc7027e6deefd3a573300b03 (patch)
treea7227214861794a45e186d807e8ee991c85a9007 /libstdc++-v3/testsuite
parent37b454b7e171bd8a792cbe4c57ea0f9702afa22d (diff)
downloadgcc-73edc003c0a8f0badc7027e6deefd3a573300b03.zip
gcc-73edc003c0a8f0badc7027e6deefd3a573300b03.tar.gz
gcc-73edc003c0a8f0badc7027e6deefd3a573300b03.tar.bz2
libstdc++: Implement LWG3528 make_from_tuple can perform (the equivalent of) a C-style cast
Implement LWG3528 to make std::make_from_tuple SFINAE friendly. libstdc++-v3/ChangeLog: * include/std/tuple (__can_make_from_tuple): New variable template. (__make_from_tuple_impl): Add static_assert. (make_from_tuple): Constrain using __can_make_from_tuple. * testsuite/20_util/tuple/dr3528.cc: New test. Signed-off-by: Yihan Wang <yronglin777@gmail.com> Co-authored-by: Jonathan Wakely <jwakely@redhat.com> Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
Diffstat (limited to 'libstdc++-v3/testsuite')
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/dr3528.cc46
1 files changed, 46 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/20_util/tuple/dr3528.cc b/libstdc++-v3/testsuite/20_util/tuple/dr3528.cc
new file mode 100644
index 0000000..c20ff95
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/dr3528.cc
@@ -0,0 +1,46 @@
+// { dg-do compile { target c++17 } }
+
+// LWG 3528. make_from_tuple can perform (the equivalent of) a C-style cast
+
+#include <tuple>
+#include <array>
+#include <utility>
+
+template<typename T, typename Tuple>
+using make_t = decltype(std::make_from_tuple<T>(std::declval<Tuple>()));
+
+template<typename T, typename Tuple, typename = void>
+constexpr bool can_make = false;
+template<typename T, typename Tuple>
+constexpr bool can_make<T, Tuple, std::void_t<make_t<T, Tuple>>> = true;
+
+static_assert( can_make<int, std::tuple<int>> );
+static_assert( can_make<int, std::tuple<int>&> );
+static_assert( can_make<int, const std::tuple<int>&> );
+static_assert( can_make<int, std::array<short, 1>> );
+static_assert( can_make<int, const std::array<short, 1>&&> );
+static_assert( can_make<std::tuple<int, int>, std::pair<unsigned, long>> );
+static_assert( can_make<std::pair<int, int>, std::array<int, 2>> );
+static_assert( can_make<const int*, std::tuple<int*>> );
+static_assert( can_make<void*, std::tuple<int*>> );
+static_assert( can_make<int, std::tuple<>> );
+static_assert( ! can_make<int, std::tuple<int, int>> );
+static_assert( ! can_make<int, std::pair<short, char>> );
+static_assert( ! can_make<int, std::pair<short, char>&> );
+static_assert( ! can_make<int, std::tuple<const char*>> );
+static_assert( ! can_make<int*, std::tuple<const int*>> );
+static_assert( ! can_make<int*, std::tuple<void*>> );
+static_assert( ! can_make<int, std::array<int, 2>> );
+static_assert( ! can_make<void, std::tuple<>> );
+static_assert( ! can_make<void, std::array<int, 1>> );
+
+struct Two
+{
+ Two(const char*, int);
+};
+
+static_assert( can_make<Two, std::tuple<char*, unsigned>> );
+static_assert( ! can_make<Two, std::tuple<const char*, int, int>> );
+static_assert( can_make<Two, std::pair<const char*, long>> );
+static_assert( ! can_make<Two, std::pair<int*, long>> );
+static_assert( ! can_make<std::pair<int, int>, std::array<int, 3>> );