diff options
author | Yihan Wang <yronglin777@gmail.com> | 2025-06-09 11:07:51 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2025-06-10 14:28:55 +0100 |
commit | 73edc003c0a8f0badc7027e6deefd3a573300b03 (patch) | |
tree | a7227214861794a45e186d807e8ee991c85a9007 /libstdc++-v3/testsuite | |
parent | 37b454b7e171bd8a792cbe4c57ea0f9702afa22d (diff) | |
download | gcc-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.cc | 46 |
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>> ); |