From patchwork Sat Nov 9 02:07:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Smith-Rowland, Edward M" X-Patchwork-Id: 1192352 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-512873-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=alionscience.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="clrEmm86"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4790sj33w5z9sPF for ; Sat, 9 Nov 2019 13:08:07 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:content-type:mime-version; q=dns; s=default; b=buy7lzxwzVcPAeMne9AdL0OrAPJZ1Dq6r75m592ZZSFp0IbN3h fIhTEJB00PSJfvWOlld51k6PyGAumU+NMqEzv2fm/J5xltsaVp73FYIN9KIkhuY5 TSG4du1oxHjFn6Hg5CpOxEfP8ofMJORGy+gwKv6leIxvsaHistYSBH/Aw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:content-type:mime-version; s= default; bh=a9ZGUA25k0aIgHZiVGZGj6DHfhk=; b=clrEmm8656OZq0KO4KPR eR7TkLnk3KArV7gmIf6VOOClKaVPJfcP0uclKa2SLVpZnSooJBYHGyQ389Hn7KEh aWqSUg88kZjWN5MI1KgATPime758ig+GmgIXadua6a0+E5IQ+HAWbU6gk9vvKXXV 11Cqt9Lqou/Z2Z14R4x7ijs= Received: (qmail 129404 invoked by alias); 9 Nov 2019 02:07:50 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 129389 invoked by uid 89); 9 Nov 2019 02:07:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-6.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=7466, 3227, 7076 X-HELO: mfilt2.alionscience.com Received: from mfilt2.alionscience.com (HELO mfilt2.alionscience.com) (192.104.146.194) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 09 Nov 2019 02:07:46 +0000 Received: from mfilt2.alionscience.com (127.0.0.1) id hoofn20171sg; Fri, 8 Nov 2019 21:07:44 -0500 (envelope-from ) Received: from noc-cas1.alionscience.com ([205.167.170.4]) by mfilt2.alionscience.com ([192.104.146.194]) (SonicWall 10.0.1.1213) with ESMTP id o201911090207440265887-66; Fri, 08 Nov 2019 21:07:44 -0500 Received: from NOC-MBX07.alionscience.com (172.20.3.236) by NOC-MBX06.alionscience.com (172.20.3.235) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1591.10; Fri, 8 Nov 2019 21:07:43 -0500 Received: from NOC-MBX07.alionscience.com ([fe80::cd73:84f:ff0b:b766]) by NOC-MBX07.alionscience.com ([fe80::cd73:84f:ff0b:b766%6]) with mapi id 15.01.1591.017; Fri, 8 Nov 2019 21:07:43 -0500 From: "Smith-Rowland, Edward M" To: "libstdc++@gcc.gnu.org" , "gcc-patches@gcc.gnu.org" , "jwakely@redhat.com" CC: "Ed Smith-Rowland (3dw4rd@verizon.net)" <3dw4rd@verizon.net> Subject: Implement the part of C++20 p1032 Misc constexpr bits. Date: Sat, 9 Nov 2019 02:07:43 +0000 Message-ID: MIME-Version: 1.0 X-Mlf-DSE-Version: 5813 X-Mlf-Rules-Version: s20191106221030; ds20171117204456; di20191025164238; ri20160318003319; fs20191107232316 X-Mlf-Smartnet-Version: 20191105220248 X-Mlf-Version: 10.0.1.1213 X-Mlf-License: BSVKCAP____ X-Mlf-UniqueId: o201911090207440265887 Here is the part of C++20 p1032 Misc constexpr bits. Tested on x86_64-linux. OK? Ed Index: include/std/tuple =================================================================== --- include/std/tuple (revision 277944) +++ include/std/tuple (working copy) @@ -132,6 +132,7 @@ constexpr _Head_base(_UHead&& __h) : _M_head_impl(std::forward<_UHead>(__h)) { } + _GLIBCXX20_CONSTEXPR _Head_base(allocator_arg_t, __uses_alloc0) : _M_head_impl() { } @@ -144,6 +145,7 @@ : _M_head_impl(*__a._M_a) { } template + _GLIBCXX20_CONSTEXPR _Head_base(__uses_alloc0, _UHead&& __uhead) : _M_head_impl(std::forward<_UHead>(__uhead)) { } @@ -243,6 +245,7 @@ (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a), _Base(__tag, __use_alloc<_Head>(__a)) { } @@ -256,6 +259,7 @@ template::type> + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _UHead&& __head, _UTail&&... __tail) : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), @@ -263,6 +267,7 @@ std::forward<_UHead>(__head)) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) : _Inherited(__tag, __a, _M_tail(__in)), @@ -269,6 +274,7 @@ _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) : _Inherited(__tag, __a, std::move(_M_tail(__in))), @@ -276,6 +282,7 @@ std::forward<_Head>(_M_head(__in))) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UElements...>& __in) : _Inherited(__tag, __a, @@ -284,6 +291,7 @@ _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) : _Inherited(__tag, __a, std::move @@ -293,6 +301,7 @@ (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } template + _GLIBCXX20_CONSTEXPR void _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) { @@ -302,6 +311,7 @@ } template + _GLIBCXX20_CONSTEXPR void _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) { @@ -312,6 +322,7 @@ } protected: + _GLIBCXX20_CONSTEXPR void _M_swap(_Tuple_impl& __in) { @@ -369,6 +380,7 @@ { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) : _Base(__tag, __use_alloc<_Head>(__a)) { } @@ -378,6 +390,7 @@ : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _UHead&& __head) : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), @@ -384,11 +397,13 @@ std::forward<_UHead>(__head)) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), @@ -395,6 +410,7 @@ std::forward<_Head>(_M_head(__in))) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UHead>& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), @@ -401,6 +417,7 @@ _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } template + _GLIBCXX20_CONSTEXPR _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead>&& __in) : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), @@ -408,6 +425,7 @@ { } template + _GLIBCXX20_CONSTEXPR void _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) { @@ -415,6 +433,7 @@ } template + _GLIBCXX20_CONSTEXPR void _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) { @@ -423,6 +442,7 @@ } protected: + _GLIBCXX20_CONSTEXPR void _M_swap(_Tuple_impl& __in) { @@ -680,11 +700,13 @@ template::value> = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a) { } template= 1), _ImplicitCtor<_NotEmpty, const _Elements&...> = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const _Elements&... __elements) : _Inherited(__tag, __a, __elements...) { } @@ -691,6 +713,7 @@ template= 1), _ExplicitCtor<_NotEmpty, const _Elements&...> = false> + _GLIBCXX20_CONSTEXPR explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const _Elements&... __elements) @@ -699,6 +722,7 @@ template(), _ImplicitCtor<_Valid, _UElements...> = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) @@ -707,6 +731,7 @@ template(), _ExplicitCtor<_Valid, _UElements...> = false> + _GLIBCXX20_CONSTEXPR explicit tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) @@ -714,10 +739,12 @@ { } template + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) : _Inherited(__tag, __a, static_cast(__in)) { } template + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } @@ -725,6 +752,7 @@ bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) && !__use_other_ctor&>(), _ImplicitCtor<_Valid, const _UElements&...> = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, @@ -735,6 +763,7 @@ bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) && !__use_other_ctor&>(), _ExplicitCtor<_Valid, const _UElements&...> = false> + _GLIBCXX20_CONSTEXPR explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) @@ -746,6 +775,7 @@ bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) && !__use_other_ctor&&>(), _ImplicitCtor<_Valid, _UElements...> = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, @@ -756,6 +786,7 @@ bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) && !__use_other_ctor&&>(), _ExplicitCtor<_Valid, _UElements...> = false> + _GLIBCXX20_CONSTEXPR explicit tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) @@ -765,6 +796,7 @@ // tuple assignment + _GLIBCXX20_CONSTEXPR tuple& operator=(typename conditional<__assignable(), const tuple&, @@ -775,6 +807,7 @@ return *this; } + _GLIBCXX20_CONSTEXPR tuple& operator=(typename conditional<__assignable<_Elements...>(), tuple&&, @@ -786,6 +819,7 @@ } template + _GLIBCXX20_CONSTEXPR __enable_if_t<__assignable(), tuple&> operator=(const tuple<_UElements...>& __in) noexcept(__nothrow_assignable()) @@ -795,6 +829,7 @@ } template + _GLIBCXX20_CONSTEXPR __enable_if_t<__assignable<_UElements...>(), tuple&> operator=(tuple<_UElements...>&& __in) noexcept(__nothrow_assignable<_UElements...>()) @@ -804,6 +839,7 @@ } // tuple swap + _GLIBCXX20_CONSTEXPR void swap(tuple& __in) noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value) @@ -834,8 +870,10 @@ tuple() = default; // No-op allocator constructors. template + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t, const _Alloc&) noexcept { } template + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { } }; @@ -1015,11 +1053,13 @@ template::value, _T1, _T2> = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a) { } template = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1, const _T2& __a2) : _Inherited(__tag, __a, __a1, __a2) { } @@ -1027,6 +1067,7 @@ template = false> explicit + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1, const _T2& __a2) : _Inherited(__tag, __a, __a1, __a2) { } @@ -1033,6 +1074,7 @@ template = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } @@ -1040,6 +1082,7 @@ template = false> explicit + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), @@ -1046,15 +1089,18 @@ std::forward<_U2>(__a2)) { } template + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) : _Inherited(__tag, __a, static_cast(__in)) { } template + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } template = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, @@ -1064,6 +1110,7 @@ template = false> explicit + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, @@ -1072,6 +1119,7 @@ template = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } @@ -1079,6 +1127,7 @@ template = false> explicit + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } @@ -1085,6 +1134,7 @@ template = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) : _Inherited(__tag, __a, __in.first, __in.second) { } @@ -1092,6 +1142,7 @@ template = false> explicit + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) : _Inherited(__tag, __a, __in.first, __in.second) { } @@ -1098,6 +1149,7 @@ template = true> + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } @@ -1105,10 +1157,14 @@ template = false> explicit + _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } + // Tuple assignment. + + _GLIBCXX20_CONSTEXPR tuple& operator=(typename conditional<__assignable(), const tuple&, @@ -1119,6 +1175,7 @@ return *this; } + _GLIBCXX20_CONSTEXPR tuple& operator=(typename conditional<__assignable<_T1, _T2>(), tuple&&, @@ -1130,6 +1187,7 @@ } template + _GLIBCXX20_CONSTEXPR __enable_if_t<__assignable(), tuple&> operator=(const tuple<_U1, _U2>& __in) noexcept(__nothrow_assignable()) @@ -1139,6 +1197,7 @@ } template + _GLIBCXX20_CONSTEXPR __enable_if_t<__assignable<_U1, _U2>(), tuple&> operator=(tuple<_U1, _U2>&& __in) noexcept(__nothrow_assignable<_U1, _U2>()) @@ -1148,6 +1207,7 @@ } template + _GLIBCXX20_CONSTEXPR __enable_if_t<__assignable(), tuple&> operator=(const pair<_U1, _U2>& __in) noexcept(__nothrow_assignable()) @@ -1158,6 +1218,7 @@ } template + _GLIBCXX20_CONSTEXPR __enable_if_t<__assignable<_U1, _U2>(), tuple&> operator=(pair<_U1, _U2>&& __in) noexcept(__nothrow_assignable<_U1, _U2>()) @@ -1167,6 +1228,7 @@ return *this; } + _GLIBCXX20_CONSTEXPR void swap(tuple& __in) noexcept(__and_<__is_nothrow_swappable<_T1>, @@ -1521,6 +1583,7 @@ /// swap template + _GLIBCXX20_CONSTEXPR inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 @@ -1535,6 +1598,7 @@ #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 template + _GLIBCXX20_CONSTEXPR typename enable_if...>::value>::type swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; #endif @@ -1570,7 +1634,8 @@ */ template template - _GLIBCXX20_CONSTEXPR inline + _GLIBCXX20_CONSTEXPR + inline pair<_T1, _T2>:: pair(piecewise_construct_t, tuple<_Args1...> __first, tuple<_Args2...> __second) Index: include/bits/uses_allocator.h =================================================================== --- include/bits/uses_allocator.h (revision 277944) +++ include/bits/uses_allocator.h (working copy) @@ -72,7 +72,7 @@ struct __uses_alloc0 : __uses_alloc_base { - struct _Sink { void operator=(const void*) { } } _M_a; + struct _Sink { void _GLIBCXX20_CONSTEXPR operator=(const void*) { } } _M_a; }; template @@ -109,6 +109,7 @@ __uses_alloc::value, _Tp, _Alloc, _Args...>; template + _GLIBCXX20_CONSTEXPR inline __uses_alloc_t<_Tp, _Alloc, _Args...> __use_alloc(const _Alloc& __a) { Index: testsuite/20_util/tuple/cons/constexpr_allocator_arg_t.cc =================================================================== --- testsuite/20_util/tuple/cons/constexpr_allocator_arg_t.cc (nonexistent) +++ testsuite/20_util/tuple/cons/constexpr_allocator_arg_t.cc (working copy) @@ -0,0 +1,48 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } +// +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include + +const std::allocator alloc{}; + +constexpr bool +test_tuple() +{ + auto ok = true; + + std::tuple ta(std::allocator_arg, alloc); + std::tuple tb(std::allocator_arg, alloc, 0, 3.456, 6.789); + std::tuple tc(std::allocator_arg, alloc, 0, 3.456f, 6.789f); + std::tuple td(std::allocator_arg, alloc, tb); + std::tuple te(std::allocator_arg, alloc, std::move(tb)); + + std::tuple tf(std::allocator_arg, alloc, 0, 3.456f, 6.789f); + std::tuple tg(std::allocator_arg, alloc, tf); + std::tuple th(std::allocator_arg, alloc, std::move(tf)); + + std::pair pf(12, 3.142f); + std::tuple ti(std::allocator_arg, alloc, pf); + std::tuple tj(std::allocator_arg, alloc, std::move(pf)); + + return ok; +} + +static_assert(test_tuple());