uTL
micro Template library
TmetaTypelist.cpp
Go to the documentation of this file.
1 
20 #include <utl/meta/meta.h>
21 #include <gtest/gtest.h>
22 #include <type_traits>
23 
24 namespace TmetaTypelist {
25  using namespace utl;
26  using namespace meta;
27 
28  /*
29  * Types to behave like Fixtures
30  */
31  // Test type_of fixture
32  template<class T> struct Identity {
33  using type = T;
34  };
35  template<class T1, class T2> struct MfunBin {
36  using type = int;
37  };
38  template<int a, int b> struct MfunBin_i {
39  using type = int;
40  };
41  template<class T1> struct MfunUn1 {
42  using type = int;
43  };
44  template<class T1> struct MfunUn2 {
45  using type = int;
46  };
47 
48  template <typename T> struct Pred_isInt {
49  using type = std::is_integral<T>;
50  };
51 
52  template <typename T> struct Pred_isVoid {
53  using type = std::is_void<T>;
54  };
55 
56 
57  /*
58  * Test high order metaFun tools
59  */
60  TEST(TmetaTypelist, Invoke) {
61  using W = wrap <MfunBin>;
62  using Wi = wrap_i<int, MfunBin_i>;
63  using W1 = wrap<MfunUn1>;
64  using W2 = wrap<MfunUn2>;
65  using Q = quote<MfunBin>;
66  using Qi = quote_i<int, MfunBin_i>;
67  using Q1 = quote<MfunUn1>;
68  using Q2 = quote<MfunUn2>;
69 
70  // identity
71  EXPECT_EQ (true, (std::is_same<int, eval<identity<int>>>()));
72  EXPECT_EQ (true, (std::is_same<int, identity_t<int>>()));
73  EXPECT_EQ (true, (std::is_same<void*, identity_t<void*>>()));
74 
75  // invoke, check that invoke un-wraps and un-quotes staff
76  EXPECT_EQ (true, (std::is_same< invoke<wrap<MfunBin>, int, char>, MfunBin<int, char> >()));
77  EXPECT_EQ (true, (std::is_same< invoke<quote<MfunBin>, int, char>, MfunBin<int, char> >()));
80 
81  // Wrap
86 
87  // applicable trait
90 
95 
98 
99  // defer
101  EXPECT_EQ (true, (std::is_same<defer<MfunBin, void>::type, nil_>()));
103  EXPECT_EQ (true, (std::is_same<defer_i<int, MfunBin_i, 7>::type, nil_>()));
104 
105  // quote
110 
111  // compose
112  EXPECT_EQ (true, (std::is_same<invoke<compose_f<MfunUn1>, int>, MfunUn1<int>>()));
113  EXPECT_EQ (true, (std::is_same<invoke<compose_f<MfunUn1, MfunUn2>, int>, MfunUn1<MfunUn2<int>>>()));
114 
115  EXPECT_EQ (true, (std::is_same<invoke<compose<W1>, int>, MfunUn1<int>>()));
116  EXPECT_EQ (true, (std::is_same<invoke<compose<W1, W2>, int>, MfunUn1<MfunUn2<int>>>()));
117  EXPECT_EQ (true, (std::is_same<
119  >()));
120 
121  EXPECT_EQ (true, (std::is_same<invoke<compose<Q1>, int>, MfunUn1<int>>()));
122  EXPECT_EQ (true, (std::is_same<invoke<compose<Q1, Q2>, int>, MfunUn1<MfunUn2<int>>>()));
123  EXPECT_EQ (true, (std::is_same<
125  >()));
126 
127  // bind
128  EXPECT_EQ (true, (std::is_same<invoke<bind_front<Q, int>, long>, MfunBin<int, long>>()));
129  EXPECT_EQ (true, (std::is_same<invoke<bind_back<Q, int>, long>, MfunBin<long, int>>()));
130 
131  // Check the case of ill formed parameter composition. Quote must save us
132  EXPECT_EQ (true, (std::is_same< nil_, invoke<Q, int> >()));
133  EXPECT_EQ (true, (std::is_same< nil_, invoke<Qi, int_<42>> >()));
134  EXPECT_EQ (true, (std::is_same< MfunUn1<MfunUn2<nil_>>, invoke<compose<Q1, Q2, Qi>, int_<42>> >()));
135  }
136 
137  /*
138  * Test typelist
139  */
140  TEST(TmetaTypelist, Basics) {
141  using l1 = typelist<int, int, int>;
143  using l3 = typelist<>;
144 
145  EXPECT_EQ (true, (std::is_same<l1, typelist<int>::times<3>>()));
146  EXPECT_EQ (true, (std::is_same<l2, typelist<int, void*>::times<2>>()));
147  EXPECT_EQ (true, (std::is_same<l3, typelist<>::times<3>>()));
148  EXPECT_EQ (true, (std::is_same<l3, typelist<int>::times<0>>()));
149  EXPECT_EQ (true, (std::is_same<l3, typelist<int, void>::times<0>>()));
150  EXPECT_EQ (true, (std::is_same<typelist<short, double>, pair<short, double>>()));
151 
152  EXPECT_EQ (true, (std::is_same<l1, repeat <int_<3>, int>>()));
153  EXPECT_EQ (true, (std::is_same<l2, repeat_c <2, int, void*>>()));
154 
155 
156  EXPECT_EQ (3, size<l1>());
157  EXPECT_EQ (0, size<l3>());
158  EXPECT_EQ (true, empty<l3>());
159 
160  // pass typelist to an invocable
161  EXPECT_EQ (true, (std::is_same< apply_t<quote<MfunUn1>, typelist<int>>, MfunUn1<int> >()));
163  }
164 
165  TEST(TmetaTypelist, ElementAccess) {
167 
168  EXPECT_EQ (true, (std::is_same<char*, at_c<l, 0>>()));
169  EXPECT_EQ (true, (std::is_same<void*, at_c<l, 2>>()));
170  EXPECT_EQ (true, (std::is_same<short, at_c<l, 5>>()));
171  EXPECT_EQ (true, (std::is_same<nil_, at_c<l, 6>>()));
172 
173  EXPECT_EQ (true, (std::is_same<void, at<l, int_<1>>>()));
174  EXPECT_EQ (true, (std::is_same<long, at<l, int_<3>>>()));
175 
176  EXPECT_EQ (true, (std::is_same<char*, front<l>>()));
177  EXPECT_EQ (true, (std::is_same<short, back<l>>()));
178  }
179 
180  TEST(TmetaTypelist, Concat) {
181  using l1 = typelist<int, long, void>;
182  using l2 = typelist<void*, int*>;
184  using l4 = typelist<>;
186 
187  EXPECT_EQ(true, (std::is_same<l4, cat<l4, l4>>()));
188  EXPECT_EQ(true, (std::is_same<conc, cat<l1, l2, l3, l4>>()));
189  EXPECT_EQ(true, (std::is_same<conc, cat<l1, l4, l2, l3>>()));
190  EXPECT_EQ(true, (std::is_same<conc, cat<l4, l1, l2, l3>>()));
191  }
192 
193  template<class T1, class T2> struct F {}; // binary invocable
195  struct X1 {};
196  struct X2 {};
197  struct X3 {};
198  struct X4 {};
199  using Q = quote<F>;
200 
201  EXPECT_EQ(true, (std::is_same<fold<typelist<>, void, Q>, void>()));
202  EXPECT_EQ(true, (std::is_same<fold<typelist<X1>, void, Q>, F<void, X1>>()));
203  EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2>, void, Q>, F<F<void, X1>, X2>>()));
204  EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2, X3>, void, Q>, F<F<F<void, X1>, X2>, X3>>()));
205  EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2, X3, X4>, void, Q>, F<F<F<F<void, X1>, X2>, X3>, X4>>()));
206 
207  EXPECT_EQ(true, (std::is_same<rev_fold<typelist<>, void, Q>, void>()));
208  EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1>, void, Q>, F<X1, void>>()));
209  EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2>, void, Q>, F<X1, F<X2, void>>>()));
210  EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2, X3>, void, Q>, F<X1, F<X2, F<X3, void>>>>()));
211  EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2, X3, X4>, void, Q>, F<X1, F<X2, F<X3, F<X4, void>>>>>()));
212  }
213 
214  TEST(TmetaTypelist, PushPopReverse) {
215  using list = typelist <int, long, void>;
216  using l_char = typelist <int, long, void, char>;
218  using char_l = typelist <char, int, long, void>;
220  using rev = typelist<void, long, int>;
221 
222  EXPECT_EQ (true, (std::is_same< char_l, push_front<list, char> >()));
223  EXPECT_EQ (true, (std::is_same< cc_l, push_front<list, char, char> >()));
224  EXPECT_EQ (true, (std::is_same< list, pop_front <char_l> >()));
225  EXPECT_EQ (true, (std::is_same< l_char, push_back <list, char> >()));
226  EXPECT_EQ (true, (std::is_same< l_cc, push_back <list, char, char> >()));
227  EXPECT_EQ (true, (std::is_same< list, pop_back <l_char> >()));
228 
229  EXPECT_EQ (true, (std::is_same< rev, reverse <list> >()));
230  }
231 
232  TEST(TmetaTypelist, Transform) {
233  using QBin = quote<MfunBin>; // both metafuctions return int
234  using QUn = quote<MfunUn1>;
235 
236  using l1 = typelist<char, int, float>;
237  using l2 = typelist<void, void, void>;
238  using r = typelist<int, int, int>;
241 
242  EXPECT_EQ (true, (std::is_same<r, transform<l1, QUn>>()));
243  EXPECT_EQ (true, (std::is_same<r, transform<l1, l2, QBin>>()));
244 
245  EXPECT_EQ (true, (std::is_same<r_ulazy, transform_lazy<l1, QUn>>()));
246  EXPECT_EQ (true, (std::is_same<r_blazy, transform_lazy<l1, l2, QBin>>()));
247  }
248 
249 
252  using l2 = typelist <char, long, float>;
253  using l3 = typelist <long, float>;
254  using empty = typelist<>;
255 
256  EXPECT_EQ(true, (std::is_same<index_<1>, find_if<l1, same_as<char>>>()));
257  EXPECT_EQ(true, (std::is_same<Npos, find_if<empty, same_as<char>>>()));
258  EXPECT_EQ(true, (std::is_same<Npos, find_if<l1, same_as<double>>>()));
259 
260  EXPECT_EQ(true, (std::is_same<index_<2>, find<l1, long>>()));
261 
262  EXPECT_EQ(true, (std::is_same<l2, seek_if<l1, same_as<char>>>()));
263  EXPECT_EQ(true, (std::is_same<empty, seek_if<empty, same_as<char>>>()));
264  EXPECT_EQ(true, (std::is_same<empty, seek_if<l1, same_as<double>>>()));
265 
266  EXPECT_EQ(true, (std::is_same<l3, seek<l1, long>>()));
267  }
268 
269  TEST(TmetaTypelist, Count) {
271  using empty = typelist<>;
272 
273  EXPECT_EQ (true, (std::is_same<size_<3>, count_if<list, same_as<int>>>()));
274  EXPECT_EQ (true, (std::is_same<size_<2>, count_if<list, same_as<char>>>()));
275  EXPECT_EQ (true, (std::is_same<size_<0>, count_if<list, same_as<double>>>()));
276  EXPECT_EQ (true, (std::is_same<size_<0>, count_if<empty, int>>()));
277 
278  EXPECT_EQ (true, (std::is_same<size_<1>, count<list, void*>>()));
279  }
280 
281  TEST(TmetaTypelist, Filter) {
282  using Q1 = quote<Pred_isInt>;
283  using Q2 = quote<Pred_isVoid>;
285  using filtered = typelist<int, char, short>;
286 
287  EXPECT_EQ (true, (std::is_same<filtered, filter<list, Q1>>()));
288  EXPECT_EQ (true, (std::is_same<typelist<>, filter<typelist<>, Q1>>()));
289  EXPECT_EQ (true, (std::is_same<typelist<>, filter<list, Q2>>()));
290  EXPECT_EQ (true, (std::is_same<typelist<>, filter<typelist<>, Q1>>()));
291  }
292 
293  TEST(TmetaTypelist, Replace) {
294  using Q = quote<Pred_isInt>;
298 
299  EXPECT_EQ (true, (std::is_same<res, replace_if<list, Q, void>>()));
300  EXPECT_EQ (true, (std::is_same<typelist<>, replace_if<typelist<>, Q, void>>()));
301  EXPECT_EQ (true, (std::is_same<res, replace_if<res, Q, void>>()));
302  EXPECT_EQ (true, (std::is_same<typelist<>, replace_if<typelist<>, Q, void>>()));
303 
304  EXPECT_EQ (true, (std::is_same<repl, replace<list, char, void>>()));
305  EXPECT_EQ (true, (std::is_same<typelist<>, replace<typelist<>, char, void>>()));
306  }
307 
308  TEST (TmetaTypelist, AllAnyNone) {
311  using l3 = typelist<>;
312 
313  EXPECT_EQ (true, (std::is_same<false_, all_of<l1, quote<Pred_isInt>>>()));
314  EXPECT_EQ (true, (std::is_same<true_, all_of<l2, quote<Pred_isInt>>>()));
315  EXPECT_EQ (true, (std::is_same<false_, all_of<l3, quote<Pred_isVoid>>>()));
316 
317  EXPECT_EQ (true, (std::is_same<true_, any_of<l1, quote<Pred_isInt>>>()));
318  EXPECT_EQ (true, (std::is_same<false_, any_of<l2, quote<Pred_isVoid>>>()));
319  EXPECT_EQ (true, (std::is_same<false_, any_of<l3, quote<Pred_isVoid>>>()));
320 
321  EXPECT_EQ (true, (std::is_same<true_, none_of<l1, quote<Pred_isVoid>>>()));
322  EXPECT_EQ (true, (std::is_same<false_, none_of<l1, quote<Pred_isInt>>>()));
323  EXPECT_EQ (true, (std::is_same<true_, none_of<l3, quote<Pred_isInt>>>()));
324  }
325 
326 }
if_< detail::is_applicable_< F, Ts... >, detail::defer_< F, Ts... >, nil_ > defer
defer alias template for F<Ts...>
Definition: invoke.h:213
Include all meta library.
empty< filter< List, Pred > > none_of
Definition: typelist.h:875
eval< detail::is_applicable_q_< Q, T... > > is_applicable_qt
check if we can invoke Q with parameters T
Definition: invoke.h:168
eval< count_if_impl::count_if_< List, Pred, 0 > > count_if
Definition: typelist.h:755
std::is_integral< T > type
eval< filter_impl::filter_< List, Pred, typelist<> > > filter
Definition: typelist.h:800
eval< at_impl::at_< List, N > > at_c
Definition: typelist.h:245
if_< detail::is_applicable_i_< T, F, Is... >, detail::defer_i_< T, F, Is... >, nil_ > defer_i
defer_i alias template for F<T, Is...>
Definition: invoke.h:221
bool_< true > true_
The type used as a compile-time boolean with true value.
Definition: integral.h:68
eval< replace_if_impl::replace_if_< List, Pred, T, typelist<> > > replace_if
Definition: typelist.h:841
size_< List::size()> size
Definition: typelist.h:129
eval< apply< bind_back< quote< typelist >, Ts... >, List > > push_back
Definition: typelist.h:461
eval< back_impl::back_< List > > back
Definition: typelist.h:296
at_c< List, N::type::value > at
Definition: typelist.h:253
eval< reverse_impl::reverse_< List > > reverse
Definition: typelist.h:479
repeat_c< N::type::value, Ts... > repeat
Definition: typelist.h:161
integral_< size_t, v > size_
size_ type: integral constant wrapper for size_t a.k.a std::size_t
Definition: integral.h:110
eval< replace_if< List, same_as< T >, U > > replace
Definition: typelist.h:848
find_if< List, same_as< T > > find
Definition: typelist.h:663
count_if< List, same_as< T > > count
Definition: typelist.h:761
size_< index_t(-1)> Npos
The last position we can express for indexing.
Definition: integral.h:124
eval< cat_impl::cat_< Lists... > > cat
Definition: typelist.h:338
integral_< int, v > int_
int_ type: integral constant wrapper for int
Definition: integral.h:98
bool_< false > false_
The type used as a compile-time boolean with false value.
Definition: integral.h:69
Wrap a template F taking literal constants of type T into an Invokable.
Definition: invoke.h:243
eval< seek_if_impl::seek_if_< List, Pred, 0 > > seek_if
Definition: typelist.h:705
eval< rev_fold_impl::rev_fold_< List, V, Fn > > rev_fold
Definition: typelist.h:438
eval< fold_impl::fold_< List, V, Fn > > fold
Definition: typelist.h:383
typename Tp::type eval
Type alias for Tp::type. Used to evaluate/extract return type of metafunctions.
Definition: integral.h:49
not_< empty< filter< List, Pred > > > any_of
Definition: typelist.h:868
STL&#39;s core language concepts.
Definition: _1wire.h:30
if_< empty< List >, false_, empty< filter< List, compose< quote< not_ >, Pred > > > > all_of
Definition: typelist.h:861
eval< pop_back_impl::pop_back_< List > > pop_back
Definition: typelist.h:526
eval< apply< bind_front< quote< typelist >, Ts... >, List > > push_front
Definition: typelist.h:450
eval< pop_front_impl::pop_front_< List > > pop_front
Definition: typelist.h:502
integral_< index_t, v > index_
index_ type: integral constant wrapper for index_t a.k.a std::size_t
Definition: integral.h:106
eval< front_impl::front_< List > > front
Definition: typelist.h:274
eval< detail::is_applicable_< F, T... > > is_applicable_t
check if we can instantiate F with parameters T
Definition: invoke.h:163
eval< find_if_impl::find_if_< List, Pred, 0 > > find_if
Definition: typelist.h:657
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:16643
typename typelist< Ts... >::template times< N > repeat_c
Definition: typelist.h:155
eval< identity< _Tp > > identity_t
identity type alias
Definition: invoke.h:68
eval< transform_impl::transform_< typelist< Args... > > > transform
Definition: typelist.h:568
eval< detail::is_applicable_i_< T, F, Is... > > is_applicable_it
check if we can instantiate F with parameters Is of type T
Definition: invoke.h:174
eval< apply< Fn, Seq > > apply_t
Definition: typelist.h:200
typename Fn::template apply< Args... > invoke
Definition: invoke.h:81
Wrap a template F taking literal constants of type T into an Invokable.
Definition: invoke.h:107
TEST(TmetaTypelist, Invoke)
seek_if< List, same_as< T > > seek
Definition: typelist.h:711
bool_< List::empty()> empty
Definition: typelist.h:140
eval< transform_lazy_impl::transform_lazy_< typelist< Args... > > > transform_lazy
Definition: typelist.h:614