From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id CE0793858404 for ; Tue, 24 Jan 2023 23:51:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CE0793858404 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1674604317; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=JpptHDMDv3NZ+XLIfGtOmWEQYEpH/wr+L4ScME0EyG4=; b=RwwahM1N1iWWPpUwV5CZUV6x5qXj3e8rvhV0T6sKR8KkElhPLC1Rrnou3/hU0JoI0pYnTX vHNFqKotdv4zKxiCN1mnXdRAtaCDe4dBK75K1ah7/y2wkx/4qU8Pfn8c14Yqvc7gOBmfZg bOB9b5W3ww51nuGj8yMLiSgIV7SXsYc= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-128-gxoBOAtaOpeu1ZmY8e42qA-1; Tue, 24 Jan 2023 18:51:54 -0500 X-MC-Unique: gxoBOAtaOpeu1ZmY8e42qA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1811C85A588; Tue, 24 Jan 2023 23:51:54 +0000 (UTC) Received: from localhost (unknown [10.33.36.201]) by smtp.corp.redhat.com (Postfix) with ESMTP id CD51D1121330; Tue, 24 Jan 2023 23:51:53 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Include std::ranges::subrange definition in [PR102301] Date: Tue, 24 Jan 2023 23:51:53 +0000 Message-Id: <20230124235153.1186124-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Tested x86_64-linux. Pushed to trunk. -- >8 -- In order for std::make_from_tuple to work with tuple-like types, the overloads of std::get for those types must have been declared before the definition of std::make_from_tuple. That means we need to include the definition of std::ranges::subrange in . The definitions of std::pair and its overloads of std::get are already included in . We provide forward declarations of std::array and its std::get overloads in . We could just declare subrange without defining it, and give ranges::get a non-deduced return type, like so: namespace ranges { enum class subrange_kind : bool { unsized, sized}; template S, subrange_kind K> requires (K == subrange_kind::sized || !sized_sentinel_for) class subrange; template requires (_Num < 2) constexpr __conditional_t<_Num == 0, _It, _Sent> get(const subrange<_It, _Sent, _Kind>& __r); template requires (_Num < 2) constexpr __conditional_t<_Num == 0, _It, _Sent> get(subrange<_It, _Sent, _Kind>&& __r) } using ranges::get; It is a bit late in the GCC 13 dev cycle to do this, so just include the right headers for now. Also add the dangling check to std::make_from_tuple added by P2255. libstdc++-v3/ChangeLog: PR libstdc++/102301 * include/bits/ranges_base.h: Include for std::make_reverse_iterator. * include/std/tuple: Include for subrange. (make_from_tuple): Add static assertion from P2255 to diagnose dangling references. * testsuite/20_util/tuple/make_from_tuple/dangling_ref.cc: New test. * testsuite/20_util/tuple/make_from_tuple/tuple_like.cc: New test. --- libstdc++-v3/include/bits/ranges_base.h | 2 +- libstdc++-v3/include/std/tuple | 16 +++++-- .../tuple/make_from_tuple/dangling_ref.cc | 5 +++ .../tuple/make_from_tuple/tuple_like.cc | 43 +++++++++++++++++++ 4 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/dangling_ref.cc create mode 100644 libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/tuple_like.cc diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 26b3a983f72..86952b34096 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 -#include +#include #include #include diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 3d82ed1c370..c773b3a348b 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -37,10 +37,11 @@ #include // for std::pair #include // for std::allocator_arg_t -#include // for std::get, std::tuple_size etc. +#include // for std::tuple_size etc. #include // for std::__invoke #if __cplusplus > 201703L # include +# include // 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) { - return __make_from_tuple_impl<_Tp>( - std::forward<_Tuple>(__t), - make_index_sequence>>{}); + constexpr size_t __n = tuple_size_v>; +#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 00000000000..7958ec888a3 --- /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 +std::tuple f(); +auto t = std::make_from_tuple(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 00000000000..de694554d86 --- /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 +#include + +struct Two +{ + Two(const char*, int); +}; + +void +test_pair() +{ + auto two = std::make_from_tuple(std::pair("one", 2)); + static_assert(std::is_same_v, "make from pair"); +} + +#include + +struct Three +{ + Three(int, int, int); +}; + +void +test_array() +{ + Three three = std::make_from_tuple(std::array{{1, 2, 3}}); + static_assert(std::is_same_v, "make from array"); +} + +#if __cplusplus >= 202002L +#include +#include + +void +test_subrange() // PR libstdc++/102301 +{ + auto r = std::views::iota(0, 5); + auto v = std::make_from_tuple>(std::ranges::subrange(r)); + static_assert(std::is_same_v>, "from subrange"); +} +#endif -- 2.39.1