blob: 56dc3c6aaa2522561b733bd12a1986ef39781da4 [file] [log] [blame]
Eric Fiselier13858ee2015-03-17 18:28:14 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// UNSUPPORTED: c++98, c++03, c++11
11
12// <experimental/tuple>
13
14// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
15
16// Test with different ref/ptr/cv qualified argument types.
17
18#include <experimental/tuple>
19#include <array>
20#include <utility>
21#include <cassert>
22
Eric Fiselier13858ee2015-03-17 18:28:14 +000023namespace ex = std::experimental;
24
25int call_with_value(int x, int y) { return (x + y); }
26int call_with_ref(int & x, int & y) { return (x + y); }
27int call_with_const_ref(int const & x, int const & y) { return (x + y); }
28int call_with_rvalue_ref(int && x, int && y) { return (x + y); }
29int call_with_pointer(int * x, int * y) { return (*x + *y); }
30int call_with_const_pointer(int const* x, int const * y) { return (*x + *y); }
31
32
33template <class Tuple>
34void test_values()
35{
36 {
37 Tuple t{1, 2};
38 assert(3 == ex::apply(call_with_value, t));
39 }
40 {
41 Tuple t{2, 2};
42 assert(4 == ex::apply(call_with_ref, t));
43 }
44 {
45 Tuple t{2, 3};
46 assert(5 == ex::apply(call_with_const_ref, t));
47 }
48 {
49 Tuple t{3, 3};
50 assert(6 == ex::apply(call_with_rvalue_ref, static_cast<Tuple &&>(t)));
51 }
52 {
53 Tuple const t{4, 4};
54 assert(8 == ex::apply(call_with_value, t));
55 }
56 {
57 Tuple const t{4, 5};
58 assert(9 == ex::apply(call_with_const_ref, t));
59 }
60}
61
62template <class Tuple>
63void test_refs()
64{
65 int x = 0;
66 int y = 0;
67 {
68 x = 1; y = 2;
69 Tuple t{x, y};
70 assert(3 == ex::apply(call_with_value, t));
71 }
72 {
73 x = 2; y = 2;
74 Tuple t{x, y};
75 assert(4 == ex::apply(call_with_ref, t));
76 }
77 {
78 x = 2; y = 3;
79 Tuple t{x, y};
80 assert(5 == ex::apply(call_with_const_ref, t));
81 }
82 {
83 x = 3; y = 3;
84 Tuple const t{x, y};
85 assert(6 == ex::apply(call_with_value, t));
86 }
87 {
88 x = 3; y = 4;
89 Tuple const t{x, y};
90 assert(7 == ex::apply(call_with_const_ref, t));
91 }
92}
93
94template <class Tuple>
95void test_const_refs()
96{
97 int x = 0;
98 int y = 0;
99 {
100 x = 1; y = 2;
101 Tuple t{x, y};
102 assert(3 == ex::apply(call_with_value, t));
103 }
104 {
105 x = 2; y = 3;
106 Tuple t{x, y};
107 assert(5 == ex::apply(call_with_const_ref, t));
108 }
109 {
110 x = 3; y = 3;
111 Tuple const t{x, y};
112 assert(6 == ex::apply(call_with_value, t));
113 }
114 {
115 x = 3; y = 4;
116 Tuple const t{x, y};
117 assert(7 == ex::apply(call_with_const_ref, t));
118 }
119}
120
121
122template <class Tuple>
123void test_pointer()
124{
125 int x = 0;
126 int y = 0;
127 {
128 x = 2; y = 2;
129 Tuple t{&x, &y};
130 assert(4 == ex::apply(call_with_pointer, t));
131 }
132 {
133 x = 2; y = 3;
134 Tuple t{&x, &y};
135 assert(5 == ex::apply(call_with_const_pointer, t));
136 }
137 {
138 x = 3; y = 4;
139 Tuple const t{&x, &y};
140 assert(7 == ex::apply(call_with_const_pointer, t));
141 }
142}
143
144
145template <class Tuple>
146void test_const_pointer()
147{
148 int x = 0;
149 int y = 0;
150 {
151 x = 2; y = 3;
152 Tuple t{&x, &y};
153 assert(5 == ex::apply(call_with_const_pointer, t));
154 }
155 {
156 x = 3; y = 4;
157 Tuple const t{&x, &y};
158 assert(7 == ex::apply(call_with_const_pointer, t));
159 }
160}
161
162
163int main()
164{
165 test_values<std::tuple<int, int>>();
166 test_values<std::pair<int, int>>();
167 test_values<std::array<int, 2>>();
168
169 test_refs<std::tuple<int &, int &>>();
170 test_refs<std::pair<int &, int &>>();
171
172 test_const_refs<std::tuple<int const &, int const &>>();
173 test_const_refs<std::pair<int const &, int const &>>();
174
175 test_pointer<std::tuple<int *, int *>>();
176 test_pointer<std::pair<int *, int *>>();
177 test_pointer<std::array<int *, 2>>();
178
179 test_const_pointer<std::tuple<int const *, int const *>>();
180 test_const_pointer<std::pair<int const *, int const *>>();
181 test_const_pointer<std::array<int const *, 2>>();
182}