1 // { dg-do run { target c++11 } }
2 
3 // Copyright (C) 2011-2020 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING3.  If not see
18 // <http://www.gnu.org/licenses/>.
19 
20 #include <tuple>
21 #include <type_traits>
22 #include <testsuite_hooks.h>
23 
24 template<typename T>
copy(T && x)25   typename std::decay<T>::type copy(T&& x)
26   { return std::forward<T>(x); }
27 
28 template<typename... Args1, typename... Args2>
29   void
check_tuple_cat(std::tuple<Args1...> t1,std::tuple<Args2...> t2)30   check_tuple_cat(std::tuple<Args1...> t1, std::tuple<Args2...> t2)
31   {
32     typedef std::tuple<Args1..., Args2...> concatenated;
33 
34     auto cat1 = std::tuple_cat(     t1,       t2 );
35     auto cat2 = std::tuple_cat(copy(t1),      t2 );
36     auto cat3 = std::tuple_cat(     t1,  copy(t2));
37     auto cat4 = std::tuple_cat(copy(t1), copy(t2));
38 
39     static_assert( std::is_same<decltype(cat1), concatenated>::value, "" );
40     static_assert( std::is_same<decltype(cat2), concatenated>::value, "" );
41     static_assert( std::is_same<decltype(cat3), concatenated>::value, "" );
42     static_assert( std::is_same<decltype(cat4), concatenated>::value, "" );
43 
44     VERIFY( cat1 == cat2 );
45     VERIFY( cat1 == cat3 );
46     VERIFY( cat1 == cat4 );
47   }
48 
49 // libstdc++/48476
test01()50 void test01()
51 {
52   int i = 0;
53   std::tuple<> t0;
54   std::tuple<int&> t1(i);
55   std::tuple<int&, int> t2(i, 0);
56   std::tuple<int const&, int, double> t3(i, 0, 0);
57 
58   check_tuple_cat(t0, t0);
59   check_tuple_cat(t0, t1);
60   check_tuple_cat(t0, t2);
61   check_tuple_cat(t0, t3);
62 
63   check_tuple_cat(t1, t0);
64   check_tuple_cat(t1, t1);
65   check_tuple_cat(t1, t2);
66   check_tuple_cat(t1, t3);
67 
68   check_tuple_cat(t2, t0);
69   check_tuple_cat(t2, t1);
70   check_tuple_cat(t2, t2);
71   check_tuple_cat(t2, t3);
72 
73   check_tuple_cat(t3, t0);
74   check_tuple_cat(t3, t1);
75   check_tuple_cat(t3, t2);
76   check_tuple_cat(t3, t3);
77 }
78 
main()79 int main()
80 {
81   test01();
82   return 0;
83 }
84