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 // type_traits 11 12 // common_type 13 14 #include <type_traits> 15 #include <memory> 16 17 #include "test_macros.h" 18 19 struct E {}; 20 21 template <class T> 22 struct X { explicit X(T const&){} }; 23 24 template <class T> 25 struct S { explicit S(T const&){} }; 26 27 namespace std 28 { 29 template <typename T> 30 struct common_type<T, ::S<T> > 31 { 32 typedef S<T> type; 33 }; 34 35 template <class T> 36 struct common_type< ::S<T>, T> { 37 typedef S<T> type; 38 }; 39 40 // P0548 41 template <class T> 42 struct common_type< ::S<T>, ::S<T> > { 43 typedef S<T> type; 44 }; 45 46 template <> struct common_type< ::S<long>, long> {}; 47 template <> struct common_type<long, ::S<long> > {}; 48 template <> struct common_type< ::X<float> > {}; 49 template <> struct common_type< ::X<double>, ::X<double> > {}; 50 } 51 52 #if TEST_STD_VER >= 11 53 template <class Tp> 54 struct always_bool_imp { using type = bool; }; 55 template <class Tp> using always_bool = typename always_bool_imp<Tp>::type; 56 57 template <class ...Args> 58 constexpr auto no_common_type_imp(int) 59 -> always_bool<typename std::common_type<Args...>::type> 60 { return false; } 61 62 template <class ...Args> 63 constexpr bool no_common_type_imp(long) { return true; } 64 65 template <class ...Args> 66 using no_common_type = std::integral_constant<bool, no_common_type_imp<Args...>(0)>; 67 68 template <class Tp> 69 using Decay = typename std::decay<Tp>::type; 70 71 template <class ...Args> 72 using CommonType = typename std::common_type<Args...>::type; 73 74 template <class T1, class T2> 75 struct TernaryOpImp { 76 static_assert(std::is_same<Decay<T1>, T1>::value, "must be same"); 77 static_assert(std::is_same<Decay<T2>, T2>::value, "must be same"); 78 using type = typename std::decay< 79 decltype(false ? std::declval<T1>() : std::declval<T2>()) 80 >::type; 81 }; 82 83 template <class T1, class T2> 84 using TernaryOp = typename TernaryOpImp<T1, T2>::type; 85 86 // -- If sizeof...(T) is zero, there shall be no member type. 87 void test_bullet_one() { 88 static_assert(no_common_type<>::value, ""); 89 } 90 91 // If sizeof...(T) is one, let T0 denote the sole type constituting the pack T. 92 // The member typedef-name type shall denote the same type as decay_t<T0>. 93 void test_bullet_two() { 94 static_assert(std::is_same<CommonType<void>, void>::value, ""); 95 static_assert(std::is_same<CommonType<int>, int>::value, ""); 96 static_assert(std::is_same<CommonType<int const>, int>::value, ""); 97 static_assert(std::is_same<CommonType<int volatile[]>, int volatile*>::value, ""); 98 static_assert(std::is_same<CommonType<void(&)()>, void(*)()>::value, ""); 99 100 static_assert(no_common_type<X<float> >::value, ""); 101 static_assert(no_common_type<X<double> >::value, ""); 102 } 103 104 template <class T, class U, class Expect> 105 void test_bullet_three_one_imp() { 106 using DT = Decay<T>; 107 using DU = Decay<U>; 108 static_assert(!std::is_same<T, DT>::value || !std::is_same<U, DU>::value, ""); 109 static_assert(std::is_same<CommonType<T, U>, Expect>::value, ""); 110 static_assert(std::is_same<CommonType<U, T>, Expect>::value, ""); 111 static_assert(std::is_same<CommonType<T, U>, CommonType<DT, DU>>::value, ""); 112 } 113 114 // (3.3) 115 // -- If sizeof...(T) is two, let the first and second types constituting T be 116 // denoted by T1 and T2, respectively, and let D1 and D2 denote the same types 117 // as decay_t<T1> and decay_t<T2>, respectively. 118 // (3.3.1) 119 // -- If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false, let C 120 // denote the same type, if any, as common_type_t<D1, D2>. 121 void test_bullet_three_one() { 122 // Test that the user provided specialization of common_type is used after 123 // decaying T1. 124 { 125 using T1 = S<int> const; 126 using T2 = int; 127 test_bullet_three_one_imp<T1, T2, S<int> >(); 128 } 129 // Test a user provided specialization that does not provide a typedef. 130 { 131 using T1 = ::S<long> const; 132 using T2 = long; 133 static_assert(no_common_type<T1, T2>::value, ""); 134 static_assert(no_common_type<T2, T1>::value, ""); 135 } 136 // Test that the ternary operator is not applied when the types are the 137 // same. 138 { 139 using T1 = const void; 140 using Expect = void; 141 static_assert(std::is_same<CommonType<T1, T1>, Expect>::value, ""); 142 static_assert(std::is_same<CommonType<T1, T1>, CommonType<T1>>::value, ""); 143 } 144 { 145 using T1 = int const[]; 146 using Expect = int const*; 147 static_assert(std::is_same<CommonType<T1, T1>, Expect>::value, ""); 148 static_assert(std::is_same<CommonType<T1, T1>, CommonType<T1>>::value, ""); 149 } 150 } 151 152 // (3.3) 153 // -- If sizeof...(T) is two, let the first and second types constituting T be 154 // denoted by T1 and T2, respectively, and let D1 and D2 denote the same types 155 // as decay_t<T1> and decay_t<T2>, respectively. 156 // (3.3.1) 157 // -- If [...] 158 // (3.3.2) 159 // -- Otherwise, let C denote the same type, if any, as 160 // decay_t<decltype(false ? declval<D1>() : declval<D2>())> 161 void test_bullet_three_two() { 162 { 163 using T1 = int const*; 164 using T2 = int*; 165 using Expect = TernaryOp<T1, T2>; 166 static_assert(std::is_same<CommonType<T1, T2>, Expect>::value, ""); 167 static_assert(std::is_same<CommonType<T2, T1>, Expect>::value, ""); 168 } 169 // Test that there is no ::type member when the ternary op is ill-formed 170 { 171 using T1 = int; 172 using T2 = void; 173 static_assert(no_common_type<T1, T2>::value, ""); 174 static_assert(no_common_type<T2, T1>::value, ""); 175 } 176 { 177 using T1 = int; 178 using T2 = X<int>; 179 static_assert(no_common_type<T1, T2>::value, ""); 180 static_assert(no_common_type<T2, T1>::value, ""); 181 } 182 // Test that the ternary operator is not applied when the types are the 183 // same. 184 { 185 using T1 = void; 186 using Expect = void; 187 static_assert(std::is_same<CommonType<T1, T1>, Expect>::value, ""); 188 static_assert(std::is_same<CommonType<T1, T1>, CommonType<T1>>::value, ""); 189 } 190 } 191 192 // (3.4) 193 // -- If sizeof...(T) is greater than two, let T1, T2, and R, respectively, 194 // denote the first, second, and (pack of) remaining types constituting T. 195 // Let C denote the same type, if any, as common_type_t<T1, T2>. If there is 196 // such a type C, the member typedef-name type shall denote the 197 // same type, if any, as common_type_t<C, R...>. Otherwise, there shall be 198 // no member type. 199 void test_bullet_four() { 200 { // test that there is no ::type member 201 static_assert(no_common_type<int, E>::value, ""); 202 static_assert(no_common_type<int, int, E>::value, ""); 203 static_assert(no_common_type<int, int, E, int>::value, ""); 204 static_assert(no_common_type<int, int, int, E>::value, ""); 205 } 206 } 207 208 209 // The example code specified in Note B for common_type 210 namespace note_b_example { 211 212 using PF1 = bool (&)(); 213 using PF2 = short (*)(long); 214 215 struct S { 216 operator PF2() const; 217 double operator()(char, int&); 218 void fn(long) const; 219 char data; 220 }; 221 222 using PMF = void (S::*)(long) const; 223 using PMD = char S::*; 224 225 using std::is_same; 226 using std::result_of; 227 using std::unique_ptr; 228 229 static_assert(is_same<typename result_of<S(int)>::type, short>::value, "Error!"); 230 static_assert(is_same<typename result_of<S&(unsigned char, int&)>::type, double>::value, "Error!"); 231 static_assert(is_same<typename result_of<PF1()>::type, bool>::value, "Error!"); 232 static_assert(is_same<typename result_of<PMF(unique_ptr<S>, int)>::type, void>::value, "Error!"); 233 static_assert(is_same<typename result_of<PMD(S)>::type, char&&>::value, "Error!"); 234 static_assert(is_same<typename result_of<PMD(const S*)>::type, const char&>::value, "Error!"); 235 236 } // namespace note_b_example 237 #endif // TEST_STD_VER >= 11 238 239 int main() 240 { 241 static_assert((std::is_same<std::common_type<int>::type, int>::value), ""); 242 static_assert((std::is_same<std::common_type<char>::type, char>::value), ""); 243 #if TEST_STD_VER > 11 244 static_assert((std::is_same<std::common_type_t<int>, int>::value), ""); 245 static_assert((std::is_same<std::common_type_t<char>, char>::value), ""); 246 #endif 247 248 static_assert((std::is_same<std::common_type< int>::type, int>::value), ""); 249 static_assert((std::is_same<std::common_type<const int>::type, int>::value), ""); 250 static_assert((std::is_same<std::common_type< volatile int>::type, int>::value), ""); 251 static_assert((std::is_same<std::common_type<const volatile int>::type, int>::value), ""); 252 253 static_assert((std::is_same<std::common_type<int, int>::type, int>::value), ""); 254 static_assert((std::is_same<std::common_type<int, const int>::type, int>::value), ""); 255 256 static_assert((std::is_same<std::common_type<long, const int>::type, long>::value), ""); 257 static_assert((std::is_same<std::common_type<const long, int>::type, long>::value), ""); 258 static_assert((std::is_same<std::common_type<long, volatile int>::type, long>::value), ""); 259 static_assert((std::is_same<std::common_type<volatile long, int>::type, long>::value), ""); 260 static_assert((std::is_same<std::common_type<const long, const int>::type, long>::value), ""); 261 262 static_assert((std::is_same<std::common_type<double, char>::type, double>::value), ""); 263 static_assert((std::is_same<std::common_type<short, char>::type, int>::value), ""); 264 #if TEST_STD_VER > 11 265 static_assert((std::is_same<std::common_type_t<double, char>, double>::value), ""); 266 static_assert((std::is_same<std::common_type_t<short, char>, int>::value), ""); 267 #endif 268 269 static_assert((std::is_same<std::common_type<double, char, long long>::type, double>::value), ""); 270 static_assert((std::is_same<std::common_type<unsigned, char, long long>::type, long long>::value), ""); 271 #if TEST_STD_VER > 11 272 static_assert((std::is_same<std::common_type_t<double, char, long long>, double>::value), ""); 273 static_assert((std::is_same<std::common_type_t<unsigned, char, long long>, long long>::value), ""); 274 #endif 275 276 static_assert((std::is_same<std::common_type< void>::type, void>::value), ""); 277 static_assert((std::is_same<std::common_type<const void>::type, void>::value), ""); 278 static_assert((std::is_same<std::common_type< volatile void>::type, void>::value), ""); 279 static_assert((std::is_same<std::common_type<const volatile void>::type, void>::value), ""); 280 281 static_assert((std::is_same<std::common_type<void, const void>::type, void>::value), ""); 282 static_assert((std::is_same<std::common_type<const void, void>::type, void>::value), ""); 283 static_assert((std::is_same<std::common_type<void, volatile void>::type, void>::value), ""); 284 static_assert((std::is_same<std::common_type<volatile void, void>::type, void>::value), ""); 285 static_assert((std::is_same<std::common_type<const void, const void>::type, void>::value), ""); 286 287 static_assert((std::is_same<std::common_type<int, S<int> >::type, S<int> >::value), ""); 288 static_assert((std::is_same<std::common_type<int, S<int>, S<int> >::type, S<int> >::value), ""); 289 static_assert((std::is_same<std::common_type<int, int, S<int> >::type, S<int> >::value), ""); 290 291 #if TEST_STD_VER >= 11 292 test_bullet_one(); 293 test_bullet_two(); 294 test_bullet_three_one(); 295 test_bullet_three_two(); 296 test_bullet_four(); 297 #endif 298 299 // P0548 300 static_assert((std::is_same<std::common_type<S<int> >::type, S<int> >::value), ""); 301 static_assert((std::is_same<std::common_type<S<int>, S<int> >::type, S<int> >::value), ""); 302 303 static_assert((std::is_same<std::common_type<int>::type, int>::value), ""); 304 static_assert((std::is_same<std::common_type<const int>::type, int>::value), ""); 305 static_assert((std::is_same<std::common_type<volatile int>::type, int>::value), ""); 306 static_assert((std::is_same<std::common_type<const volatile int>::type, int>::value), ""); 307 308 static_assert((std::is_same<std::common_type<int, int>::type, int>::value), ""); 309 static_assert((std::is_same<std::common_type<const int, int>::type, int>::value), ""); 310 static_assert((std::is_same<std::common_type<int, const int>::type, int>::value), ""); 311 static_assert((std::is_same<std::common_type<const int, const int>::type, int>::value), ""); 312 } 313