1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14, c++17 10 11 // template<class From, class To> 12 // concept common_reference_with; 13 14 #include <concepts> 15 #include <type_traits> 16 17 #include "test_macros.h" 18 19 template <class T, class U> 20 constexpr bool CheckCommonReferenceWith() noexcept { 21 static_assert(std::common_reference_with<T, U&>); 22 static_assert(std::common_reference_with<T, const U&>); 23 static_assert(std::common_reference_with<T, volatile U&>); 24 static_assert(std::common_reference_with<T, const volatile U&>); 25 static_assert(std::common_reference_with<T, U&&>); 26 static_assert(std::common_reference_with<T, const U&&>); 27 static_assert(std::common_reference_with<T, volatile U&&>); 28 static_assert(std::common_reference_with<T, const volatile U&&>); 29 static_assert(std::common_reference_with<T&, U&&>); 30 static_assert(std::common_reference_with<T&, const U&&>); 31 static_assert(std::common_reference_with<T&, volatile U&&>); 32 static_assert(std::common_reference_with<T&, const volatile U&&>); 33 static_assert(std::common_reference_with<const T&, U&&>); 34 static_assert(std::common_reference_with<const T&, const U&&>); 35 static_assert(std::common_reference_with<const T&, volatile U&&>); 36 static_assert(std::common_reference_with<const T&, const volatile U&&>); 37 static_assert(std::common_reference_with<volatile T&, U&&>); 38 static_assert(std::common_reference_with<volatile T&, const U&&>); 39 static_assert(std::common_reference_with<volatile T&, volatile U&&>); 40 static_assert(std::common_reference_with<volatile T&, const volatile U&&>); 41 static_assert(std::common_reference_with<const volatile T&, U&&>); 42 static_assert(std::common_reference_with<const volatile T&, const U&&>); 43 static_assert(std::common_reference_with<const volatile T&, volatile U&&>); 44 static_assert( 45 std::common_reference_with<const volatile T&, const volatile U&&>); 46 47 return std::common_reference_with<T, U>; 48 } 49 50 namespace BuiltinTypes { 51 // fundamental types 52 static_assert(std::common_reference_with<void, void>); 53 static_assert(CheckCommonReferenceWith<int, int>()); 54 static_assert(CheckCommonReferenceWith<int, long>()); 55 static_assert(CheckCommonReferenceWith<int, unsigned char>()); 56 #ifndef TEST_HAS_NO_INT128 57 static_assert(CheckCommonReferenceWith<int, __int128_t>()); 58 #endif 59 static_assert(CheckCommonReferenceWith<int, double>()); 60 61 // arrays 62 static_assert(CheckCommonReferenceWith<int[5], int[5]>()); 63 64 // pointers (common with void*) 65 static_assert(CheckCommonReferenceWith<int*, void*>()); 66 static_assert(CheckCommonReferenceWith<int*, const void*>()); 67 static_assert(CheckCommonReferenceWith<int*, volatile void*>()); 68 static_assert(CheckCommonReferenceWith<int*, const volatile void*>()); 69 static_assert(CheckCommonReferenceWith<const int*, void*>()); 70 static_assert(CheckCommonReferenceWith<const int*, const void*>()); 71 static_assert(CheckCommonReferenceWith<const int*, volatile void*>()); 72 static_assert(CheckCommonReferenceWith<const int*, const volatile void*>()); 73 static_assert(CheckCommonReferenceWith<volatile int*, void*>()); 74 static_assert(CheckCommonReferenceWith<volatile int*, const void*>()); 75 static_assert(CheckCommonReferenceWith<volatile int*, volatile void*>()); 76 static_assert(CheckCommonReferenceWith<volatile int*, const volatile void*>()); 77 static_assert(CheckCommonReferenceWith<const volatile int*, void*>()); 78 static_assert(CheckCommonReferenceWith<const volatile int*, const void*>()); 79 static_assert(CheckCommonReferenceWith<const volatile int*, volatile void*>()); 80 static_assert( 81 CheckCommonReferenceWith<const volatile int*, const volatile void*>()); 82 83 static_assert(CheckCommonReferenceWith<int (*)(), int (*)()>()); 84 static_assert(CheckCommonReferenceWith<int (*)(), int (*)() noexcept>()); 85 struct S {}; 86 static_assert(CheckCommonReferenceWith<int S::*, int S::*>()); 87 static_assert(CheckCommonReferenceWith<int S::*, const int S::*>()); 88 static_assert(CheckCommonReferenceWith<int (S::*)(), int (S::*)()>()); 89 static_assert(CheckCommonReferenceWith<int (S::*)(), int (S::*)() noexcept>()); 90 static_assert( 91 CheckCommonReferenceWith<int (S::*)() const, int (S::*)() const>()); 92 static_assert(CheckCommonReferenceWith<int (S::*)() const, 93 int (S::*)() const noexcept>()); 94 static_assert( 95 CheckCommonReferenceWith<int (S::*)() volatile, int (S::*)() volatile>()); 96 static_assert(CheckCommonReferenceWith<int (S::*)() volatile, 97 int (S::*)() volatile noexcept>()); 98 static_assert(CheckCommonReferenceWith<int (S::*)() const volatile, 99 int (S::*)() const volatile>()); 100 static_assert(CheckCommonReferenceWith<int (S::*)() const volatile, 101 int (S::*)() const volatile noexcept>()); 102 103 // nonsense 104 static_assert(!std::common_reference_with<double, float*>); 105 static_assert(!std::common_reference_with<int, int[5]>); 106 static_assert(!std::common_reference_with<int*, long*>); 107 static_assert(!std::common_reference_with<int*, unsigned int*>); 108 static_assert(!std::common_reference_with<int (*)(), int (*)(int)>); 109 static_assert(!std::common_reference_with<int S::*, float S::*>); 110 static_assert(!std::common_reference_with<int (S::*)(), int (S::*)() const>); 111 static_assert(!std::common_reference_with<int (S::*)(), int (S::*)() volatile>); 112 static_assert( 113 !std::common_reference_with<int (S::*)(), int (S::*)() const volatile>); 114 static_assert( 115 !std::common_reference_with<int (S::*)() const, int (S::*)() volatile>); 116 static_assert(!std::common_reference_with<int (S::*)() const, 117 int (S::*)() const volatile>); 118 static_assert(!std::common_reference_with<int (S::*)() volatile, 119 int (S::*)() const volatile>); 120 } // namespace BuiltinTypes 121 122 namespace NoDefaultCommonReference { 123 class T {}; 124 125 static_assert(!std::common_reference_with<T, int>); 126 static_assert(!std::common_reference_with<int, T>); 127 static_assert(!std::common_reference_with<T, int[10]>); 128 static_assert(!std::common_reference_with<T[10], int>); 129 static_assert(!std::common_reference_with<T*, int*>); 130 static_assert(!std::common_reference_with<T*, const int*>); 131 static_assert(!std::common_reference_with<T*, volatile int*>); 132 static_assert(!std::common_reference_with<T*, const volatile int*>); 133 static_assert(!std::common_reference_with<const T*, int*>); 134 static_assert(!std::common_reference_with<volatile T*, int*>); 135 static_assert(!std::common_reference_with<const volatile T*, int*>); 136 static_assert(!std::common_reference_with<const T*, const int*>); 137 static_assert(!std::common_reference_with<const T*, volatile int*>); 138 static_assert(!std::common_reference_with<const T*, const volatile int*>); 139 static_assert(!std::common_reference_with<const T*, const int*>); 140 static_assert(!std::common_reference_with<volatile T*, const int*>); 141 static_assert(!std::common_reference_with<const volatile T*, const int*>); 142 static_assert(!std::common_reference_with<volatile T*, const int*>); 143 static_assert(!std::common_reference_with<volatile T*, volatile int*>); 144 static_assert(!std::common_reference_with<volatile T*, const volatile int*>); 145 static_assert(!std::common_reference_with<const T*, volatile int*>); 146 static_assert(!std::common_reference_with<volatile T*, volatile int*>); 147 static_assert(!std::common_reference_with<const volatile T*, volatile int*>); 148 static_assert(!std::common_reference_with<const volatile T*, const int*>); 149 static_assert(!std::common_reference_with<const volatile T*, volatile int*>); 150 static_assert( 151 !std::common_reference_with<const volatile T*, const volatile int*>); 152 static_assert(!std::common_reference_with<const T*, const volatile int*>); 153 static_assert(!std::common_reference_with<volatile T*, const volatile int*>); 154 static_assert( 155 !std::common_reference_with<const volatile T*, const volatile int*>); 156 static_assert(!std::common_reference_with<T&, int&>); 157 static_assert(!std::common_reference_with<T&, const int&>); 158 static_assert(!std::common_reference_with<T&, volatile int&>); 159 static_assert(!std::common_reference_with<T&, const volatile int&>); 160 static_assert(!std::common_reference_with<const T&, int&>); 161 static_assert(!std::common_reference_with<volatile T&, int&>); 162 static_assert(!std::common_reference_with<const volatile T&, int&>); 163 static_assert(!std::common_reference_with<const T&, const int&>); 164 static_assert(!std::common_reference_with<const T&, volatile int&>); 165 static_assert(!std::common_reference_with<const T&, const volatile int&>); 166 static_assert(!std::common_reference_with<const T&, const int&>); 167 static_assert(!std::common_reference_with<volatile T&, const int&>); 168 static_assert(!std::common_reference_with<const volatile T&, const int&>); 169 static_assert(!std::common_reference_with<volatile T&, const int&>); 170 static_assert(!std::common_reference_with<volatile T&, volatile int&>); 171 static_assert(!std::common_reference_with<volatile T&, const volatile int&>); 172 static_assert(!std::common_reference_with<const T&, volatile int&>); 173 static_assert(!std::common_reference_with<volatile T&, volatile int&>); 174 static_assert(!std::common_reference_with<const volatile T&, volatile int&>); 175 static_assert(!std::common_reference_with<const volatile T&, const int&>); 176 static_assert(!std::common_reference_with<const volatile T&, volatile int&>); 177 static_assert( 178 !std::common_reference_with<const volatile T&, const volatile int&>); 179 static_assert(!std::common_reference_with<const T&, const volatile int&>); 180 static_assert(!std::common_reference_with<volatile T&, const volatile int&>); 181 static_assert( 182 !std::common_reference_with<const volatile T&, const volatile int&>); 183 static_assert(!std::common_reference_with<T&, int&&>); 184 static_assert(!std::common_reference_with<T&, const int&&>); 185 static_assert(!std::common_reference_with<T&, volatile int&&>); 186 static_assert(!std::common_reference_with<T&, const volatile int&&>); 187 static_assert(!std::common_reference_with<const T&, int&&>); 188 static_assert(!std::common_reference_with<volatile T&, int&&>); 189 static_assert(!std::common_reference_with<const volatile T&, int&&>); 190 static_assert(!std::common_reference_with<const T&, const int&&>); 191 static_assert(!std::common_reference_with<const T&, volatile int&&>); 192 static_assert(!std::common_reference_with<const T&, const volatile int&&>); 193 static_assert(!std::common_reference_with<const T&, const int&&>); 194 static_assert(!std::common_reference_with<volatile T&, const int&&>); 195 static_assert(!std::common_reference_with<const volatile T&, const int&&>); 196 static_assert(!std::common_reference_with<volatile T&, const int&&>); 197 static_assert(!std::common_reference_with<volatile T&, volatile int&&>); 198 static_assert(!std::common_reference_with<volatile T&, const volatile int&&>); 199 static_assert(!std::common_reference_with<const T&, volatile int&&>); 200 static_assert(!std::common_reference_with<volatile T&, volatile int&&>); 201 static_assert(!std::common_reference_with<const volatile T&, volatile int&&>); 202 static_assert(!std::common_reference_with<const volatile T&, const int&&>); 203 static_assert(!std::common_reference_with<const volatile T&, volatile int&&>); 204 static_assert( 205 !std::common_reference_with<const volatile T&, const volatile int&&>); 206 static_assert(!std::common_reference_with<const T&, const volatile int&&>); 207 static_assert(!std::common_reference_with<volatile T&, const volatile int&&>); 208 static_assert( 209 !std::common_reference_with<const volatile T&, const volatile int&&>); 210 static_assert(!std::common_reference_with<T&&, int&>); 211 static_assert(!std::common_reference_with<T&&, const int&>); 212 static_assert(!std::common_reference_with<T&&, volatile int&>); 213 static_assert(!std::common_reference_with<T&&, const volatile int&>); 214 static_assert(!std::common_reference_with<const T&&, int&>); 215 static_assert(!std::common_reference_with<volatile T&&, int&>); 216 static_assert(!std::common_reference_with<const volatile T&&, int&>); 217 static_assert(!std::common_reference_with<const T&&, const int&>); 218 static_assert(!std::common_reference_with<const T&&, volatile int&>); 219 static_assert(!std::common_reference_with<const T&&, const volatile int&>); 220 static_assert(!std::common_reference_with<const T&&, const int&>); 221 static_assert(!std::common_reference_with<volatile T&&, const int&>); 222 static_assert(!std::common_reference_with<const volatile T&&, const int&>); 223 static_assert(!std::common_reference_with<volatile T&&, const int&>); 224 static_assert(!std::common_reference_with<volatile T&&, volatile int&>); 225 static_assert(!std::common_reference_with<volatile T&&, const volatile int&>); 226 static_assert(!std::common_reference_with<const T&&, volatile int&>); 227 static_assert(!std::common_reference_with<volatile T&&, volatile int&>); 228 static_assert(!std::common_reference_with<const volatile T&&, volatile int&>); 229 static_assert(!std::common_reference_with<const volatile T&&, const int&>); 230 static_assert(!std::common_reference_with<const volatile T&&, volatile int&>); 231 static_assert( 232 !std::common_reference_with<const volatile T&&, const volatile int&>); 233 static_assert(!std::common_reference_with<const T&&, const volatile int&>); 234 static_assert(!std::common_reference_with<volatile T&&, const volatile int&>); 235 static_assert( 236 !std::common_reference_with<const volatile T&&, const volatile int&>); 237 static_assert(!std::common_reference_with<T&&, int&&>); 238 static_assert(!std::common_reference_with<T&&, const int&&>); 239 static_assert(!std::common_reference_with<T&&, volatile int&&>); 240 static_assert(!std::common_reference_with<T&&, const volatile int&&>); 241 static_assert(!std::common_reference_with<const T&&, int&&>); 242 static_assert(!std::common_reference_with<volatile T&&, int&&>); 243 static_assert(!std::common_reference_with<const volatile T&&, int&&>); 244 static_assert(!std::common_reference_with<const T&&, const int&&>); 245 static_assert(!std::common_reference_with<const T&&, volatile int&&>); 246 static_assert(!std::common_reference_with<const T&&, const volatile int&&>); 247 static_assert(!std::common_reference_with<const T&&, const int&&>); 248 static_assert(!std::common_reference_with<volatile T&&, const int&&>); 249 static_assert(!std::common_reference_with<const volatile T&&, const int&&>); 250 static_assert(!std::common_reference_with<volatile T&&, const int&&>); 251 static_assert(!std::common_reference_with<volatile T&&, volatile int&&>); 252 static_assert(!std::common_reference_with<volatile T&&, const volatile int&&>); 253 static_assert(!std::common_reference_with<const T&&, volatile int&&>); 254 static_assert(!std::common_reference_with<volatile T&&, volatile int&&>); 255 static_assert(!std::common_reference_with<const volatile T&&, volatile int&&>); 256 static_assert(!std::common_reference_with<const volatile T&&, const int&&>); 257 static_assert(!std::common_reference_with<const volatile T&&, volatile int&&>); 258 static_assert( 259 !std::common_reference_with<const volatile T&&, const volatile int&&>); 260 static_assert(!std::common_reference_with<const T&&, const volatile int&&>); 261 static_assert(!std::common_reference_with<volatile T&&, const volatile int&&>); 262 static_assert( 263 !std::common_reference_with<const volatile T&&, const volatile int&&>); 264 } // namespace NoDefaultCommonReference 265 266 struct BadBasicCommonReference { 267 // This test is ill-formed, NDR. If it ever blows up in our faces: that's a good thing. 268 // In the meantime, the test should be included. If compiler support is added, then an include guard 269 // should be placed so the test doesn't get deleted. 270 operator int() const; 271 operator int&(); 272 }; 273 static_assert(std::convertible_to<BadBasicCommonReference, int>); 274 static_assert(std::convertible_to<BadBasicCommonReference, int&>); 275 276 template <template <class> class X, template <class> class Y> 277 struct std::basic_common_reference<BadBasicCommonReference, int, X, Y> { 278 using type = BadBasicCommonReference&; 279 }; 280 281 template <template <class> class X, template <class> class Y> 282 struct std::basic_common_reference<int, BadBasicCommonReference, X, Y> { 283 using type = int&; 284 }; 285 286 static_assert(!std::common_reference_with<BadBasicCommonReference, int>); 287 288 struct StructNotConvertibleToCommonReference { 289 explicit(false) StructNotConvertibleToCommonReference(int); 290 }; 291 static_assert(std::convertible_to<int, StructNotConvertibleToCommonReference>); 292 293 template <template <class> class X, template <class> class Y> 294 struct std::basic_common_reference<StructNotConvertibleToCommonReference, int, X, Y> { 295 using type = int&; 296 }; 297 298 template <template <class> class X, template <class> class Y> 299 struct std::basic_common_reference<int, StructNotConvertibleToCommonReference, X, Y> { 300 using type = int&; 301 }; 302 303 static_assert( 304 !std::common_reference_with<StructNotConvertibleToCommonReference, int>); 305 306 struct IntNotConvertibleToCommonReference { 307 operator int&() const; 308 }; 309 310 template <template <class> class X, template <class> class Y> 311 struct std::basic_common_reference<IntNotConvertibleToCommonReference, int, X, Y> { 312 using type = int&; 313 }; 314 315 template <template <class> class X, template <class> class Y> 316 struct std::basic_common_reference<int, IntNotConvertibleToCommonReference, X, Y> { 317 using type = int&; 318 }; 319 320 static_assert( 321 !std::common_reference_with<StructNotConvertibleToCommonReference, int>); 322 323 struct HasCommonReference { 324 explicit(false) HasCommonReference(int); 325 operator int&() const; 326 }; 327 328 template <template <class> class X, template <class> class Y> 329 struct std::basic_common_reference<HasCommonReference, int, X, Y> { 330 using type = int&; 331 }; 332 333 template <template <class> class X, template <class> class Y> 334 struct std::basic_common_reference<int, HasCommonReference, X, Y> { 335 using type = int&; 336 }; 337 338 static_assert(!std::common_reference_with<HasCommonReference, int>); 339 static_assert(std::common_reference_with<HasCommonReference, int&>); 340