1 // { dg-options "-std=gnu++2a" }
2 // { dg-do run { target c++2a } }
3 
4 // Copyright (C) 2020 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3.  If not see
19 // <http://www.gnu.org/licenses/>.
20 
21 // Tuple
22 
23 #include <tuple>
24 #include <testsuite_hooks.h>
25 
26 using namespace std;
27 
28 template<typename T>
self_consistent(const T & x)29 bool self_consistent(const T& x)
30 {
31   return std::is_eq(x <=> x) && x == x && !(x != x) && x <= x && !(x < x);
32 }
33 
34 void
test01()35 test01()
36 {
37   int i=0;
38   int j=0;
39   int k=2;
40   tuple<int, int, int> a(0, 0, 0);
41   tuple<int, int, int> b(0, 0, 1);
42   tuple<int& , int& , int&> c(i,j,k);
43   tuple<const int&, const int&, const int&> d(c);
44   VERIFY( self_consistent(a) );
45   VERIFY( self_consistent(b) );
46   VERIFY( self_consistent(c) );
47   VERIFY( self_consistent(d) );
48   VERIFY( !(a > a) && !(b > b) );
49   VERIFY( a >= a && b >= b );
50   VERIFY( a < b && !(b < a) && a <= b && !(b <= a) );
51   VERIFY( b > a && !(a > b) && b >= a && !(a >= b) );
52 
53   VERIFY( std::is_lt(a <=> b) );
54   VERIFY( std::is_gt(b <=> a) );
55   VERIFY( std::is_gt(c <=> a) );
56   VERIFY( std::is_eq(c <=> d) );
57 
58   static_assert( std::is_same_v<decltype(a <=> d), std::strong_ordering> );
59 }
60 
61 template<typename T, typename U, typename C>
62 constexpr bool
check_compare(T && t,U && u,C c)63 check_compare(T&& t, U&& u, C c)
64 {
65   using R = std::compare_three_way_result_t<T, U>;
66   static_assert( std::same_as<C, R> );
67   return (t <=> u) == c;
68 }
69 
70 void
test02()71 test02()
72 {
73   using std::strong_ordering;
74   using std::weak_ordering;
75   using std::partial_ordering;
76 
77   using T0 = std::tuple<>;
78   static_assert( check_compare(T0(), T0(), strong_ordering::equal) );
79 
80   using Ti = std::tuple<int>;
81   using Tu = std::tuple<unsigned>;
82   static_assert( check_compare(Ti(1), Tu(1u), weak_ordering::equivalent) );
83   static_assert( check_compare(Ti(1), Tu(2u), weak_ordering::less) );
84   static_assert( check_compare(Ti(-1), Tu(1u), weak_ordering::greater) );
85 
86   using Tii = std::tuple<int, int>;
87   using Tlu = std::tuple<long, unsigned>;
88   static_assert( check_compare(Tii(1, 2), Tlu(2l, 1u), weak_ordering::less) );
89 
90   using Tid = std::tuple<int, double>;
91   static_assert( check_compare(Tii(3, 4), Tid(2, 0.9), partial_ordering::greater) );
92 
93   static_assert( !std::three_way_comparable_with<T0, Ti> );
94   static_assert( !std::three_way_comparable_with<Ti, Tii> );
95   static_assert( !std::three_way_comparable_with<Ti, Tid> );
96 }
97 
main()98 int main()
99 {
100   test01();
101   test02();
102 }
103