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 with different ref/ptr/cv qualified argument types. 17 18 #include <experimental/tuple> 19 #include <array> 20 #include <utility> 21 #include <cassert> 22 23 namespace ex = std::experimental; 24 25 int call_with_value(int x, int y) { return (x + y); } 26 int call_with_ref(int & x, int & y) { return (x + y); } 27 int call_with_const_ref(int const & x, int const & y) { return (x + y); } 28 int call_with_rvalue_ref(int && x, int && y) { return (x + y); } 29 int call_with_pointer(int * x, int * y) { return (*x + *y); } 30 int call_with_const_pointer(int const* x, int const * y) { return (*x + *y); } 31 32 33 template <class Tuple> 34 void 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 62 template <class Tuple> 63 void 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 94 template <class Tuple> 95 void 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 122 template <class Tuple> 123 void 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 145 template <class Tuple> 146 void 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 163 int 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 } 183