Home | History | Annotate | Download | only in type_traits
      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 // UNSUPPORTED: c++98, c++03
     11 
     12 // <type_traits>
     13 
     14 // __lazy_enable_if, __lazy_not, __lazy_and and __lazy_or
     15 
     16 // Test the libc++ lazy meta-programming helpers in <type_traits>
     17 
     18 #include <type_traits>
     19 
     20 template <class Type>
     21 struct Identity {
     22     typedef Type type;
     23 };
     24 
     25 typedef std::true_type TrueT;
     26 typedef std::false_type FalseT;
     27 
     28 typedef Identity<TrueT>  LazyTrueT;
     29 typedef Identity<FalseT> LazyFalseT;
     30 
     31 // A type that cannot be instantiated
     32 template <class T>
     33 struct CannotInst {
     34     typedef T type;
     35     static_assert(std::is_same<T, T>::value == false, "");
     36 };
     37 
     38 
     39 template <int Value>
     40 struct NextInt {
     41     typedef NextInt<Value + 1> type;
     42     static const int value = Value;
     43 };
     44 
     45 template <int Value>
     46 const int NextInt<Value>::value;
     47 
     48 
     49 template <class Type>
     50 struct HasTypeImp {
     51     template <class Up, class = typename Up::type>
     52     static TrueT test(int);
     53     template <class>
     54     static FalseT test(...);
     55 
     56     typedef decltype(test<Type>(0)) type;
     57 };
     58 
     59 // A metafunction that returns True if Type has a nested 'type' typedef
     60 // and false otherwise.
     61 template <class Type>
     62 struct HasType : HasTypeImp<Type>::type {};
     63 
     64 void LazyEnableIfTest() {
     65     {
     66         typedef std::__lazy_enable_if<true, NextInt<0> > Result;
     67         static_assert(HasType<Result>::value, "");
     68         static_assert(Result::type::value == 1, "");
     69     }
     70     {
     71         typedef std::__lazy_enable_if<false, CannotInst<int> > Result;
     72         static_assert(!HasType<Result>::value, "");
     73     }
     74 }
     75 
     76 void LazyNotTest() {
     77     {
     78         typedef std::__lazy_not<LazyTrueT> NotT;
     79         static_assert(std::is_same<typename NotT::type, FalseT>::value, "");
     80         static_assert(NotT::value == false, "");
     81     }
     82     {
     83         typedef std::__lazy_not<LazyFalseT> NotT;
     84         static_assert(std::is_same<typename NotT::type, TrueT>::value, "");
     85         static_assert(NotT::value == true, "");
     86     }
     87     {
     88          // Check that CannotInst<int> is not instantiated.
     89         typedef std::__lazy_not<CannotInst<int> > NotT;
     90 
     91         static_assert(std::is_same<NotT, NotT>::value, "");
     92 
     93     }
     94 }
     95 
     96 void LazyAndTest() {
     97     { // Test that it acts as the identity function for a single value
     98         static_assert(std::__lazy_and<LazyFalseT>::value == false, "");
     99         static_assert(std::__lazy_and<LazyTrueT>::value == true, "");
    100     }
    101     {
    102         static_assert(std::__lazy_and<LazyTrueT, LazyTrueT>::value == true, "");
    103         static_assert(std::__lazy_and<LazyTrueT, LazyFalseT>::value == false, "");
    104         static_assert(std::__lazy_and<LazyFalseT, LazyTrueT>::value == false, "");
    105         static_assert(std::__lazy_and<LazyFalseT, LazyFalseT>::value == false, "");
    106     }
    107     { // Test short circuiting - CannotInst<T> should never be instantiated.
    108         static_assert(std::__lazy_and<LazyFalseT, CannotInst<int>>::value == false, "");
    109         static_assert(std::__lazy_and<LazyTrueT, LazyFalseT, CannotInst<int>>::value == false, "");
    110     }
    111 }
    112 
    113 
    114 void LazyOrTest() {
    115     { // Test that it acts as the identity function for a single value
    116         static_assert(std::__lazy_or<LazyFalseT>::value == false, "");
    117         static_assert(std::__lazy_or<LazyTrueT>::value == true, "");
    118     }
    119     {
    120         static_assert(std::__lazy_or<LazyTrueT, LazyTrueT>::value == true, "");
    121         static_assert(std::__lazy_or<LazyTrueT, LazyFalseT>::value == true, "");
    122         static_assert(std::__lazy_or<LazyFalseT, LazyTrueT>::value == true, "");
    123         static_assert(std::__lazy_or<LazyFalseT, LazyFalseT>::value == false, "");
    124     }
    125     { // Test short circuiting - CannotInst<T> should never be instantiated.
    126         static_assert(std::__lazy_or<LazyTrueT, CannotInst<int>>::value == true, "");
    127         static_assert(std::__lazy_or<LazyFalseT, LazyTrueT, CannotInst<int>>::value == true, "");
    128     }
    129 }
    130 
    131 
    132 int main() {
    133     LazyEnableIfTest();
    134     LazyNotTest();
    135     LazyAndTest();
    136     LazyOrTest();
    137 }