2 * Copyright 2017-present Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <folly/detail/TypeList.h>
18 #include <folly/portability/GTest.h>
20 using namespace folly;
21 using namespace detail;
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...>>>
29 template <class T, class... Ts>
30 using IsApplicable = IsApplicable_<T, TypeList<Ts...>>;
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, "");
40 using AddPointer = T*;
42 TEST(TypeList, Defer) {
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, "");
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, "");
60 template <class Car, class Cdr = Nil>
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, "");
69 using T2 = TypeFold<TypeList<int, short, void, int*, short*, void*>, Nil, Fn>;
72 Cons<short, Cons<void, Cons<int*, Cons<short*, Cons<void*, Nil>>>>>>;
73 static_assert(std::is_same<T2, E2>::value, "");
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, "");
79 using T4 = TypeReverseFold<
80 TypeList<int, short, void, int*, short*, void*>,
85 Cons<short*, Cons<int*, Cons<void, Cons<short, Cons<int, Nil>>>>>>;
86 static_assert(std::is_same<T4, E4>::value, "");
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, "");
93 using T2 = TypeReverseUnique<TypeList<int, int, int, short, int, short>>;
94 static_assert(std::is_same<T2, TypeList<short, int>>::value, "");
97 TEST(TypeList, PushFront) {
98 using T1 = TypePushFront<TypeList<>, int, short>;
99 static_assert(std::is_same<T1, TypeList<int, short>>::value, "");
101 using T2 = TypePushFront<T1, float, double, struct XXX>;
103 std::is_same<T2, TypeList<float, double, struct XXX, int, short>>::value,
107 TEST(TypeList, PushBack) {
108 using T1 = TypePushBack<TypeList<>, int, short>;
109 static_assert(std::is_same<T1, TypeList<int, short>>::value, "");
111 using T2 = TypePushBack<T1, float, double, struct XXX>;
113 std::is_same<T2, TypeList<int, short, float, double, struct XXX>>::value,
117 TEST(TypeList, Join) {
119 TypeList<TypeList<int>, TypeList<short, float>, TypeList<void*>>>;
121 std::is_same<T1, TypeList<int, short, float, void*>>::value, "");