brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.8 KiB · b3fb96e Raw
296 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 T, class U>12// concept same_as;13 14#include <concepts>15#include <type_traits>16 17struct S1 {};18struct S2 {19  int i;20 21  int& f();22  double g(int x) const;23};24struct S3 {25  int& r;26};27struct S4 {28  int&& r;29};30struct S5 {31  int* p;32};33 34class C1 {};35class C2 {36  [[maybe_unused]] int i;37};38 39class C3 {40public:41  int i;42};43 44template <class T1, class T2 = T1>45class C4 {46  int t1;47  int t2;48};49 50template <class T1, class T2 = T1>51class C5 {52  [[maybe_unused]] T1 t1;53 54public:55  T2 t2;56};57 58template <class T1, class T2 = T1>59class C6 {60public:61  [[maybe_unused]] T1 t1;62  [[maybe_unused]] T2 t2;63};64 65template <class T>66struct identity {67  using type = T;68};69 70template <template <typename> class Modifier = identity>71void CheckSameAs() {72  static_assert(73      std::same_as<typename Modifier<int>::type, typename Modifier<int>::type>);74  static_assert(75      std::same_as<typename Modifier<S1>::type, typename Modifier<S1>::type>);76  static_assert(77      std::same_as<typename Modifier<S2>::type, typename Modifier<S2>::type>);78  static_assert(79      std::same_as<typename Modifier<S3>::type, typename Modifier<S3>::type>);80  static_assert(81      std::same_as<typename Modifier<S4>::type, typename Modifier<S4>::type>);82  static_assert(83      std::same_as<typename Modifier<S5>::type, typename Modifier<S5>::type>);84  static_assert(85      std::same_as<typename Modifier<C1>::type, typename Modifier<C1>::type>);86  static_assert(87      std::same_as<typename Modifier<C2>::type, typename Modifier<C2>::type>);88  static_assert(89      std::same_as<typename Modifier<C3>::type, typename Modifier<C3>::type>);90  static_assert(std::same_as<typename Modifier<C4<int> >::type,91                             typename Modifier<C4<int> >::type>);92  static_assert(std::same_as<typename Modifier<C4<int&> >::type,93                             typename Modifier<C4<int&> >::type>);94  static_assert(std::same_as<typename Modifier<C4<int&&> >::type,95                             typename Modifier<C4<int&&> >::type>);96  static_assert(std::same_as<typename Modifier<C5<int> >::type,97                             typename Modifier<C5<int> >::type>);98  static_assert(std::same_as<typename Modifier<C5<int&> >::type,99                             typename Modifier<C5<int&> >::type>);100  static_assert(std::same_as<typename Modifier<C5<int&&> >::type,101                             typename Modifier<C5<int&&> >::type>);102  static_assert(std::same_as<typename Modifier<C6<int> >::type,103                             typename Modifier<C6<int> >::type>);104  static_assert(std::same_as<typename Modifier<C6<int&> >::type,105                             typename Modifier<C6<int&> >::type>);106  static_assert(std::same_as<typename Modifier<C6<int&&> >::type,107                             typename Modifier<C6<int&&> >::type>);108 109  static_assert(std::same_as<typename Modifier<void>::type,110                             typename Modifier<void>::type>);111}112 113template <template <typename> class Modifier1,114          template <typename> class Modifier2>115void CheckNotSameAs() {116  static_assert(!std::same_as<typename Modifier1<int>::type,117                              typename Modifier2<int>::type>);118  static_assert(!std::same_as<typename Modifier1<S1>::type,119                              typename Modifier2<S1>::type>);120  static_assert(!std::same_as<typename Modifier1<S2>::type,121                              typename Modifier2<S2>::type>);122  static_assert(!std::same_as<typename Modifier1<S3>::type,123                              typename Modifier2<S3>::type>);124  static_assert(!std::same_as<typename Modifier1<S4>::type,125                              typename Modifier2<S4>::type>);126  static_assert(!std::same_as<typename Modifier1<S5>::type,127                              typename Modifier2<S5>::type>);128  static_assert(!std::same_as<typename Modifier1<C1>::type,129                              typename Modifier2<C1>::type>);130  static_assert(!std::same_as<typename Modifier1<C2>::type,131                              typename Modifier2<C2>::type>);132  static_assert(!std::same_as<typename Modifier1<C3>::type,133                              typename Modifier2<C3>::type>);134  static_assert(!std::same_as<typename Modifier1<C4<int> >::type,135                              typename Modifier2<C4<int> >::type>);136  static_assert(!std::same_as<typename Modifier1<C4<int&> >::type,137                              typename Modifier2<C4<int&> >::type>);138  static_assert(!std::same_as<typename Modifier1<C4<int&&> >::type,139                              typename Modifier2<C4<int&&> >::type>);140  static_assert(!std::same_as<typename Modifier1<C5<int> >::type,141                              typename Modifier2<C5<int> >::type>);142  static_assert(!std::same_as<typename Modifier1<C5<int&> >::type,143                              typename Modifier2<C5<int&> >::type>);144  static_assert(!std::same_as<typename Modifier1<C5<int&&> >::type,145                              typename Modifier2<C5<int&&> >::type>);146  static_assert(!std::same_as<typename Modifier1<C6<int> >::type,147                              typename Modifier2<C6<int> >::type>);148  static_assert(!std::same_as<typename Modifier1<C6<int&> >::type,149                              typename Modifier2<C6<int&> >::type>);150  static_assert(!std::same_as<typename Modifier1<C6<int&&> >::type,151                              typename Modifier2<C6<int&&> >::type>);152}153 154// Checks subsumption works as intended155template <class T, class U>156requires std::same_as<T, U> void SubsumptionTest();157 158// clang-format off159template <class T, class U>160requires std::same_as<U, T> && true // NOLINT(readability-simplify-boolean-expr)161int SubsumptionTest();162// clang-format on163 164static_assert(std::same_as<int, decltype(SubsumptionTest<int, int>())>);165static_assert(std::same_as<int, decltype(SubsumptionTest<void, void>())>);166static_assert(167    std::same_as<int, decltype(SubsumptionTest<int (*)(), int (*)()>())>);168static_assert(169    std::same_as<170        int, decltype(SubsumptionTest<double (&)(int), double (&)(int)>())>);171static_assert(172    std::same_as<int, decltype(SubsumptionTest<int S2::*, int S2::*>())>);173static_assert(174    std::same_as<int,175                 decltype(SubsumptionTest<int& (S2::*)(), int& (S2::*)()>())>);176 177int main(int, char**) {178  { // Checks std::same_as<T, T> is true179    CheckSameAs();180 181    // Checks std::same_as<T&, T&> is true182    CheckSameAs<std::add_lvalue_reference>();183 184    // Checks std::same_as<T&&, T&&> is true185    CheckSameAs<std::add_rvalue_reference>();186 187    // Checks std::same_as<const T, const T> is true188    CheckSameAs<std::add_const>();189 190    // Checks std::same_as<volatile T, volatile T> is true191    CheckSameAs<std::add_volatile>();192 193    // Checks std::same_as<const volatile T, const volatile T> is true194    CheckSameAs<std::add_cv>();195 196    // Checks std::same_as<T*, T*> is true197    CheckSameAs<std::add_pointer>();198 199    // Checks concrete types are identical200    static_assert(std::same_as<void, void>);201 202    using Void = void;203    static_assert(std::same_as<void, Void>);204 205    static_assert(std::same_as<int[1], int[1]>);206    static_assert(std::same_as<int[2], int[2]>);207 208    static_assert(std::same_as<int (*)(), int (*)()>);209    static_assert(std::same_as<void (&)(), void (&)()>);210    static_assert(std::same_as<S1& (*)(S1), S1& (*)(S1)>);211    static_assert(std::same_as<C1& (&)(S1, int), C1& (&)(S1, int)>);212 213    static_assert(std::same_as<int S2::*, int S2::*>);214    static_assert(std::same_as<double S2::*, double S2::*>);215 216    static_assert(std::same_as<int& (S2::*)(), int& (S2::*)()>);217    static_assert(std::same_as<double& (S2::*)(int), double& (S2::*)(int)>);218  }219 220  { // Checks that `T` and `T&` are distinct types221    CheckNotSameAs<identity, std::add_lvalue_reference>();222    CheckNotSameAs<std::add_lvalue_reference, identity>();223 224    // Checks that `T` and `T&&` are distinct types225    CheckNotSameAs<identity, std::add_rvalue_reference>();226    CheckNotSameAs<std::add_rvalue_reference, identity>();227 228    // Checks that `T` and `const T` are distinct types229    CheckNotSameAs<identity, std::add_const>();230    CheckNotSameAs<std::add_const, identity>();231 232    // Checks that `T` and `volatile T` are distinct types233    CheckNotSameAs<identity, std::add_volatile>();234    CheckNotSameAs<std::add_volatile, identity>();235 236    // Checks that `T` and `const volatile T` are distinct types237    CheckNotSameAs<identity, std::add_cv>();238    CheckNotSameAs<std::add_cv, identity>();239 240    // Checks that `const T` and `volatile T` are distinct types241    CheckNotSameAs<std::add_const, std::add_volatile>();242    CheckNotSameAs<std::add_volatile, std::add_const>();243 244    // Checks that `const T` and `const volatile T` are distinct types245    CheckNotSameAs<std::add_const, std::add_cv>();246    CheckNotSameAs<std::add_cv, std::add_const>();247 248    // Checks that `volatile T` and `const volatile T` are distinct types249    CheckNotSameAs<std::add_volatile, std::add_cv>();250    CheckNotSameAs<std::add_cv, std::add_volatile>();251 252    // Checks `T&` and `T&&` are distinct types253    CheckNotSameAs<std::add_lvalue_reference, std::add_rvalue_reference>();254    CheckNotSameAs<std::add_rvalue_reference, std::add_lvalue_reference>();255  }256 257  { // Checks different type names are distinct types258    static_assert(!std::same_as<S1, C1>);259    static_assert(!std::same_as<C4<int>, C5<int> >);260    static_assert(!std::same_as<C4<int>, C5<int> >);261    static_assert(!std::same_as<C5<int, double>, C5<double, int> >);262 263    static_assert(!std::same_as<int&, const int&>);264    static_assert(!std::same_as<int&, volatile int&>);265    static_assert(!std::same_as<int&, const volatile int&>);266 267    static_assert(!std::same_as<int&&, const int&>);268    static_assert(!std::same_as<int&&, volatile int&>);269    static_assert(!std::same_as<int&&, const volatile int&>);270 271    static_assert(!std::same_as<int&, const int&&>);272    static_assert(!std::same_as<int&, volatile int&&>);273    static_assert(!std::same_as<int&, const volatile int&&>);274 275    static_assert(!std::same_as<int&&, const int&&>);276    static_assert(!std::same_as<int&&, volatile int&&>);277    static_assert(!std::same_as<int&&, const volatile int&&>);278 279    static_assert(!std::same_as<void, int>);280 281    static_assert(!std::same_as<int[1], int[2]>);282    static_assert(!std::same_as<double[1], int[2]>);283 284    static_assert(!std::same_as<int* (*)(), const int* (*)()>);285    static_assert(!std::same_as<void (&)(), void (&)(S1)>);286    static_assert(!std::same_as<S1 (*)(S1), S1& (*)(S1)>);287    static_assert(!std::same_as<C3 (&)(int), C1& (&)(S1, int)>);288 289    static_assert(!std::same_as<int S2::*, double S2::*>);290 291    static_assert(!std::same_as<int& (S2::*)(), double& (S2::*)(int)>);292  }293 294  return 0;295}296