brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.8 KiB · acc3758 Raw
422 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// template<class From, class To>12// concept convertible_to;13 14#include <concepts>15#include <type_traits>16 17namespace {18enum ClassicEnum { a, b };19enum class ScopedEnum { x, y };20struct Empty {};21using nullptr_t = decltype(nullptr);22 23template <class T, class U>24void 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 31template <class T, class U>32void 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 39template <class T, class U>40void 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)50template <class T>51constexpr 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 63template <std::same_as<bool> >64constexpr 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 75template <std::same_as<nullptr_t> >76constexpr 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} // namespace88 89using Function = void();90using NoexceptFunction = void() noexcept;91using ConstFunction = void() const;92using Array = char[1];93 94struct StringType {95  StringType(const char*) {}96};97 98class NonCopyable {99  NonCopyable(NonCopyable&);100};101 102template <typename T>103class CannotInstantiate {104  enum { X = T::ThisExpressionWillBlowUp };105};106 107struct abstract {108  virtual int f() = 0;109};110 111struct ExplicitlyConvertible;112struct ImplicitlyConvertible;113 114struct ExplicitlyConstructible {115  explicit ExplicitlyConstructible(int);116  explicit ExplicitlyConstructible(ExplicitlyConvertible);117  explicit ExplicitlyConstructible(ImplicitlyConvertible) = delete;118};119 120struct ExplicitlyConvertible {121  explicit operator ExplicitlyConstructible() const {122    return ExplicitlyConstructible(0);123  }124};125 126struct ImplicitlyConstructible;127 128struct ImplicitlyConvertible {129  operator ExplicitlyConstructible() const;130  operator ImplicitlyConstructible() const = delete;131};132 133struct ImplicitlyConstructible {134  ImplicitlyConstructible(ImplicitlyConvertible);135};136 137int main(int, char**) {138  // void139  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  // Function154  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 type198  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  // NoexceptFunction208  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  // Array258  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  // char325  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  // NonCopyable384  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 when398  // 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 PR13592407  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