MPL11
All Classes Namespaces Files Typedefs Macros Groups Pages
foldable.hpp
Go to the documentation of this file.
1 
12 #ifndef BOOST_MPL11_DETAIL_TEST_FOLDABLE_HPP
13 #define BOOST_MPL11_DETAIL_TEST_FOLDABLE_HPP
14 
15 #include <boost/mpl11/foldable.hpp>
16 
17 #include <boost/mpl11/bool.hpp>
18 #include <boost/mpl11/core.hpp>
24 #include <boost/mpl11/integer.hpp>
25 
26 
27 #define static_assert_(...) static_assert(__VA_ARGS__, # __VA_ARGS__)
28 
29 namespace boost { namespace mpl11 { namespace detail {
30 namespace foldable_detail {
31 template <typename ...x>
32 struct f { using type = f<typename x::type...>; };
33 struct x0 { using type = x0; };
34 struct x1 { using type = x1; };
35 struct x2 { using type = x2; };
36 struct x3 { using type = x3; };
37 struct x4 { using type = x4; };
38 struct x5 { using type = x5; };
39 
40 struct t { using type = t; };
41 struct x { using type = x; };
42 struct y { using type = y; };
43 struct z { using type = z; };
44 
45 using u = undefined;
46 
47 
48 template <template <typename ...> class structure>
49 struct test_foldr1 {
50  template <typename ...xs>
51  using _foldr1 = foldr1<lift<f>, structure<xs...>>;
52 
53  struct go
54  : expect<_foldr1<x1>>::template to_eq<x1>
55  , expect<_foldr1<x1, x2>>::template to_eq<f<x1, x2>>
56  , expect<_foldr1<x1, x2, x3>>::template to_eq<f<x1, f<x2, x3>>>
57  , expect<_foldr1<x1, x2, x3, x4>>::template
58  to_eq<f<x1, f<x2, f<x3, x4>>>>
59  , expect<_foldr1<x1, x2, x3, x4, x5>>::template
60  to_eq<f<x1, f<x2, f<x3, f<x4, x5>>>>>
61  { };
62 
63  static_assert_(sizeof(go));
64 };
65 
66 template <template <typename ...> class structure>
67 struct test_foldl1 {
68  template <typename ...xs>
69  using _foldl1 = foldl1<lift<f>, structure<xs...>>;
70 
71  struct go
72  : expect<_foldl1<x1>>::template to_eq<x1>
73  , expect<_foldl1<x1, x2>>::template to_eq<f<x1, x2>>
74  , expect<_foldl1<x1, x2, x3>>::template to_eq<f<f<x1, x2>, x3>>
75  , expect<_foldl1<x1, x2, x3, x4>>::template
76  to_eq<f<f<f<x1, x2>, x3>, x4>>
77  , expect<_foldl1<x1, x2, x3, x4, x5>>::template
78  to_eq<f<f<f<f<x1, x2>, x3>, x4>, x5>>
79  { };
80 
81  static_assert_(sizeof(go));
82 };
83 
84 template <template <typename ...> class structure>
85 struct test_any {
86  template <typename predicate, typename ...xs>
87  using _any = any<predicate, structure<xs...>>;
88 
89  static_assert_(!_any<u>::value);
90 
91  static_assert_(!_any<always<false_>, u>::value);
92  static_assert_(!_any<always<false_>, u, u>::value);
93 
94  static_assert_( _any<always<true_>, u>::value);
95  static_assert_( _any<always<true_>, u, u>::value);
96 
97  using is_t = rsect_<equal, t>;
98  static_assert_( _any<is_t, t>::value);
99  static_assert_(!_any<is_t, x>::value);
100 
101  static_assert_( _any<is_t, t, u>::value);
102  static_assert_( _any<is_t, x, t>::value);
103  static_assert_(!_any<is_t, x, y>::value);
104 
105  static_assert_( _any<is_t, t, u, u>::value);
106  static_assert_( _any<is_t, x, t, u>::value);
107  static_assert_( _any<is_t, x, y, t>::value);
108  static_assert_(!_any<is_t, x, y, z>::value);
109 };
110 
111 template <template <typename ...> class structure>
112 struct test_none {
113  template <typename predicate, typename ...xs>
114  using _none = none<predicate, structure<xs...>>;
115 
116  static_assert_(_none<u>::value);
117 
118  static_assert_(_none<always<false_>, u>::value);
119  static_assert_(_none<always<false_>, u, u>::value);
120 
121  static_assert_(!_none<always<true_>, u>::value);
122  static_assert_(!_none<always<true_>, u, u>::value);
123 
124  using is_t = rsect_<equal, t>;
125  static_assert_(!_none<is_t, t>::value);
126  static_assert_( _none<is_t, x>::value);
127 
128  static_assert_(!_none<is_t, t, u>::value);
129  static_assert_(!_none<is_t, x, t>::value);
130  static_assert_( _none<is_t, x, y>::value);
131 
132  static_assert_(!_none<is_t, t, u, u>::value);
133  static_assert_(!_none<is_t, x, t, u>::value);
134  static_assert_(!_none<is_t, x, y, t>::value);
135  static_assert_( _none<is_t, x, y, z>::value);
136 };
137 
138 template <template <typename ...> class structure>
139 struct test_all {
140  template <typename predicate, typename ...xs>
141  using _all = all<predicate, structure<xs...>>;
142 
143  static_assert_(_all<u>::value);
144 
145  static_assert_(!_all<always<false_>, u>::value);
146  static_assert_(!_all<always<false_>, u, u>::value);
147 
148  static_assert_(_all<always<true_>, u>::value);
149  static_assert_(_all<always<true_>, u, u>::value);
150 
151  using is_t = rsect_<equal, t>;
152  static_assert_( _all<is_t, t>::value);
153  static_assert_(!_all<is_t, x>::value);
154 
155  static_assert_( _all<is_t, t, t>::value);
156  static_assert_(!_all<is_t, t, y>::value);
157  static_assert_(!_all<is_t, x, u>::value);
158 
159  static_assert_( _all<is_t, t, t, t>::value);
160  static_assert_(!_all<is_t, t, t, z>::value);
161  static_assert_(!_all<is_t, t, y, u>::value);
162  static_assert_(!_all<is_t, x, u, u>::value);
163 };
164 
165 template <template <typename ...> class structure>
166 struct test_all_of {
167  template <typename ...xs>
168  using _all_of = all_of<structure<xs...>>;
169 
170  static_assert_(_all_of<>::value);
171 
172  static_assert_( _all_of<true_>::value);
173  static_assert_(!_all_of<false_>::value);
174 
175  static_assert_( _all_of<true_, true_>::value);
176  static_assert_(!_all_of<true_, false_>::value);
177  static_assert_(!_all_of<false_, u>::value);
178  static_assert_(!_all_of<false_, u>::value);
179 
180  static_assert_( _all_of<true_, true_, true_>::value);
181  static_assert_(!_all_of<true_, true_, false_>::value);
182  static_assert_(!_all_of<true_, false_, u>::value);
183  static_assert_(!_all_of<false_, u, u>::value);
184 };
185 
186 template <template <typename ...> class structure>
187 struct test_any_of {
188  template <typename ...xs>
189  using _any_of = any_of<structure<xs...>>;
190 
191  static_assert_(!_any_of<>::value);
192 
193  static_assert_( _any_of<true_>::value);
194  static_assert_(!_any_of<false_>::value);
195 
196  static_assert_( _any_of<true_, u>::value);
197  static_assert_( _any_of<false_, true_>::value);
198  static_assert_(!_any_of<false_, false_>::value);
199 
200  static_assert_( _any_of<true_, u, u>::value);
201  static_assert_( _any_of<false_, true_, u>::value);
202  static_assert_( _any_of<false_, false_, true_>::value);
203  static_assert_(!_any_of<false_, false_, false_>::value);
204 };
205 
206 template <template <typename ...> class structure>
207 struct test_none_of {
208  template <typename ...xs>
209  using _none_of = none_of<structure<xs...>>;
210 
211  static_assert_( _none_of<>::value);
212 
213  static_assert_(!_none_of<true_>::value);
214  static_assert_(_none_of<false_>::value);
215 
216  static_assert_(!_none_of<true_, u>::value);
217  static_assert_(!_none_of<false_, true_>::value);
218  static_assert_( _none_of<false_, false_>::value);
219 
220  static_assert_(!_none_of<true_, u, u>::value);
221  static_assert_(!_none_of<false_, true_, u>::value);
222  static_assert_(!_none_of<false_, false_, true_>::value);
223  static_assert_( _none_of<false_, false_, false_>::value);
224 };
225 
226 template <template <typename ...> class structure>
227 struct test_sum {
228  template <int ...xs>
229  using _sum = sum<structure<int_<xs>...>>;
230 
231  static_assert_(_sum<>::value == 0);
232 
233  static_assert_(_sum<0>::value == 0);
234  static_assert_(_sum<1>::value == 1);
235  static_assert_(_sum<2>::value == 2);
236 
237  static_assert_(_sum<0, 1>::value == 1);
238  static_assert_(_sum<1, 2>::value == 3);
239 
240  static_assert_(_sum<1, 2, 3, 4>::value == 1 + 2 + 3 + 4);
241  static_assert_(_sum<1, 2, 3, 4, 5, 0>::value == 1 + 2 + 3 + 4 + 5 + 0);
242 };
243 
244 template <template <typename ...> class structure>
245 struct test_product {
246  template <int ...xs>
247  using _prod = product<structure<int_<xs>...>>;
248 
249  static_assert_(_prod<>::value == 1);
250 
251  static_assert_(_prod<0>::value == 0);
252  static_assert_(_prod<1>::value == 1);
253  static_assert_(_prod<2>::value == 2);
254 
255  static_assert_(_prod<0, 1>::value == 0);
256  static_assert_(_prod<1, 2>::value == 2);
257 
258  static_assert_(_prod<2, 3, 4>::value == 2 * 3 * 4);
259  static_assert_(_prod<1, 2, 3, 4, 5, 0>::value == 0);
260 };
261 
262 template <template <typename ...> class structure>
263 struct test_maximum {
264  template <int ...xs>
265  using _max = typename maximum<structure<int_<xs>...>>::type;
266 
267  static_assert_(_max<0>::value == 0);
268  static_assert_(_max<1>::value == 1);
269  static_assert_(_max<1, 2, 3>::value == 3);
270  static_assert_(_max<1, 3, 0>::value == 3);
271  static_assert_(_max<1, 3, 0, 50>::value == 50);
272  static_assert_(_max<50, 3, 0, 1>::value == 50);
273  static_assert_(_max<50, 3, 0, 50>::value == 50);
274 };
275 
276 template <template <typename ...> class structure>
277 struct test_maximum_by {
278  template <int ...xs>
279  using _max = typename maximum_by<lift<less>, structure<int_<xs>...>>::type;
280 
281  static_assert_(_max<0>::value == 0);
282  static_assert_(_max<1>::value == 1);
283  static_assert_(_max<1, 2, 3>::value == 3);
284  static_assert_(_max<1, 3, 0>::value == 3);
285  static_assert_(_max<1, 3, 0, 50>::value == 50);
286  static_assert_(_max<50, 3, 0, 1>::value == 50);
287  static_assert_(_max<50, 3, 0, 50>::value == 50);
288 };
289 
290 template <template <typename ...> class structure>
291 struct test_minimum {
292  template <int ...xs>
293  using _min = typename minimum<structure<int_<xs>...>>::type;
294 
295  static_assert_(_min<0>::value == 0);
296  static_assert_(_min<1>::value == 1);
297  static_assert_(_min<1, 2, 3>::value == 1);
298  static_assert_(_min<1, 3, 0>::value == 0);
299  static_assert_(_min<1, 3, 0, 50>::value == 0);
300  static_assert_(_min<0, 3, 4, 0>::value == 0);
301 };
302 
303 template <template <typename ...> class structure>
304 struct test_minimum_by {
305  template <int ...xs>
306  using _min = typename minimum_by<lift<less>, structure<int_<xs>...>>::type;
307 
308  static_assert_(_min<0>::value == 0);
309  static_assert_(_min<1>::value == 1);
310  static_assert_(_min<1, 2, 3>::value == 1);
311  static_assert_(_min<1, 3, 0>::value == 0);
312  static_assert_(_min<1, 3, 0, 50>::value == 0);
313  static_assert_(_min<0, 3, 4, 0>::value == 0);
314 };
315 
316 template <template <typename ...> class structure>
317 struct test_unpack {
318  template <typename ...xs>
319  using _unpack = detail::std_is_same<
320  typename unpack<lift<f>, structure<xs...>>::type,
321  typename f<xs...>::type
322  >;
323 
324  static_assert_(_unpack<>::value);
325  static_assert_(_unpack<x0>::value);
326  static_assert_(_unpack<x0, x1>::value);
327  static_assert_(_unpack<x0, x1, x2>::value);
328  static_assert_(_unpack<x0, x1, x2, x3>::value);
329  static_assert_(_unpack<x0, x1, x2, x3, x4>::value);
330 };
331 
332 template <template <typename ...> class structure>
333 struct test_datatype {
334  template <typename ...xs>
335  using _datatype = typename expect<
336  typename datatype<typename structure<xs...>::type>::type
337  >::template to_satisfy<lift<mpl11::Foldable>>;
338 
340  sizeof(_datatype<>) +
341  sizeof(_datatype<u>) +
342  sizeof(_datatype<u, u>) +
343  sizeof(_datatype<u, u, u>)
344  );
345 };
346 
347 template <
348  template <typename ...> class fold,
349  template <typename ...> class structure
350 >
351 struct fold_on {
352  // Note: Using a struct instead of an alias here to
353  // avoid a ICE on GCC 4.9.
354  template <typename f, typename z, typename ...xs>
355  struct go : fold<f, z, structure<xs...>> { };
356 };
357 } // end namespace foldable_detail
358 
359 template <template <typename ...> class structure>
360 struct test_Foldable
361  : test_foldl<foldable_detail::fold_on<foldl, structure>::template go>
362  , test_foldr<foldable_detail::fold_on<foldr, structure>::template go>
363  , foldable_detail::test_foldl1<structure>
364  , foldable_detail::test_foldr1<structure>
365 
366  , foldable_detail::test_all<structure>
367  , foldable_detail::test_all_of<structure>
368  , foldable_detail::test_any<structure>
369  , foldable_detail::test_any_of<structure>
370  , foldable_detail::test_none<structure>
371  , foldable_detail::test_none_of<structure>
372 
373  , foldable_detail::test_sum<structure>
374  , foldable_detail::test_product<structure>
375 
376  , foldable_detail::test_maximum<structure>
377  , foldable_detail::test_maximum_by<structure>
378  , foldable_detail::test_minimum<structure>
379  , foldable_detail::test_minimum_by<structure>
380 
381  , foldable_detail::test_unpack<structure>
382  , foldable_detail::test_datatype<structure>
383 { };
384 }}} // end namespace boost::mpl11::detail
385 
386 #endif // !BOOST_MPL11_DETAIL_TEST_FOLDABLE_HPP
Defines the Integer datatype.
Defines unit tests for left fold algorithms.
Defines unit tests for right fold algorithms.
Defines boost::mpl11::detail::std_is_same.
Defines the Core module.
Returns the given boolean expression and statically asserts that its value is true.
Definition: static_assert.hpp:22
Defines utilities to write unit tests.
Forwards to boost/mpl11/integer.hpp.
Defines the methods of the Foldable typeclass.
Defines the Functional module.