Baton::ready, a const variant of try_wait
[folly.git] / folly / test / TypeListTest.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/detail/TypeList.h>
18 #include <folly/portability/GTest.h>
19
20 using namespace folly;
21 using namespace detail;
22
23 namespace {
24 template <class T, class Ts, class = void>
25 struct IsApplicable_ : std::false_type {};
26 template <class T, class... Ts>
27 struct IsApplicable_<T, TypeList<Ts...>, void_t<MetaApply<T, Ts...>>>
28     : std::true_type {};
29 template <class T, class... Ts>
30 using IsApplicable = IsApplicable_<T, TypeList<Ts...>>;
31 } // namespace
32
33 TEST(TypeList, Basic) {
34   static_assert(TypeList<>::size() == 0, "");
35   static_assert(TypeList<int>::size() == 1, "");
36   static_assert(TypeList<int, short, float>::size() == 3, "");
37 }
38
39 template <class T>
40 using AddPointer = T*;
41
42 TEST(TypeList, Defer) {
43   static_assert(
44       std::is_same<MetaApply<MetaDefer<AddPointer, int>>, int*>::value, "");
45   static_assert(!IsApplicable<MetaDefer<AddPointer, int, short>>::value, "");
46   static_assert(!IsApplicable<MetaDefer<AddPointer, int&>>::value, "");
47 }
48
49 TEST(TypeList, Transform) {
50   using Fn = MetaQuote<AddPointer>;
51   using T1 = TypeTransform<TypeList<>, Fn>;
52   static_assert(std::is_same<T1, TypeList<>>::value, "");
53   using T2 = TypeTransform<TypeList<int>, Fn>;
54   static_assert(std::is_same<T2, TypeList<int*>>::value, "");
55   using T3 = TypeTransform<TypeList<int, short, void>, Fn>;
56   static_assert(std::is_same<T3, TypeList<int*, short*, void*>>::value, "");
57 }
58
59 using Nil = Empty;
60 template <class Car, class Cdr = Nil>
61 struct Cons {};
62
63 TEST(TypeList, Fold) {
64   using Fn = MetaQuote<Cons>;
65   using T1 = TypeFold<TypeList<int, short, void>, Nil, Fn>;
66   using E1 = Cons<int, Cons<short, Cons<void, Nil>>>;
67   static_assert(std::is_same<T1, E1>::value, "");
68
69   using T2 = TypeFold<TypeList<int, short, void, int*, short*, void*>, Nil, Fn>;
70   using E2 = Cons<
71       int,
72       Cons<short, Cons<void, Cons<int*, Cons<short*, Cons<void*, Nil>>>>>>;
73   static_assert(std::is_same<T2, E2>::value, "");
74
75   using T3 = TypeReverseFold<TypeList<int, short, void>, Nil, MetaFlip<Fn>>;
76   using E3 = Cons<void, Cons<short, Cons<int, Nil>>>;
77   static_assert(std::is_same<T3, E3>::value, "");
78
79   using T4 = TypeReverseFold<
80       TypeList<int, short, void, int*, short*, void*>,
81       Nil,
82       MetaFlip<Fn>>;
83   using E4 = Cons<
84       void*,
85       Cons<short*, Cons<int*, Cons<void, Cons<short, Cons<int, Nil>>>>>>;
86   static_assert(std::is_same<T4, E4>::value, "");
87 }
88
89 TEST(TypeList, Unique) {
90   using T1 = TypeUnique<TypeList<int, int, int, short, int, short>>;
91   static_assert(std::is_same<T1, TypeList<int, short>>::value, "");
92
93   using T2 = TypeReverseUnique<TypeList<int, int, int, short, int, short>>;
94   static_assert(std::is_same<T2, TypeList<short, int>>::value, "");
95 }
96
97 TEST(TypeList, PushFront) {
98   using T1 = TypePushFront<TypeList<>, int, short>;
99   static_assert(std::is_same<T1, TypeList<int, short>>::value, "");
100
101   using T2 = TypePushFront<T1, float, double, struct XXX>;
102   static_assert(
103       std::is_same<T2, TypeList<float, double, struct XXX, int, short>>::value,
104       "");
105 }
106
107 TEST(TypeList, PushBack) {
108   using T1 = TypePushBack<TypeList<>, int, short>;
109   static_assert(std::is_same<T1, TypeList<int, short>>::value, "");
110
111   using T2 = TypePushBack<T1, float, double, struct XXX>;
112   static_assert(
113       std::is_same<T2, TypeList<int, short, float, double, struct XXX>>::value,
114       "");
115 }
116
117 TEST(TypeList, Join) {
118   using T1 = TypeJoin<
119       TypeList<TypeList<int>, TypeList<short, float>, TypeList<void*>>>;
120   static_assert(
121       std::is_same<T1, TypeList<int, short, float, void*>>::value, "");
122 }