Home | History | Annotate | Download | only in meta.trans.other
      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