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// 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 27 28namespace ex = std::experimental; 29 30int call_with_value(int x, int y) { return (x + y); } 31int call_with_ref(int & x, int & y) { return (x + y); } 32int call_with_const_ref(int const & x, int const & y) { return (x + y); } 33int call_with_rvalue_ref(int && x, int && y) { return (x + y); } 34int call_with_pointer(int * x, int * y) { return (*x + *y); } 35int call_with_const_pointer(int const* x, int const * y) { return (*x + *y); } 36 37 38template <class Tuple> 39void test_values() 40{ 41 { 42 Tuple t{1, 2}; 43 assert(3 == ex::apply(call_with_value, t)); 44 } 45 { 46 Tuple t{2, 2}; 47 assert(4 == ex::apply(call_with_ref, t)); 48 } 49 { 50 Tuple t{2, 3}; 51 assert(5 == ex::apply(call_with_const_ref, t)); 52 } 53 { 54 Tuple t{3, 3}; 55 assert(6 == ex::apply(call_with_rvalue_ref, static_cast<Tuple &&>(t))); 56 } 57 { 58 Tuple const t{4, 4}; 59 assert(8 == ex::apply(call_with_value, t)); 60 } 61 { 62 Tuple const t{4, 5}; 63 assert(9 == ex::apply(call_with_const_ref, t)); 64 } 65} 66 67template <class Tuple> 68void test_refs() 69{ 70 int x = 0; 71 int y = 0; 72 { 73 x = 1; y = 2; 74 Tuple t{x, y}; 75 assert(3 == ex::apply(call_with_value, t)); 76 } 77 { 78 x = 2; y = 2; 79 Tuple t{x, y}; 80 assert(4 == ex::apply(call_with_ref, t)); 81 } 82 { 83 x = 2; y = 3; 84 Tuple t{x, y}; 85 assert(5 == ex::apply(call_with_const_ref, t)); 86 } 87 { 88 x = 3; y = 3; 89 Tuple const t{x, y}; 90 assert(6 == ex::apply(call_with_value, t)); 91 } 92 { 93 x = 3; y = 4; 94 Tuple const t{x, y}; 95 assert(7 == ex::apply(call_with_const_ref, t)); 96 } 97} 98 99template <class Tuple> 100void test_const_refs() 101{ 102 int x = 0; 103 int y = 0; 104 { 105 x = 1; y = 2; 106 Tuple t{x, y}; 107 assert(3 == ex::apply(call_with_value, t)); 108 } 109 { 110 x = 2; y = 3; 111 Tuple t{x, y}; 112 assert(5 == ex::apply(call_with_const_ref, t)); 113 } 114 { 115 x = 3; y = 3; 116 Tuple const t{x, y}; 117 assert(6 == ex::apply(call_with_value, t)); 118 } 119 { 120 x = 3; y = 4; 121 Tuple const t{x, y}; 122 assert(7 == ex::apply(call_with_const_ref, t)); 123 } 124} 125 126 127template <class Tuple> 128void test_pointer() 129{ 130 int x = 0; 131 int y = 0; 132 { 133 x = 2; y = 2; 134 Tuple t{&x, &y}; 135 assert(4 == ex::apply(call_with_pointer, t)); 136 } 137 { 138 x = 2; y = 3; 139 Tuple t{&x, &y}; 140 assert(5 == ex::apply(call_with_const_pointer, t)); 141 } 142 { 143 x = 3; y = 4; 144 Tuple const t{&x, &y}; 145 assert(7 == ex::apply(call_with_const_pointer, t)); 146 } 147} 148 149 150template <class Tuple> 151void test_const_pointer() 152{ 153 int x = 0; 154 int y = 0; 155 { 156 x = 2; y = 3; 157 Tuple t{&x, &y}; 158 assert(5 == ex::apply(call_with_const_pointer, t)); 159 } 160 { 161 x = 3; y = 4; 162 Tuple const t{&x, &y}; 163 assert(7 == ex::apply(call_with_const_pointer, t)); 164 } 165} 166 167 168int main() 169{ 170 test_values<std::tuple<int, int>>(); 171 test_values<std::pair<int, int>>(); 172 test_values<std::array<int, 2>>(); 173 174 test_refs<std::tuple<int &, int &>>(); 175 test_refs<std::pair<int &, int &>>(); 176 177 test_const_refs<std::tuple<int const &, int const &>>(); 178 test_const_refs<std::pair<int const &, int const &>>(); 179 180 test_pointer<std::tuple<int *, int *>>(); 181 test_pointer<std::pair<int *, int *>>(); 182 test_pointer<std::array<int *, 2>>(); 183 184 test_const_pointer<std::tuple<int const *, int const *>>(); 185 test_const_pointer<std::pair<int const *, int const *>>(); 186 test_const_pointer<std::array<int const *, 2>>(); 187} 188