| 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 convertible_to; |
| 13 | |
| 14 | #include <concepts> |
| 15 | #include <type_traits> |
| 16 | |
| 17 | namespace { |
| 18 | enum ClassicEnum { a, b }; |
| 19 | enum class ScopedEnum { x, y }; |
| 20 | struct Empty {}; |
| 21 | using nullptr_t = decltype(nullptr); |
| 22 | |
| 23 | template <class T, class U> |
| 24 | void CheckConvertibleTo() { |
| 25 | static_assert(std::convertible_to<T, U>); |
| 26 | static_assert(std::convertible_to<const T, U>); |
| 27 | static_assert(std::convertible_to<T, const U>); |
| 28 | static_assert(std::convertible_to<const T, const U>); |
| 29 | } |
| 30 | |
| 31 | template <class T, class U> |
| 32 | void CheckNotConvertibleTo() { |
| 33 | static_assert(!std::convertible_to<T, U>); |
| 34 | static_assert(!std::convertible_to<const T, U>); |
| 35 | static_assert(!std::convertible_to<T, const U>); |
| 36 | static_assert(!std::convertible_to<const T, const U>); |
| 37 | } |
| 38 | |
| 39 | template <class T, class U> |
| 40 | void CheckIsConvertibleButNotConvertibleTo() { |
| 41 | // Sanity check T is either implicitly xor explicitly convertible to U. |
| 42 | static_assert(std::is_convertible_v<T, U>); |
| 43 | static_assert(std::is_convertible_v<const T, U>); |
| 44 | static_assert(std::is_convertible_v<T, const U>); |
| 45 | static_assert(std::is_convertible_v<const T, const U>); |
| 46 | CheckNotConvertibleTo<T, U>(); |
| 47 | } |
| 48 | |
| 49 | // Tests that should objectively return false (except for bool and nullptr_t) |
| 50 | template <class T> |
| 51 | constexpr void CommonlyNotConvertibleTo() { |
| 52 | CheckNotConvertibleTo<T, void>(); |
| 53 | CheckNotConvertibleTo<T, nullptr_t>(); |
| 54 | CheckNotConvertibleTo<T, T*>(); |
| 55 | CheckNotConvertibleTo<T, T Empty::*>(); |
| 56 | CheckNotConvertibleTo<T, T (Empty::*)()>(); |
| 57 | CheckNotConvertibleTo<T, T[sizeof(T)]>(); |
| 58 | CheckNotConvertibleTo<T, T (*)()>(); |
| 59 | CheckNotConvertibleTo<T, T (&)()>(); |
| 60 | CheckNotConvertibleTo<T, T(&&)()>(); |
| 61 | } |
| 62 | |
| 63 | template <std::same_as<bool> > |
| 64 | constexpr void CommonlyNotConvertibleTo() { |
| 65 | CheckNotConvertibleTo<bool, void>(); |
| 66 | CheckNotConvertibleTo<bool, nullptr_t>(); |
| 67 | CheckConvertibleTo<bool Empty::*, bool>(); |
| 68 | CheckConvertibleTo<bool (Empty::*)(), bool>(); |
| 69 | CheckConvertibleTo<bool[2], bool>(); |
| 70 | CheckConvertibleTo<bool (*)(), bool>(); |
| 71 | CheckConvertibleTo<bool (&)(), bool>(); |
| 72 | CheckConvertibleTo<bool(&&)(), bool>(); |
| 73 | } |
| 74 | |
| 75 | template <std::same_as<nullptr_t> > |
| 76 | constexpr void CommonlyNotConvertibleTo() { |
| 77 | CheckNotConvertibleTo<nullptr_t, void>(); |
| 78 | CheckConvertibleTo<nullptr_t, nullptr_t>(); |
| 79 | CheckConvertibleTo<nullptr_t, void*>(); |
| 80 | CheckConvertibleTo<nullptr_t, int Empty::*>(); |
| 81 | CheckConvertibleTo<nullptr_t, void (Empty::*)()>(); |
| 82 | CheckNotConvertibleTo<nullptr_t, int[2]>(); |
| 83 | CheckConvertibleTo<nullptr_t, void (*)()>(); |
| 84 | CheckNotConvertibleTo<nullptr_t, void (&)()>(); |
| 85 | CheckNotConvertibleTo<nullptr_t, void(&&)()>(); |
| 86 | } |
| 87 | } // namespace |
| 88 | |
| 89 | using Function = void(); |
| 90 | using NoexceptFunction = void() noexcept; |
| 91 | using ConstFunction = void() const; |
| 92 | using Array = char[1]; |
| 93 | |
| 94 | struct StringType { |
| 95 | StringType(const char*) {} |
| 96 | }; |
| 97 | |
| 98 | class NonCopyable { |
| 99 | NonCopyable(NonCopyable&); |
| 100 | }; |
| 101 | |
| 102 | template <typename T> |
| 103 | class CannotInstantiate { |
| 104 | enum { X = T::ThisExpressionWillBlowUp }; |
| 105 | }; |
| 106 | |
| 107 | struct abstract { |
| 108 | virtual int f() = 0; |
| 109 | }; |
| 110 | |
| 111 | struct ExplicitlyConvertible; |
| 112 | struct ImplicitlyConvertible; |
| 113 | |
| 114 | struct ExplicitlyConstructible { |
| 115 | explicit ExplicitlyConstructible(int); |
| 116 | explicit ExplicitlyConstructible(ExplicitlyConvertible); |
| 117 | explicit ExplicitlyConstructible(ImplicitlyConvertible) = delete; |
| 118 | }; |
| 119 | |
| 120 | struct ExplicitlyConvertible { |
| 121 | explicit operator ExplicitlyConstructible() const { |
| 122 | return ExplicitlyConstructible(0); |
| 123 | } |
| 124 | }; |
| 125 | |
| 126 | struct ImplicitlyConstructible; |
| 127 | |
| 128 | struct ImplicitlyConvertible { |
| 129 | operator ExplicitlyConstructible() const; |
| 130 | operator ImplicitlyConstructible() const = delete; |
| 131 | }; |
| 132 | |
| 133 | struct ImplicitlyConstructible { |
| 134 | ImplicitlyConstructible(ImplicitlyConvertible); |
| 135 | }; |
| 136 | |
| 137 | int main(int, char**) { |
| 138 | // void |
| 139 | CheckConvertibleTo<void, void>(); |
| 140 | CheckNotConvertibleTo<void, Function>(); |
| 141 | CheckNotConvertibleTo<void, Function&>(); |
| 142 | CheckNotConvertibleTo<void, Function*>(); |
| 143 | CheckNotConvertibleTo<void, NoexceptFunction>(); |
| 144 | CheckNotConvertibleTo<void, NoexceptFunction&>(); |
| 145 | CheckNotConvertibleTo<void, NoexceptFunction*>(); |
| 146 | CheckNotConvertibleTo<void, Array>(); |
| 147 | CheckNotConvertibleTo<void, Array&>(); |
| 148 | CheckNotConvertibleTo<void, char>(); |
| 149 | CheckNotConvertibleTo<void, char&>(); |
| 150 | CheckNotConvertibleTo<void, char*>(); |
| 151 | CheckNotConvertibleTo<char, void>(); |
| 152 | |
| 153 | // Function |
| 154 | CheckNotConvertibleTo<Function, void>(); |
| 155 | CheckNotConvertibleTo<Function, Function>(); |
| 156 | CheckNotConvertibleTo<Function, NoexceptFunction>(); |
| 157 | CheckNotConvertibleTo<Function, NoexceptFunction&>(); |
| 158 | CheckNotConvertibleTo<Function, NoexceptFunction*>(); |
| 159 | CheckNotConvertibleTo<Function, NoexceptFunction* const>(); |
| 160 | CheckConvertibleTo<Function, Function&>(); |
| 161 | CheckConvertibleTo<Function, Function*>(); |
| 162 | CheckConvertibleTo<Function, Function* const>(); |
| 163 | |
| 164 | static_assert(std::convertible_to<Function, Function&&>); |
| 165 | static_assert(!std::convertible_to<Function, NoexceptFunction&&>); |
| 166 | |
| 167 | CheckNotConvertibleTo<Function, Array>(); |
| 168 | CheckNotConvertibleTo<Function, Array&>(); |
| 169 | CheckNotConvertibleTo<Function, char>(); |
| 170 | CheckNotConvertibleTo<Function, char&>(); |
| 171 | CheckNotConvertibleTo<Function, char*>(); |
| 172 | |
| 173 | // Function& |
| 174 | CheckNotConvertibleTo<Function&, void>(); |
| 175 | CheckNotConvertibleTo<Function&, Function>(); |
| 176 | CheckConvertibleTo<Function&, Function&>(); |
| 177 | |
| 178 | CheckConvertibleTo<Function&, Function*>(); |
| 179 | CheckNotConvertibleTo<Function&, Array>(); |
| 180 | CheckNotConvertibleTo<Function&, Array&>(); |
| 181 | CheckNotConvertibleTo<Function&, char>(); |
| 182 | CheckNotConvertibleTo<Function&, char&>(); |
| 183 | CheckNotConvertibleTo<Function&, char*>(); |
| 184 | |
| 185 | // Function* |
| 186 | CheckNotConvertibleTo<Function*, void>(); |
| 187 | CheckNotConvertibleTo<Function*, Function>(); |
| 188 | CheckNotConvertibleTo<Function*, Function&>(); |
| 189 | CheckConvertibleTo<Function*, Function*>(); |
| 190 | |
| 191 | CheckNotConvertibleTo<Function*, Array>(); |
| 192 | CheckNotConvertibleTo<Function*, Array&>(); |
| 193 | CheckNotConvertibleTo<Function*, char>(); |
| 194 | CheckNotConvertibleTo<Function*, char&>(); |
| 195 | CheckNotConvertibleTo<Function*, char*>(); |
| 196 | |
| 197 | // Non-referencable function type |
| 198 | static_assert(!std::convertible_to<ConstFunction, Function>); |
| 199 | static_assert(!std::convertible_to<ConstFunction, Function*>); |
| 200 | static_assert(!std::convertible_to<ConstFunction, Function&>); |
| 201 | static_assert(!std::convertible_to<ConstFunction, Function&&>); |
| 202 | static_assert(!std::convertible_to<Function*, ConstFunction>); |
| 203 | static_assert(!std::convertible_to<Function&, ConstFunction>); |
| 204 | static_assert(!std::convertible_to<ConstFunction, ConstFunction>); |
| 205 | static_assert(!std::convertible_to<ConstFunction, void>); |
| 206 | |
| 207 | // NoexceptFunction |
| 208 | CheckNotConvertibleTo<NoexceptFunction, void>(); |
| 209 | CheckNotConvertibleTo<NoexceptFunction, Function>(); |
| 210 | CheckNotConvertibleTo<NoexceptFunction, NoexceptFunction>(); |
| 211 | CheckConvertibleTo<NoexceptFunction, NoexceptFunction&>(); |
| 212 | CheckConvertibleTo<NoexceptFunction, NoexceptFunction*>(); |
| 213 | CheckConvertibleTo<NoexceptFunction, NoexceptFunction* const>(); |
| 214 | CheckConvertibleTo<NoexceptFunction, Function&>(); |
| 215 | CheckConvertibleTo<NoexceptFunction, Function*>(); |
| 216 | CheckConvertibleTo<NoexceptFunction, Function* const>(); |
| 217 | |
| 218 | static_assert(std::convertible_to<NoexceptFunction, Function&&>); |
| 219 | static_assert(std::convertible_to<NoexceptFunction, NoexceptFunction&&>); |
| 220 | |
| 221 | CheckNotConvertibleTo<NoexceptFunction, Array>(); |
| 222 | CheckNotConvertibleTo<NoexceptFunction, Array&>(); |
| 223 | CheckNotConvertibleTo<NoexceptFunction, char>(); |
| 224 | CheckNotConvertibleTo<NoexceptFunction, char&>(); |
| 225 | CheckNotConvertibleTo<NoexceptFunction, char*>(); |
| 226 | |
| 227 | // NoexceptFunction& |
| 228 | CheckNotConvertibleTo<NoexceptFunction&, void>(); |
| 229 | CheckNotConvertibleTo<NoexceptFunction&, Function>(); |
| 230 | CheckNotConvertibleTo<NoexceptFunction&, NoexceptFunction>(); |
| 231 | CheckConvertibleTo<NoexceptFunction&, Function&>(); |
| 232 | CheckConvertibleTo<NoexceptFunction&, NoexceptFunction&>(); |
| 233 | |
| 234 | CheckConvertibleTo<NoexceptFunction&, Function*>(); |
| 235 | CheckConvertibleTo<NoexceptFunction&, NoexceptFunction*>(); |
| 236 | CheckNotConvertibleTo<NoexceptFunction&, Array>(); |
| 237 | CheckNotConvertibleTo<NoexceptFunction&, Array&>(); |
| 238 | CheckNotConvertibleTo<NoexceptFunction&, char>(); |
| 239 | CheckNotConvertibleTo<NoexceptFunction&, char&>(); |
| 240 | CheckNotConvertibleTo<NoexceptFunction&, char*>(); |
| 241 | |
| 242 | // NoexceptFunction* |
| 243 | CheckNotConvertibleTo<NoexceptFunction*, void>(); |
| 244 | CheckNotConvertibleTo<NoexceptFunction*, Function>(); |
| 245 | CheckNotConvertibleTo<NoexceptFunction*, Function&>(); |
| 246 | CheckNotConvertibleTo<NoexceptFunction*, NoexceptFunction>(); |
| 247 | CheckNotConvertibleTo<NoexceptFunction*, NoexceptFunction&>(); |
| 248 | CheckConvertibleTo<NoexceptFunction*, Function*>(); |
| 249 | CheckConvertibleTo<NoexceptFunction*, NoexceptFunction*>(); |
| 250 | |
| 251 | CheckNotConvertibleTo<NoexceptFunction*, Array>(); |
| 252 | CheckNotConvertibleTo<NoexceptFunction*, Array&>(); |
| 253 | CheckNotConvertibleTo<NoexceptFunction*, char>(); |
| 254 | CheckNotConvertibleTo<NoexceptFunction*, char&>(); |
| 255 | CheckNotConvertibleTo<NoexceptFunction*, char*>(); |
| 256 | |
| 257 | // Array |
| 258 | CheckNotConvertibleTo<Array, void>(); |
| 259 | CheckNotConvertibleTo<Array, Function>(); |
| 260 | CheckNotConvertibleTo<Array, Function&>(); |
| 261 | CheckNotConvertibleTo<Array, Function*>(); |
| 262 | CheckNotConvertibleTo<Array, NoexceptFunction>(); |
| 263 | CheckNotConvertibleTo<Array, NoexceptFunction&>(); |
| 264 | CheckNotConvertibleTo<Array, NoexceptFunction*>(); |
| 265 | CheckNotConvertibleTo<Array, Array>(); |
| 266 | |
| 267 | static_assert(!std::convertible_to<Array, Array&>); |
| 268 | static_assert(std::convertible_to<Array, const Array&>); |
| 269 | static_assert(!std::convertible_to<Array, const volatile Array&>); |
| 270 | |
| 271 | static_assert(!std::convertible_to<const Array, Array&>); |
| 272 | static_assert(std::convertible_to<const Array, const Array&>); |
| 273 | static_assert(!std::convertible_to<Array, volatile Array&>); |
| 274 | static_assert(!std::convertible_to<Array, const volatile Array&>); |
| 275 | |
| 276 | static_assert(std::convertible_to<Array, Array&&>); |
| 277 | static_assert(std::convertible_to<Array, const Array&&>); |
| 278 | static_assert(std::convertible_to<Array, volatile Array&&>); |
| 279 | static_assert(std::convertible_to<Array, const volatile Array&&>); |
| 280 | static_assert(std::convertible_to<const Array, const Array&&>); |
| 281 | static_assert(!std::convertible_to<Array&, Array&&>); |
| 282 | static_assert(!std::convertible_to<Array&&, Array&>); |
| 283 | |
| 284 | CheckNotConvertibleTo<Array, char>(); |
| 285 | CheckNotConvertibleTo<Array, char&>(); |
| 286 | |
| 287 | static_assert(std::convertible_to<Array, char*>); |
| 288 | static_assert(std::convertible_to<Array, const char*>); |
| 289 | static_assert(std::convertible_to<Array, char* const>); |
| 290 | static_assert(std::convertible_to<Array, char* const volatile>); |
| 291 | |
| 292 | static_assert(!std::convertible_to<const Array, char*>); |
| 293 | static_assert(std::convertible_to<const Array, const char*>); |
| 294 | |
| 295 | static_assert(!std::convertible_to<char[42][42], char*>); |
| 296 | static_assert(!std::convertible_to<char[][1], char*>); |
| 297 | |
| 298 | // Array& |
| 299 | CheckNotConvertibleTo<Array&, void>(); |
| 300 | CheckNotConvertibleTo<Array&, Function>(); |
| 301 | CheckNotConvertibleTo<Array&, Function&>(); |
| 302 | CheckNotConvertibleTo<Array&, Function*>(); |
| 303 | CheckNotConvertibleTo<Array&, NoexceptFunction>(); |
| 304 | CheckNotConvertibleTo<Array&, NoexceptFunction&>(); |
| 305 | CheckNotConvertibleTo<Array&, NoexceptFunction*>(); |
| 306 | CheckNotConvertibleTo<Array&, Array>(); |
| 307 | |
| 308 | static_assert(std::convertible_to<Array&, Array&>); |
| 309 | static_assert(std::convertible_to<Array&, const Array&>); |
| 310 | static_assert(!std::convertible_to<const Array&, Array&>); |
| 311 | static_assert(std::convertible_to<const Array&, const Array&>); |
| 312 | |
| 313 | CheckNotConvertibleTo<Array&, char>(); |
| 314 | CheckNotConvertibleTo<Array&, char&>(); |
| 315 | |
| 316 | static_assert(std::convertible_to<Array&, char*>); |
| 317 | static_assert(std::convertible_to<Array&, const char*>); |
| 318 | static_assert(!std::convertible_to<const Array&, char*>); |
| 319 | static_assert(std::convertible_to<const Array&, const char*>); |
| 320 | |
| 321 | static_assert(std::convertible_to<Array, StringType>); |
| 322 | static_assert(std::convertible_to<char(&)[], StringType>); |
| 323 | |
| 324 | // char |
| 325 | CheckNotConvertibleTo<char, void>(); |
| 326 | CheckNotConvertibleTo<char, Function>(); |
| 327 | CheckNotConvertibleTo<char, Function&>(); |
| 328 | CheckNotConvertibleTo<char, Function*>(); |
| 329 | CheckNotConvertibleTo<char, NoexceptFunction>(); |
| 330 | CheckNotConvertibleTo<char, NoexceptFunction&>(); |
| 331 | CheckNotConvertibleTo<char, NoexceptFunction*>(); |
| 332 | CheckNotConvertibleTo<char, Array>(); |
| 333 | CheckNotConvertibleTo<char, Array&>(); |
| 334 | |
| 335 | CheckConvertibleTo<char, char>(); |
| 336 | |
| 337 | static_assert(!std::convertible_to<char, char&>); |
| 338 | static_assert(std::convertible_to<char, const char&>); |
| 339 | static_assert(!std::convertible_to<const char, char&>); |
| 340 | static_assert(std::convertible_to<const char, const char&>); |
| 341 | |
| 342 | CheckNotConvertibleTo<char, char*>(); |
| 343 | |
| 344 | // char& |
| 345 | CheckNotConvertibleTo<char&, void>(); |
| 346 | CheckNotConvertibleTo<char&, Function>(); |
| 347 | CheckNotConvertibleTo<char&, Function&>(); |
| 348 | CheckNotConvertibleTo<char&, Function*>(); |
| 349 | CheckNotConvertibleTo<char&, NoexceptFunction>(); |
| 350 | CheckNotConvertibleTo<char&, NoexceptFunction&>(); |
| 351 | CheckNotConvertibleTo<char&, NoexceptFunction*>(); |
| 352 | CheckNotConvertibleTo<char&, Array>(); |
| 353 | CheckNotConvertibleTo<char&, Array&>(); |
| 354 | |
| 355 | CheckConvertibleTo<char&, char>(); |
| 356 | |
| 357 | static_assert(std::convertible_to<char&, char&>); |
| 358 | static_assert(std::convertible_to<char&, const char&>); |
| 359 | static_assert(!std::convertible_to<const char&, char&>); |
| 360 | static_assert(std::convertible_to<const char&, const char&>); |
| 361 | |
| 362 | CheckNotConvertibleTo<char&, char*>(); |
| 363 | |
| 364 | // char* |
| 365 | CheckNotConvertibleTo<char*, void>(); |
| 366 | CheckNotConvertibleTo<char*, Function>(); |
| 367 | CheckNotConvertibleTo<char*, Function&>(); |
| 368 | CheckNotConvertibleTo<char*, Function*>(); |
| 369 | CheckNotConvertibleTo<char*, NoexceptFunction>(); |
| 370 | CheckNotConvertibleTo<char*, NoexceptFunction&>(); |
| 371 | CheckNotConvertibleTo<char*, NoexceptFunction*>(); |
| 372 | CheckNotConvertibleTo<char*, Array>(); |
| 373 | CheckNotConvertibleTo<char*, Array&>(); |
| 374 | |
| 375 | CheckNotConvertibleTo<char*, char>(); |
| 376 | CheckNotConvertibleTo<char*, char&>(); |
| 377 | |
| 378 | static_assert(std::convertible_to<char*, char*>); |
| 379 | static_assert(std::convertible_to<char*, const char*>); |
| 380 | static_assert(!std::convertible_to<const char*, char*>); |
| 381 | static_assert(std::convertible_to<const char*, const char*>); |
| 382 | |
| 383 | // NonCopyable |
| 384 | static_assert(std::convertible_to<NonCopyable&, NonCopyable&>); |
| 385 | static_assert(std::convertible_to<NonCopyable&, const NonCopyable&>); |
| 386 | static_assert(std::convertible_to<NonCopyable&, const volatile NonCopyable&>); |
| 387 | static_assert(std::convertible_to<NonCopyable&, volatile NonCopyable&>); |
| 388 | static_assert(std::convertible_to<const NonCopyable&, const NonCopyable&>); |
| 389 | static_assert( |
| 390 | std::convertible_to<const NonCopyable&, const volatile NonCopyable&>); |
| 391 | static_assert( |
| 392 | std::convertible_to<volatile NonCopyable&, const volatile NonCopyable&>); |
| 393 | static_assert(std::convertible_to<const volatile NonCopyable&, |
| 394 | const volatile NonCopyable&>); |
| 395 | static_assert(!std::convertible_to<const NonCopyable&, NonCopyable&>); |
| 396 | |
| 397 | // This test requires Access control SFINAE which we only have in C++11 or when |
| 398 | // we are using the compiler builtin for convertible_to. |
| 399 | CheckNotConvertibleTo<NonCopyable&, NonCopyable>(); |
| 400 | |
| 401 | // Ensure that CannotInstantiate is not instantiated by convertible_to when it is not needed. |
| 402 | // For example CannotInstantiate is instantiated as a part of ADL lookup for arguments of type CannotInstantiate*. |
| 403 | static_assert( |
| 404 | std::convertible_to<CannotInstantiate<int>*, CannotInstantiate<int>*>); |
| 405 | |
| 406 | // Test for PR13592 |
| 407 | static_assert(!std::convertible_to<abstract, abstract>); |
| 408 | |
| 409 | CommonlyNotConvertibleTo<int>(); |
| 410 | CommonlyNotConvertibleTo<bool>(); |
| 411 | CommonlyNotConvertibleTo<nullptr_t>(); |
| 412 | |
| 413 | CheckNotConvertibleTo<int, ExplicitlyConstructible>(); |
| 414 | CheckNotConvertibleTo<ExplicitlyConvertible, ExplicitlyConstructible>(); |
| 415 | CheckNotConvertibleTo<ExplicitlyConstructible, ExplicitlyConvertible>(); |
| 416 | CheckIsConvertibleButNotConvertibleTo<ImplicitlyConvertible, |
| 417 | ExplicitlyConstructible>(); |
| 418 | CheckNotConvertibleTo<ImplicitlyConstructible, ImplicitlyConvertible>(); |
| 419 | |
| 420 | return 0; |
| 421 | } |
| 422 | |