1//===----------------------------------------------------------------------===// 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 function types. 17 18#include <experimental/tuple> 19#include <array> 20#include <utility> 21#include <cassert> 22 23// std::array is explicitly allowed to be initialized with A a = { init-list };. 24// Disable the missing braces warning for this reason. 25#include "disable_missing_braces_warning.h" 26 27namespace ex = std::experimental; 28 29int count = 0; 30 31void f_void_0() { ++count; } 32void f_void_1(int i) { count += i; } 33void f_void_2(int x, int y) { count += (x + y); } 34void f_void_3(int x, int y, int z) { count += (x + y + z); } 35 36int f_int_0() { return ++count; } 37int f_int_1(int x) { return count += x; } 38int f_int_2(int x, int y) { return count += (x + y); } 39int f_int_3(int x, int y, int z) { return count += (x + y + z); } 40 41struct A_void_0 42{ 43 A_void_0() {} 44 void operator()() { ++count; } 45 void operator()() const { ++count; ++count; } 46}; 47 48struct A_void_1 49{ 50 A_void_1() {} 51 void operator()(int x) { count += x; } 52 void operator()(int x) const { count += x + 1; } 53}; 54 55struct A_void_2 56{ 57 A_void_2() {} 58 void operator()(int x, int y) { count += (x + y); } 59 void operator()(int x, int y) const { count += (x + y) + 1; } 60}; 61 62struct A_void_3 63{ 64 A_void_3() {} 65 void operator()(int x, int y, int z) { count += (x + y + z); } 66 void operator()(int x, int y, int z) const { count += (x + y + z) + 1; } 67}; 68 69 70struct A_int_0 71{ 72 A_int_0() {} 73 int operator()() { return ++count; } 74 int operator()() const { ++count; return ++count; } 75}; 76 77struct A_int_1 78{ 79 A_int_1() {} 80 int operator()(int x) { return count += x; } 81 int operator()(int x) const { return count += (x + 1); } 82 83}; 84 85struct A_int_2 86{ 87 A_int_2() {} 88 int operator()(int x, int y) { return count += (x + y); } 89 int operator()(int x, int y) const { return count += (x + y + 1); } 90}; 91 92struct A_int_3 93{ 94 A_int_3() {} 95 int operator()(int x, int y, int z) { return count += (x + y + z); } 96 int operator()(int x, int y, int z) const { return count += (x + y + z + 1); } 97}; 98 99 100template <class Tuple> 101void test_void_0() 102{ 103 count = 0; 104 // function 105 { 106 Tuple t{}; 107 ex::apply(f_void_0, t); 108 assert(count == 1); 109 } 110 count = 0; 111 // function pointer 112 { 113 Tuple t{}; 114 auto fp = &f_void_0; 115 ex::apply(fp, t); 116 assert(count == 1); 117 } 118 count = 0; 119 // functor 120 { 121 Tuple t{}; 122 A_void_0 a; 123 ex::apply(a, t); 124 assert(count == 1); 125 } 126 count = 0; 127 // const functor 128 { 129 Tuple t{}; 130 A_void_0 const a; 131 ex::apply(a, t); 132 assert(count == 2); 133 } 134} 135 136template <class Tuple> 137void test_void_1() 138{ 139 count = 0; 140 // function 141 { 142 Tuple t{1}; 143 ex::apply(f_void_1, t); 144 assert(count == 1); 145 } 146 count = 0; 147 // function pointer 148 { 149 Tuple t{2}; 150 void (*fp)(int) = f_void_1; 151 ex::apply(fp, t); 152 assert(count == 2); 153 } 154 count = 0; 155 // functor 156 { 157 Tuple t{3}; 158 A_void_1 fn; 159 ex::apply(fn, t); 160 assert(count == 3); 161 } 162 count = 0; 163 // const functor 164 { 165 Tuple t{4}; 166 A_void_1 const a; 167 ex::apply(a, t); 168 assert(count == 5); 169 } 170} 171 172template <class Tuple> 173void test_void_2() 174{ 175 count = 0; 176 // function 177 { 178 Tuple t{1, 2}; 179 ex::apply(f_void_2, t); 180 assert(count == 3); 181 } 182 count = 0; 183 // function pointer 184 { 185 Tuple t{2, 3}; 186 auto fp = &f_void_2; 187 ex::apply(fp, t); 188 assert(count == 5); 189 } 190 count = 0; 191 // functor 192 { 193 Tuple t{3, 4}; 194 A_void_2 a; 195 ex::apply(a, t); 196 assert(count == 7); 197 } 198 count = 0; 199 // const functor 200 { 201 Tuple t{4, 5}; 202 A_void_2 const a; 203 ex::apply(a, t); 204 assert(count == 10); 205 } 206} 207 208template <class Tuple> 209void test_void_3() 210{ 211 count = 0; 212 // function 213 { 214 Tuple t{1, 2, 3}; 215 ex::apply(f_void_3, t); 216 assert(count == 6); 217 } 218 count = 0; 219 // function pointer 220 { 221 Tuple t{2, 3, 4}; 222 auto fp = &f_void_3; 223 ex::apply(fp, t); 224 assert(count == 9); 225 } 226 count = 0; 227 // functor 228 { 229 Tuple t{3, 4, 5}; 230 A_void_3 a; 231 ex::apply(a, t); 232 assert(count == 12); 233 } 234 count = 0; 235 // const functor 236 { 237 Tuple t{4, 5, 6}; 238 A_void_3 const a; 239 ex::apply(a, t); 240 assert(count == 16); 241 } 242} 243 244 245 246template <class Tuple> 247void test_int_0() 248{ 249 count = 0; 250 // function 251 { 252 Tuple t{}; 253 assert(1 == ex::apply(f_int_0, t)); 254 assert(count == 1); 255 } 256 count = 0; 257 // function pointer 258 { 259 Tuple t{}; 260 auto fp = &f_int_0; 261 assert(1 == ex::apply(fp, t)); 262 assert(count == 1); 263 } 264 count = 0; 265 // functor 266 { 267 Tuple t{}; 268 A_int_0 a; 269 assert(1 == ex::apply(a, t)); 270 assert(count == 1); 271 } 272 count = 0; 273 // const functor 274 { 275 Tuple t{}; 276 A_int_0 const a; 277 assert(2 == ex::apply(a, t)); 278 assert(count == 2); 279 } 280} 281 282template <class Tuple> 283void test_int_1() 284{ 285 count = 0; 286 // function 287 { 288 Tuple t{1}; 289 assert(1 == ex::apply(f_int_1, t)); 290 assert(count == 1); 291 } 292 count = 0; 293 // function pointer 294 { 295 Tuple t{2}; 296 int (*fp)(int) = f_int_1; 297 assert(2 == ex::apply(fp, t)); 298 assert(count == 2); 299 } 300 count = 0; 301 // functor 302 { 303 Tuple t{3}; 304 A_int_1 fn; 305 assert(3 == ex::apply(fn, t)); 306 assert(count == 3); 307 } 308 count = 0; 309 // const functor 310 { 311 Tuple t{4}; 312 A_int_1 const a; 313 assert(5 == ex::apply(a, t)); 314 assert(count == 5); 315 } 316} 317 318template <class Tuple> 319void test_int_2() 320{ 321 count = 0; 322 // function 323 { 324 Tuple t{1, 2}; 325 assert(3 == ex::apply(f_int_2, t)); 326 assert(count == 3); 327 } 328 count = 0; 329 // function pointer 330 { 331 Tuple t{2, 3}; 332 auto fp = &f_int_2; 333 assert(5 == ex::apply(fp, t)); 334 assert(count == 5); 335 } 336 count = 0; 337 // functor 338 { 339 Tuple t{3, 4}; 340 A_int_2 a; 341 assert(7 == ex::apply(a, t)); 342 assert(count == 7); 343 } 344 count = 0; 345 // const functor 346 { 347 Tuple t{4, 5}; 348 A_int_2 const a; 349 assert(10 == ex::apply(a, t)); 350 assert(count == 10); 351 } 352} 353 354template <class Tuple> 355void test_int_3() 356{ 357 count = 0; 358 // function 359 { 360 Tuple t{1, 2, 3}; 361 assert(6 == ex::apply(f_int_3, t)); 362 assert(count == 6); 363 } 364 count = 0; 365 // function pointer 366 { 367 Tuple t{2, 3, 4}; 368 auto fp = &f_int_3; 369 assert(9 == ex::apply(fp, t)); 370 assert(count == 9); 371 } 372 count = 0; 373 // functor 374 { 375 Tuple t{3, 4, 5}; 376 A_int_3 a; 377 assert(12 == ex::apply(a, t)); 378 assert(count == 12); 379 } 380 count = 0; 381 // const functor 382 { 383 Tuple t{4, 5, 6}; 384 A_int_3 const a; 385 assert(16 == ex::apply(a, t)); 386 assert(count == 16); 387 } 388} 389 390template <class Tuple> 391void test_0() 392{ 393 test_void_0<Tuple>(); 394 test_int_0<Tuple>(); 395} 396 397template <class Tuple> 398void test_1() 399{ 400 test_void_1<Tuple>(); 401 test_int_1<Tuple>(); 402} 403 404template <class Tuple> 405void test_2() 406{ 407 test_void_2<Tuple>(); 408 test_int_2<Tuple>(); 409} 410 411template <class Tuple> 412void test_3() 413{ 414 test_void_3<Tuple>(); 415 test_int_3<Tuple>(); 416} 417 418int main() 419{ 420 test_0<std::tuple<>>(); 421 422 test_1<std::tuple<int>>(); 423 test_1<std::array<int, 1>>(); 424 425 test_2<std::tuple<int, int>>(); 426 test_2<std::pair<int, int>>(); 427 test_2<std::array<int, 2>>(); 428 429 test_3<std::tuple<int, int, int>>(); 430 test_3<std::array<int, 3>>(); 431} 432