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
10
11// <type_traits>
12
13// __lazy_enable_if, __lazy_not, _And and _Or
14
15// Test the libc++ lazy meta-programming helpers in <type_traits>
16
17#include <type_traits>
18
19#include "test_macros.h"
20
21template <class Type>
22struct Identity : Type {
23
24};
25
26typedef std::true_type TrueT;
27typedef std::false_type FalseT;
28
29typedef Identity<TrueT> LazyTrueT;
30typedef Identity<FalseT> LazyFalseT;
31
32// A type that cannot be instantiated
33template <class T>
34struct CannotInst {
35 static_assert(std::is_same<T, T>::value == false, "");
36};
37
38
39template <int Value>
40struct NextInt {
41 typedef NextInt<Value + 1> type;
42 static const int value = Value;
43};
44
45template <int Value>
46const int NextInt<Value>::value;
47
48
49template <class Type>
50struct 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.
61template <class Type>
62struct HasType : HasTypeImp<Type>::type {};
63
64
65void LazyNotTest() {
66 {
67 typedef std::_Not<LazyTrueT> NotT;
68 static_assert(std::is_same<typename NotT::type, FalseT>::value, "");
69 static_assert(NotT::value == false, "");
70 }
71 {
72 typedef std::_Not<LazyFalseT> NotT;
73 static_assert(std::is_same<typename NotT::type, TrueT>::value, "");
74 static_assert(NotT::value == true, "");
75 }
76 {
77 // Check that CannotInst<int> is not instantiated.
78 typedef std::_Not<CannotInst<int> > NotT;
79
80 static_assert(std::is_same<NotT, NotT>::value, "");
81
82 }
83}
84
85void LazyAndTest() {
86 { // Test that it acts as the identity function for a single value
87 static_assert(std::_And<LazyFalseT>::value == false, "");
88 static_assert(std::_And<LazyTrueT>::value == true, "");
89 }
90 {
91 static_assert(std::_And<LazyTrueT, LazyTrueT>::value == true, "");
92 static_assert(std::_And<LazyTrueT, LazyFalseT>::value == false, "");
93 static_assert(std::_And<LazyFalseT, LazyTrueT>::value == false, "");
94 static_assert(std::_And<LazyFalseT, LazyFalseT>::value == false, "");
95 }
96 { // Test short circuiting - CannotInst<T> should never be instantiated.
97 static_assert(std::_And<LazyFalseT, CannotInst<int>>::value == false, "");
98 static_assert(std::_And<LazyTrueT, LazyFalseT, CannotInst<int>>::value == false, "");
99 }
100}
101
102
103void LazyOrTest() {
104 { // Test that it acts as the identity function for a single value
105 static_assert(std::_Or<LazyFalseT>::value == false, "");
106 static_assert(std::_Or<LazyTrueT>::value == true, "");
107 }
108 {
109 static_assert(std::_Or<LazyTrueT, LazyTrueT>::value == true, "");
110 static_assert(std::_Or<LazyTrueT, LazyFalseT>::value == true, "");
111 static_assert(std::_Or<LazyFalseT, LazyTrueT>::value == true, "");
112 static_assert(std::_Or<LazyFalseT, LazyFalseT>::value == false, "");
113 }
114 { // Test short circuiting - CannotInst<T> should never be instantiated.
115 static_assert(std::_Or<LazyTrueT, CannotInst<int>>::value == true, "");
116 static_assert(std::_Or<LazyFalseT, LazyTrueT, CannotInst<int>>::value == true, "");
117 }
118}
119
120
121int main(int, char**) {
122
123 LazyNotTest();
124 LazyAndTest();
125 LazyOrTest();
126
127 return 0;
128}
129

source code of libcxx/test/libcxx/type_traits/lazy_metafunctions.pass.cpp