1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11
12 // <experimental/tuple>
14 // template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
16 // Testing extended function types. The extented function types are those
17 // named by INVOKE but that are not actual callable objects. These include
18 // bullets 1-4 of invoke.
20 #include <experimental/tuple>
30 A_int_0(int x) : obj1(x) {}
31 int mem1() { return ++count; }
32 int mem2() const { return ++count; }
40 int mem1(int x) { return count += x; }
41 int mem2(int x) const { return count += x; }
48 int mem1(int x, int y) { return count += (x + y); }
49 int mem2(int x, int y) const { return count += (x + y); }
56 A_wrap(int x) : m_a(x) {}
57 A & operator*() { return m_a; }
58 A const & operator*() const { return m_a; }
62 typedef A_wrap<A_int_0> A_wrap_0;
63 typedef A_wrap<A_int_1> A_wrap_1;
64 typedef A_wrap<A_int_2> A_wrap_2;
68 struct A_base : public A
71 A_base(int x) : A(x) {}
74 typedef A_base<A_int_0> A_base_0;
75 typedef A_base<A_int_1> A_base_1;
76 typedef A_base<A_int_2> A_base_2;
78 namespace ex = std::experimental;
81 class Tuple, class ConstTuple
82 , class TuplePtr, class ConstTuplePtr
83 , class TupleWrap, class ConstTupleWrap
84 , class TupleBase, class ConstTupleBase
90 typedef A_wrap_0 Wrap;
91 typedef A_base_0 Base;
93 typedef int(T::*mem1_t)();
94 mem1_t mem1 = &T::mem1;
96 typedef int(T::*mem2_t)() const;
97 mem2_t mem2 = &T::mem2;
99 typedef int const T::*obj1_t;
100 obj1_t obj1 = &T::obj1;
102 // member function w/ref
106 assert(1 == ex::apply(mem1, t));
110 // member function w/pointer
114 assert(1 == ex::apply(mem1, t));
118 // member function w/base
122 assert(1 == ex::apply(mem1, t));
126 // member function w/wrap
130 assert(1 == ex::apply(mem1, t));
134 // const member function w/ref
138 assert(1 == ex::apply(mem2, t));
142 // const member function w/pointer
146 assert(1 == ex::apply(mem2, t));
150 // const member function w/base
154 assert(1 == ex::apply(mem2, t));
158 // const member function w/wrapper
162 assert(1 == ex::apply(mem2, t));
165 // member object w/ref
169 assert(42 == ex::apply(obj1, t));
171 // member object w/pointer
175 assert(42 == ex::apply(obj1, t));
177 // member object w/base
181 assert(42 == ex::apply(obj1, t));
183 // member object w/wrapper
187 assert(42 == ex::apply(obj1, t));
193 class Tuple, class ConstTuple
194 , class TuplePtr, class ConstTuplePtr
195 , class TupleWrap, class ConstTupleWrap
196 , class TupleBase, class ConstTupleBase
198 void test_ext_int_1()
202 typedef A_wrap_1 Wrap;
203 typedef A_base_1 Base;
205 typedef int(T::*mem1_t)(int);
206 mem1_t mem1 = &T::mem1;
208 typedef int(T::*mem2_t)(int) const;
209 mem2_t mem2 = &T::mem2;
211 // member function w/ref
215 assert(2 == ex::apply(mem1, t));
219 // member function w/pointer
223 assert(3 == ex::apply(mem1, t));
227 // member function w/base
231 assert(4 == ex::apply(mem1, t));
235 // member function w/wrap
239 assert(5 == ex::apply(mem1, t));
243 // const member function w/ref
247 assert(6 == ex::apply(mem2, t));
251 // const member function w/pointer
254 ConstTuplePtr t{&a, 7};
255 assert(7 == ex::apply(mem2, t));
259 // const member function w/base
262 ConstTupleBase t{a, 8};
263 assert(8 == ex::apply(mem2, t));
267 // const member function w/wrapper
270 ConstTupleWrap t{a, 9};
271 assert(9 == ex::apply(mem2, t));
278 class Tuple, class ConstTuple
279 , class TuplePtr, class ConstTuplePtr
280 , class TupleWrap, class ConstTupleWrap
281 , class TupleBase, class ConstTupleBase
283 void test_ext_int_2()
287 typedef A_wrap_2 Wrap;
288 typedef A_base_2 Base;
290 typedef int(T::*mem1_t)(int, int);
291 mem1_t mem1 = &T::mem1;
293 typedef int(T::*mem2_t)(int, int) const;
294 mem2_t mem2 = &T::mem2;
296 // member function w/ref
300 assert(2 == ex::apply(mem1, t));
304 // member function w/pointer
307 TuplePtr t{&a, 1, 2};
308 assert(3 == ex::apply(mem1, t));
312 // member function w/base
315 TupleBase t{a, 2, 2};
316 assert(4 == ex::apply(mem1, t));
320 // member function w/wrap
323 TupleWrap t{a, 2, 3};
324 assert(5 == ex::apply(mem1, t));
328 // const member function w/ref
331 ConstTuple t{a, 3, 3};
332 assert(6 == ex::apply(mem2, t));
336 // const member function w/pointer
339 ConstTuplePtr t{&a, 3, 4};
340 assert(7 == ex::apply(mem2, t));
344 // const member function w/base
347 ConstTupleBase t{a, 4, 4};
348 assert(8 == ex::apply(mem2, t));
352 // const member function w/wrapper
355 ConstTupleWrap t{a, 4, 5};
356 assert(9 == ex::apply(mem2, t));
365 std::tuple<A_int_0 &>, std::tuple<A_int_0 const &>
366 , std::tuple<A_int_0 *>, std::tuple<A_int_0 const *>
367 , std::tuple<A_wrap_0 &>, std::tuple<A_wrap_0 const &>
368 , std::tuple<A_base_0 &>, std::tuple<A_base_0 const &>
371 std::tuple<A_int_0>, std::tuple<A_int_0 const>
372 , std::tuple<A_int_0 *>, std::tuple<A_int_0 const *>
373 , std::tuple<A_wrap_0>, std::tuple<A_wrap_0 const>
374 , std::tuple<A_base_0>, std::tuple<A_base_0 const>
377 std::array<A_int_0, 1>, std::array<A_int_0 const, 1>
378 , std::array<A_int_0*, 1>, std::array<A_int_0 const*, 1>
379 , std::array<A_wrap_0, 1>, std::array<A_wrap_0 const, 1>
380 , std::array<A_base_0, 1>, std::array<A_base_0 const, 1>
385 std::tuple<A_int_1 &, int>, std::tuple<A_int_1 const &, int>
386 , std::tuple<A_int_1 *, int>, std::tuple<A_int_1 const *, int>
387 , std::tuple<A_wrap_1 &, int>, std::tuple<A_wrap_1 const &, int>
388 , std::tuple<A_base_1 &, int>, std::tuple<A_base_1 const &, int>
391 std::tuple<A_int_1, int>, std::tuple<A_int_1 const, int>
392 , std::tuple<A_int_1 *, int>, std::tuple<A_int_1 const *, int>
393 , std::tuple<A_wrap_1, int>, std::tuple<A_wrap_1 const, int>
394 , std::tuple<A_base_1, int>, std::tuple<A_base_1 const, int>
397 std::pair<A_int_1 &, int>, std::pair<A_int_1 const &, int>
398 , std::pair<A_int_1 *, int>, std::pair<A_int_1 const *, int>
399 , std::pair<A_wrap_1 &, int>, std::pair<A_wrap_1 const &, int>
400 , std::pair<A_base_1 &, int>, std::pair<A_base_1 const &, int>
403 std::pair<A_int_1, int>, std::pair<A_int_1 const, int>
404 , std::pair<A_int_1 *, int>, std::pair<A_int_1 const *, int>
405 , std::pair<A_wrap_1, int>, std::pair<A_wrap_1 const, int>
406 , std::pair<A_base_1, int>, std::pair<A_base_1 const, int>
411 std::tuple<A_int_2 &, int, int>, std::tuple<A_int_2 const &, int, int>
412 , std::tuple<A_int_2 *, int, int>, std::tuple<A_int_2 const *, int, int>
413 , std::tuple<A_wrap_2 &, int, int>, std::tuple<A_wrap_2 const &, int, int>
414 , std::tuple<A_base_2 &, int, int>, std::tuple<A_base_2 const &, int, int>
417 std::tuple<A_int_2, int, int>, std::tuple<A_int_2 const, int, int>
418 , std::tuple<A_int_2 *, int, int>, std::tuple<A_int_2 const *, int, int>
419 , std::tuple<A_wrap_2, int, int>, std::tuple<A_wrap_2 const, int, int>
420 , std::tuple<A_base_2, int, int>, std::tuple<A_base_2 const, int, int>