1 /*
2  *  Copyright (c) 2016, Facebook, Inc.
3  *  All rights reserved.
4  *
5  *  This source code is licensed under the BSD-style license found in the
6  *  LICENSE file in the root directory of this source tree. An additional grant
7  *  of patent rights can be found in the PATENTS file in the same directory.
8  */
9 
10 #include <fatal/type/deprecated/type_map.h>
11 
12 #include <fatal/test/driver.h>
13 
14 namespace fatal {
15 
16 namespace {
17 template <typename> struct type1_t {};
18 template <typename> struct type2_t {};
19 template <char Value> using chr_val = std::integral_constant<char, Value>;
20 template <char... Args> using chr_map = build_type_map<chr_val<Args>...>;
21 template <int Value> using int_val = std::integral_constant<int, Value>;
22 template <int... Args> using int_map = build_type_map<int_val<Args>...>;
23 template <int Increment>
24 struct add {
25   template <typename T> using type = int_val<T::value + Increment>;
26 };
27 
28 #define W(value) using w##value = std::integral_constant<int, 100 + value>
29 W(0); W(1); W(2); W(3); W(4); W(5); W(6); W(7); W(8); W(9);
30 #undef W
31 
32 #define X(value) using x##value = std::integral_constant<int, 100 + value>
33 X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9);
34 #undef X
35 
36 #define Y(value) using y##value = std::integral_constant<int, 200 + value>
37 Y(0); Y(1); Y(2); Y(3); Y(4); Y(5); Y(6); Y(7); Y(8); Y(9);
38 #undef Y
39 
40 #define Z(value) using z##value = std::integral_constant<int, 300 + value>
41 Z(0); Z(1); Z(2); Z(3); Z(4); Z(5); Z(6); Z(7); Z(8); Z(9);
42 #undef Z
43 
44 template <typename T>
45 struct sort_transform_impl { typedef typename T::template sort<> type; };
46 template <typename T>
47 using sort_transform = typename sort_transform_impl<T>::type;
48 
49 //////////////
50 // type_map //
51 //////////////
52 
53 typedef type_map<
54   type_pair<int, bool>,
55   type_pair<double, long>,
56   type_pair<short, void>
57 > ibdlsv_map;
58 
59 struct not_found_type {};
60 }
61 
62 ////////////////////
63 // build_type_map //
64 ////////////////////
65 
FATAL_TEST(type_map,build_type_map)66 FATAL_TEST(type_map, build_type_map) {
67   FATAL_EXPECT_SAME<type_map<>, build_type_map<>>();
68 
69   FATAL_EXPECT_SAME<
70     type_map<type_pair<int, bool>>,
71     build_type_map<int, bool>
72   >();
73 
74   FATAL_EXPECT_SAME<
75     ibdlsv_map,
76     build_type_map<int, bool, double, long, short, void>
77   >();
78 }
79 
80 //////////
81 // keys //
82 //////////
83 
FATAL_TEST(type_map,keys)84 FATAL_TEST(type_map, keys) {
85   FATAL_EXPECT_SAME<type_map<>::keys, type_list<>>();
86 
87   FATAL_EXPECT_SAME<
88     type_map<type_pair<int, bool>>::keys,
89     type_list<int>
90   >();
91 
92   FATAL_EXPECT_SAME<
93     ibdlsv_map::keys,
94     type_list<int, double, short>
95   >();
96 }
97 
98 ////////////
99 // mapped //
100 ////////////
101 
FATAL_TEST(type_map,mapped)102 FATAL_TEST(type_map, mapped) {
103   FATAL_EXPECT_SAME<type_map<>::mapped, type_list<>>();
104 
105   FATAL_EXPECT_SAME<
106     type_map<type_pair<int, bool>>::mapped,
107     type_list<bool>
108   >();
109 
110   FATAL_EXPECT_SAME<
111     ibdlsv_map::mapped,
112     type_list<bool, long, void>
113   >();
114 }
115 
116 ///////////////
117 // transform //
118 ///////////////
119 
FATAL_TEST(type_map,transform)120 FATAL_TEST(type_map, transform) {
121   FATAL_EXPECT_SAME<type_map<>, type_map<>::transform<add<10>::type>>();
122 
123   FATAL_EXPECT_SAME<
124     type_map<>,
125     type_map<>::transform<add<10>::type, add<100>::type>
126   >();
127 
128   typedef build_type_map<
129     int_val<0>, int_val<0>,
130     int_val<1>, int_val<11>,
131     int_val<3>, int_val<33>,
132     int_val<5>, int_val<55>,
133     int_val<7>, int_val<77>,
134     int_val<9>, int_val<99>
135   > map;
136 
137   FATAL_EXPECT_SAME<
138     build_type_map<
139       int_val<0>, int_val<10>,
140       int_val<1>, int_val<21>,
141       int_val<3>, int_val<43>,
142       int_val<5>, int_val<65>,
143       int_val<7>, int_val<87>,
144       int_val<9>, int_val<109>
145     >,
146     map::transform<add<10>::type>
147   >();
148 
149   FATAL_EXPECT_SAME<
150     build_type_map<
151       int_val<100>, int_val<10>,
152       int_val<101>, int_val<21>,
153       int_val<103>, int_val<43>,
154       int_val<105>, int_val<65>,
155       int_val<107>, int_val<87>,
156       int_val<109>, int_val<109>
157     >,
158     map::transform<add<10>::type, add<100>::type>
159   >();
160 }
161 
162 //////////////////
163 // transform_at //
164 //////////////////
165 
FATAL_TEST(type_map,transform_at)166 FATAL_TEST(type_map, transform_at) {
167   FATAL_EXPECT_SAME<
168     type_map<>,
169     type_map<>::transform_at<int_val<0>, add<10>::type>
170   >();
171 
172   FATAL_EXPECT_SAME<
173     type_map<>,
174     type_map<>::transform_at<int_val<0>, add<10>::type, add<100>::type>
175   >();
176 
177   typedef build_type_map<
178     int_val<0>, int_val<0>,
179     int_val<1>, int_val<11>,
180     int_val<3>, int_val<33>,
181     int_val<5>, int_val<55>,
182     int_val<7>, int_val<77>,
183     int_val<9>, int_val<99>
184   > map;
185 
186   FATAL_EXPECT_SAME<
187     map,
188     map::transform_at<int_val<1000>, add<10>::type>
189   >();
190 
191   FATAL_EXPECT_SAME<
192     map,
193     map::transform_at<int_val<1000>, add<10>::type, add<100>::type>
194   >();
195 
196   FATAL_EXPECT_SAME<
197     build_type_map<
198       int_val<0>, int_val<10>,
199       int_val<1>, int_val<11>,
200       int_val<3>, int_val<33>,
201       int_val<5>, int_val<55>,
202       int_val<7>, int_val<77>,
203       int_val<9>, int_val<99>
204     >,
205     map::transform_at<int_val<0>, add<10>::type>
206   >();
207 
208   FATAL_EXPECT_SAME<
209     build_type_map<
210       int_val<100>, int_val<10>,
211       int_val<1>, int_val<11>,
212       int_val<3>, int_val<33>,
213       int_val<5>, int_val<55>,
214       int_val<7>, int_val<77>,
215       int_val<9>, int_val<99>
216     >,
217     map::transform_at<int_val<0>, add<10>::type, add<100>::type>
218   >();
219 
220   FATAL_EXPECT_SAME<
221     build_type_map<
222       int_val<0>, int_val<0>,
223       int_val<1>, int_val<11>,
224       int_val<3>, int_val<33>,
225       int_val<5>, int_val<55>,
226       int_val<7>, int_val<77>,
227       int_val<9>, int_val<109>
228     >,
229     map::transform_at<int_val<9>, add<10>::type>
230   >();
231 
232   FATAL_EXPECT_SAME<
233     build_type_map<
234       int_val<0>, int_val<0>,
235       int_val<1>, int_val<11>,
236       int_val<3>, int_val<33>,
237       int_val<105>, int_val<65>,
238       int_val<7>, int_val<77>,
239       int_val<9>, int_val<99>
240     >,
241     map::transform_at<int_val<5>, add<10>::type, add<100>::type>
242   >();
243 }
244 
245 ////////////
246 // invert //
247 ////////////
248 
FATAL_TEST(type_map,invert)249 FATAL_TEST(type_map, invert) {
250   typedef type_map<
251     type_pair<int, bool>,
252     type_pair<float, long>
253   > map;
254 
255   typedef type_map<
256     type_pair<bool, int>,
257     type_pair<long, float>
258   > expected1;
259   FATAL_EXPECT_SAME<expected1, map::invert<>>();
260 
261   typedef type_map<
262     type_pair<type2_t<bool>, type1_t<int>>,
263     type_pair<type2_t<long>, type1_t<float>>
264   > expected2;
265   FATAL_EXPECT_SAME<expected2, map::invert<type1_t, type2_t>>();
266 }
267 
268 //////////
269 // find //
270 //////////
271 
FATAL_TEST(type_map,find)272 FATAL_TEST(type_map, find) {
273   FATAL_EXPECT_SAME<type_map<>::find<int, not_found_type>, not_found_type>();
274   FATAL_EXPECT_SAME<type_map<>::find<int, float>, float>();
275 
276   FATAL_EXPECT_SAME<ibdlsv_map::find<int, not_found_type>, bool>();
277   FATAL_EXPECT_SAME<ibdlsv_map::find<double, not_found_type>, long>();
278   FATAL_EXPECT_SAME<ibdlsv_map::find<short, not_found_type>, void>();
279 
280   FATAL_EXPECT_SAME<ibdlsv_map::find<bool, not_found_type>, not_found_type>();
281   FATAL_EXPECT_SAME<ibdlsv_map::find<bool, float>, float>();
282 }
283 
284 /////////
285 // get //
286 /////////
287 
FATAL_TEST(type_map,get)288 FATAL_TEST(type_map, get) {
289   FATAL_EXPECT_SAME<ibdlsv_map::get<int>, bool>();
290   FATAL_EXPECT_SAME<ibdlsv_map::get<double>, long>();
291   FATAL_EXPECT_SAME<ibdlsv_map::get<short>, void>();
292 }
293 
294 ////////////
295 // search //
296 ////////////
297 
298 template <typename T>
299 struct search_predicate {
300   template <typename U>
301   using apply = std::is_same<T, U>;
302 };
303 
FATAL_TEST(type_map,search)304 FATAL_TEST(type_map, search) {
305   FATAL_EXPECT_SAME<
306     type_map<>::search<search_predicate<int>::apply, not_found_type>,
307     not_found_type
308   >();
309 
310   FATAL_EXPECT_SAME<
311     ibdlsv_map::search<search_predicate<int>::apply, not_found_type>,
312     fatal::type_pair<int, bool>
313   >();
314 
315   FATAL_EXPECT_SAME<
316     ibdlsv_map::search<search_predicate<double>::apply, not_found_type>,
317     fatal::type_pair<double, long>
318   >();
319 
320   FATAL_EXPECT_SAME<
321     ibdlsv_map::search<search_predicate<short>::apply, not_found_type>,
322     fatal::type_pair<short, void>
323   >();
324 
325   FATAL_EXPECT_SAME<
326     ibdlsv_map::search<search_predicate<bool>::apply, not_found_type>,
327     not_found_type
328   >();
329 }
330 
331 //////////////
332 // contains //
333 //////////////
334 
FATAL_TEST(type_map,contains)335 FATAL_TEST(type_map, contains) {
336   FATAL_EXPECT_FALSE((type_map<>::contains<int>::value));
337   FATAL_EXPECT_TRUE((ibdlsv_map::contains<int>::value));
338   FATAL_EXPECT_TRUE((ibdlsv_map::contains<double>::value));
339   FATAL_EXPECT_TRUE((ibdlsv_map::contains<short>::value));
340   FATAL_EXPECT_FALSE((ibdlsv_map::contains<bool>::value));
341 }
342 
343 ////////////////
344 // push_front //
345 ////////////////
346 
FATAL_TEST(type_map,push_front)347 FATAL_TEST(type_map, push_front) {
348   using map = build_type_map<
349     int, bool,
350     float, double
351   >;
352 
353   using expected1 = build_type_map<
354     short, long,
355     int, bool,
356     float, double
357   >;
358   FATAL_EXPECT_SAME<expected1, map::push_front<short, long>>();
359 
360   using expected2 = build_type_map<
361     short, long,
362     void, float,
363     int, bool,
364     float, double
365   >;
366   FATAL_EXPECT_SAME<expected2, map::push_front<short, long, void, float>>();
367 
368   using expected3 = build_type_map<
369     type_pair<short, long>, type_pair<void, unsigned>,
370     int, bool,
371     float, double
372   >;
373   FATAL_EXPECT_SAME<
374     expected3,
375     map::push_front<type_pair<short, long>, type_pair<void, unsigned>>
376   >();
377 }
378 
379 ///////////////
380 // push_back //
381 ///////////////
382 
FATAL_TEST(type_map,push_back)383 FATAL_TEST(type_map, push_back) {
384   using map = build_type_map<
385     int, bool,
386     float, double
387   >;
388 
389   using expected1 = build_type_map<
390     int, bool,
391     float, double,
392     short, long
393   >;
394   FATAL_EXPECT_SAME<expected1, map::push_back<short, long>>();
395 
396   using expected2 = build_type_map<
397     int, bool,
398     float, double,
399     short, long,
400     void, float
401   >;
402   FATAL_EXPECT_SAME<expected2, map::push_back<short, long, void, float>>();
403 
404   using expected3 = build_type_map<
405     int, bool,
406     float, double,
407     type_pair<short, long>, type_pair<void, unsigned>
408   >;
409   FATAL_EXPECT_SAME<
410     expected3,
411     map::push_back<type_pair<short, long>, type_pair<void, unsigned>>
412   >();
413 }
414 
415 ////////////
416 // insert //
417 ////////////
418 
FATAL_TEST(type_map,insert)419 FATAL_TEST(type_map, insert) {
420   FATAL_EXPECT_SAME<
421     build_type_map<int, bool>,
422     type_map<>
423       ::insert<int, bool>
424   >();
425 
426   FATAL_EXPECT_SAME<
427     build_type_map<int, bool, double, long>,
428     type_map<>
429       ::insert<int, bool>
430       ::insert<double, long>
431   >();
432   FATAL_EXPECT_SAME<
433     build_type_map<int, bool, double, long>,
434     type_map<>::insert<int, bool, double, long>
435   >();
436 
437   FATAL_EXPECT_SAME<
438     build_type_map<int, bool, double, long, short, void>,
439     type_map<>
440       ::insert<int, bool>
441       ::insert<double, long>
442       ::insert<short, void>
443   >();
444   FATAL_EXPECT_SAME<
445     build_type_map<int, bool, double, long, short, void>,
446     type_map<>::insert<int, bool, double, long, short, void>
447   >();
448 
449   FATAL_EXPECT_SAME<
450     build_type_map<type_pair<int, bool>, type_pair<double, long>>,
451     type_map<>
452       ::insert<type_pair<int, bool>, type_pair<double, long>>
453   >();
454 
455   FATAL_EXPECT_SAME<
456     build_type_map<
457       type_pair<int, bool>, type_pair<double, long>,
458       type_pair<short, void>, type_pair<float, unsigned>
459     >,
460     type_map<>
461       ::insert<type_pair<int, bool>, type_pair<double, long>>
462       ::insert<type_pair<short, void>, type_pair<float, unsigned>>
463   >();
464   FATAL_EXPECT_SAME<
465     build_type_map<
466       type_pair<int, bool>, type_pair<double, long>,
467       type_pair<short, void>, type_pair<float, unsigned>
468     >,
469     type_map<>::insert<
470       type_pair<int, bool>, type_pair<double, long>,
471       type_pair<short, void>, type_pair<float, unsigned>
472     >
473   >();
474 }
475 
476 ///////////////////
477 // insert_sorted //
478 ///////////////////
479 
FATAL_TEST(type_map,insert_sorted)480 FATAL_TEST(type_map, insert_sorted) {
481   FATAL_EXPECT_SAME<
482     build_type_map<int_val<1>, void>,
483     type_map<>::insert_sorted<int_val<1>, void>
484   >();
485 
486   FATAL_EXPECT_SAME<
487     build_type_map<
488       int_val<1>, bool,
489       int_val<2>, long,
490       int_val<3>, double
491     >,
492     build_type_map<
493       int_val<1>, bool,
494       int_val<3>, double
495     >::insert_sorted<int_val<2>, long>
496   >();
497 
498   FATAL_EXPECT_SAME<
499     build_type_map<
500       int_val<0>, int,
501       int_val<1>, bool,
502       int_val<3>, double
503     >,
504     build_type_map<
505       int_val<1>, bool,
506       int_val<3>, double
507     >::insert_sorted<int_val<0>, int>
508   >();
509 
510   FATAL_EXPECT_SAME<
511     build_type_map<
512       int_val<1>, bool,
513       int_val<3>, double,
514       int_val<4>, short
515     >,
516     build_type_map<
517       int_val<1>, bool,
518       int_val<3>, double
519     >::insert_sorted<int_val<4>, short>
520   >();
521 
522   FATAL_EXPECT_SAME<
523     build_type_map<
524       int_val<1>, bool,
525       int_val<3>, double,
526       int_val<3>, void
527     >,
528     build_type_map<
529       int_val<1>, bool,
530       int_val<3>, double
531     >::insert_sorted<int_val<3>, void>
532   >();
533 
534   FATAL_EXPECT_SAME<
535     build_type_map<
536       int_val<3>, double,
537       int_val<2>, long,
538       int_val<1>, bool
539     >,
540     build_type_map<
541       int_val<3>, double,
542       int_val<1>, bool
543     >::insert_sorted<int_val<2>, long, comparison_transform::greater_than>
544   >();
545 
546   FATAL_EXPECT_SAME<
547     build_type_map<
548       int_val<3>, double,
549       int_val<1>, bool,
550       int_val<0>, int
551     >,
552     build_type_map<
553       int_val<3>, double,
554       int_val<1>, bool
555     >::insert_sorted<int_val<0>, int, comparison_transform::greater_than>
556   >();
557 
558   FATAL_EXPECT_SAME<
559     build_type_map<
560       int_val<4>, short,
561       int_val<3>, double,
562       int_val<1>, bool
563     >,
564     build_type_map<
565       int_val<3>, double,
566       int_val<1>, bool
567     >::insert_sorted<int_val<4>, short, comparison_transform::greater_than>
568   >();
569 
570   FATAL_EXPECT_SAME<
571     build_type_map<
572       int_val<3>, double,
573       int_val<3>, void,
574       int_val<1>, bool
575     >,
576     build_type_map<
577       int_val<3>, double,
578       int_val<1>, bool
579     >::insert_sorted<int_val<3>, void, comparison_transform::greater_than>
580   >();
581 }
582 
583 ////////////////////////
584 // insert_pair_sorted //
585 ////////////////////////
586 
FATAL_TEST(type_map,insert_pair_sorted)587 FATAL_TEST(type_map, insert_pair_sorted) {
588   FATAL_EXPECT_SAME<
589     build_type_map<int_val<1>, void>,
590     type_map<>::insert_pair_sorted<type_pair<int_val<1>, void>>
591   >();
592 
593   FATAL_EXPECT_SAME<
594     build_type_map<
595       int_val<1>, bool,
596       int_val<2>, long,
597       int_val<3>, double
598     >,
599     build_type_map<
600       int_val<1>, bool,
601       int_val<3>, double
602     >::insert_pair_sorted<type_pair<int_val<2>, long>>
603   >();
604 
605   FATAL_EXPECT_SAME<
606     build_type_map<
607       int_val<0>, int,
608       int_val<1>, bool,
609       int_val<3>, double
610     >,
611     build_type_map<
612       int_val<1>, bool,
613       int_val<3>, double
614     >::insert_pair_sorted<type_pair<int_val<0>, int>>
615   >();
616 
617   FATAL_EXPECT_SAME<
618     build_type_map<
619       int_val<1>, bool,
620       int_val<3>, double,
621       int_val<4>, short
622     >,
623     build_type_map<
624       int_val<1>, bool,
625       int_val<3>, double
626     >::insert_pair_sorted<type_pair<int_val<4>, short>>
627   >();
628 
629   FATAL_EXPECT_SAME<
630     build_type_map<
631       int_val<1>, bool,
632       int_val<3>, double,
633       int_val<3>, void
634     >,
635     build_type_map<
636       int_val<1>, bool,
637       int_val<3>, double
638     >::insert_pair_sorted<type_pair<int_val<3>, void>>
639   >();
640 
641   FATAL_EXPECT_SAME<
642     build_type_map<
643       int_val<3>, double,
644       int_val<2>, long,
645       int_val<1>, bool
646     >,
647     build_type_map<
648       int_val<3>, double,
649       int_val<1>, bool
650     >::insert_pair_sorted<
651       type_pair<int_val<2>, long>,
652       comparison_transform::greater_than
653     >
654   >();
655 
656   FATAL_EXPECT_SAME<
657     build_type_map<
658       int_val<3>, double,
659       int_val<1>, bool,
660       int_val<0>, int
661     >,
662     build_type_map<
663       int_val<3>, double,
664       int_val<1>, bool
665     >::insert_pair_sorted<
666       type_pair<int_val<0>, int>,
667       comparison_transform::greater_than
668     >
669   >();
670 
671   FATAL_EXPECT_SAME<
672     build_type_map<
673       int_val<4>, short,
674       int_val<3>, double,
675       int_val<1>, bool
676     >,
677     build_type_map<
678       int_val<3>, double,
679       int_val<1>, bool
680     >::insert_pair_sorted<
681       type_pair<int_val<4>, short>,
682       comparison_transform::greater_than
683     >
684   >();
685 
686   FATAL_EXPECT_SAME<
687     build_type_map<
688       int_val<3>, double,
689       int_val<3>, void,
690       int_val<1>, bool
691     >,
692     build_type_map<
693       int_val<3>, double,
694       int_val<1>, bool
695     >::insert_pair_sorted<
696       type_pair<int_val<3>, void>,
697       comparison_transform::greater_than
698     >
699   >();
700 }
701 
702 /////////////
703 // replace //
704 /////////////
705 
FATAL_TEST(type_map,replace)706 FATAL_TEST(type_map, replace) {
707   FATAL_EXPECT_SAME<
708     build_type_map<>,
709     build_type_map<>::replace<int, double>
710   >();
711 
712   FATAL_EXPECT_SAME<
713     build_type_map<int, double>,
714     build_type_map<int, double>
715       ::replace<bool, short>
716   >();
717 
718   FATAL_EXPECT_SAME<
719     build_type_map<int, double, long, float>,
720     build_type_map<int, double, long, float>
721       ::replace<bool, short>
722   >();
723 
724   FATAL_EXPECT_SAME<
725     build_type_map<int, double>,
726     build_type_map<int, long>
727       ::replace<int, double>
728   >();
729 
730   FATAL_EXPECT_SAME<
731     build_type_map<int, double, float, short, int, double>,
732     build_type_map<int, long, float, short, int, bool>
733       ::replace<int, double>
734   >();
735 }
736 
737 ////////////
738 // remove //
739 ////////////
740 
FATAL_TEST(type_map,remove)741 FATAL_TEST(type_map, remove) {
742   FATAL_EXPECT_SAME<build_type_map<>, build_type_map<>::remove<>>();
743   FATAL_EXPECT_SAME<build_type_map<>, build_type_map<>::remove<int>>();
744   FATAL_EXPECT_SAME<build_type_map<>, build_type_map<>::remove<int, short>>();
745 
746   FATAL_EXPECT_SAME<
747     build_type_map<int, bool>,
748     build_type_map<int, bool, short, long>
749       ::remove<short>
750   >();
751   FATAL_EXPECT_SAME<
752     build_type_map<int, bool, short, long>,
753     build_type_map<int, bool, short, long>
754       ::remove<>
755   >();
756   FATAL_EXPECT_SAME<
757     build_type_map<int, bool, short, long>,
758     build_type_map<int, bool, short, long>
759       ::remove<bool>
760   >();
761   FATAL_EXPECT_SAME<
762     build_type_map<int, bool, short, long>,
763     build_type_map<int, bool, short, long>
764       ::remove<long>
765   >();
766   FATAL_EXPECT_SAME<
767     build_type_map<int, bool, short, long>,
768     build_type_map<int, bool, short, long>
769       ::remove<void>
770   >();
771   FATAL_EXPECT_SAME<
772     build_type_map<int, bool, short, long>,
773     build_type_map<int, bool, short, long>
774       ::remove<bool, long>
775   >();
776   FATAL_EXPECT_SAME<
777     build_type_map<int, bool, short, long>,
778     build_type_map<int, bool, short, long>
779       ::remove<void, double>
780   >();
781 
782   FATAL_EXPECT_SAME<
783     build_type_map<>,
784     build_type_map<int, bool, short, long>
785       ::remove<int, short>
786   >();
787   FATAL_EXPECT_SAME<
788     build_type_map<>,
789     build_type_map<int, bool, short, long>
790       ::remove<void, double, int, short>
791   >();
792 }
793 
794 //////////////
795 // separate //
796 //////////////
797 
FATAL_TEST(type_map,separate)798 FATAL_TEST(type_map, separate) {
799   typedef type_map<
800     type_pair<int, bool>,
801     type_pair<int, float>,
802     type_pair<void, std::string>,
803     type_pair<float, double>,
804     type_pair<bool, bool>
805   > map;
806 
807   FATAL_EXPECT_SAME<
808     type_pair<
809       type_map<
810         type_pair<int, bool>,
811         type_pair<int, float>,
812         type_pair<bool, bool>
813       >,
814       type_map<
815         type_pair<void, std::string>,
816         type_pair<float, double>
817       >
818     >,
819     map::separate<std::is_integral>
820   >();
821 }
822 
823 ////////////
824 // filter //
825 ////////////
826 
FATAL_TEST(type_map,filter)827 FATAL_TEST(type_map, filter) {
828   typedef type_map<
829     type_pair<int, bool>,
830     type_pair<int, float>,
831     type_pair<void, std::string>,
832     type_pair<float, double>,
833     type_pair<bool, bool>
834   > map;
835 
836   FATAL_EXPECT_SAME<
837     type_map<
838       type_pair<int, bool>,
839       type_pair<int, float>,
840       type_pair<bool, bool>
841     >,
842     map::filter<std::is_integral>
843   >();
844 }
845 
846 ////////////
847 // reject //
848 ////////////
849 
FATAL_TEST(type_map,reject)850 FATAL_TEST(type_map, reject) {
851   typedef type_map<
852     type_pair<int, bool>,
853     type_pair<int, float>,
854     type_pair<void, std::string>,
855     type_pair<float, double>,
856     type_pair<bool, bool>
857   > map;
858 
859   FATAL_EXPECT_SAME<
860     type_map<
861       type_pair<void, std::string>,
862       type_pair<float, double>
863     >,
864     map::reject<std::is_integral>
865   >();
866 }
867 
868 //////////
869 // sort //
870 //////////
871 
FATAL_TEST(type_map,sort)872 FATAL_TEST(type_map, sort) {
873   typedef type_map<
874     type_pair<int_val<0>, void>,
875     type_pair<int_val<1>, short>,
876     type_pair<int_val<4>, double>,
877     type_pair<int_val<2>, bool>,
878     type_pair<int_val<1>, int>,
879     type_pair<int_val<3>, float>
880   > map;
881 
882   typedef type_map<
883     type_pair<int_val<0>, void>,
884     type_pair<int_val<1>, short>,
885     type_pair<int_val<1>, int>,
886     type_pair<int_val<2>, bool>,
887     type_pair<int_val<3>, float>,
888     type_pair<int_val<4>, double>
889   > expected;
890 
891   FATAL_EXPECT_SAME<
892     expected,
893     map::sort<>
894   >();
895 
896   typedef type_map<
897     type_pair<int_val<4>, double>,
898     type_pair<int_val<3>, float>,
899     type_pair<int_val<2>, bool>,
900     type_pair<int_val<1>, short>,
901     type_pair<int_val<1>, int>,
902     type_pair<int_val<0>, void>
903   > expected_reverse;
904 
905   FATAL_EXPECT_SAME<
906     expected_reverse,
907     map::sort<comparison_transform::greater_than>
908   >();
909 }
910 
911 /////////////
912 // cluster //
913 /////////////
914 
FATAL_TEST(type_map,cluster)915 FATAL_TEST(type_map, cluster) {
916   FATAL_EXPECT_SAME<
917     build_type_map<>::sort<>,
918     build_type_map<>::cluster<>::sort<>
919   >();
920 
921   FATAL_EXPECT_SAME<
922     build_type_map<>,
923     build_type_map<>::cluster<>::sort<>::transform<sort_transform>
924   >();
925 
926   FATAL_EXPECT_SAME<
927     build_type_map<
928       x0, type_list<y0>
929     >::sort<>,
930     build_type_map<
931       x0, y0
932     >::cluster<>::sort<>::transform<sort_transform>
933   >();
934 
935   FATAL_EXPECT_SAME<
936     build_type_map<
937       x0, type_list<y0>, x1, type_list<y1>,
938       x2, type_list<y2>, x3, type_list<y3>,
939       x4, type_list<y4>, x5, type_list<y5>,
940       x6, type_list<y6>, x7, type_list<y7>,
941       x8, type_list<y8>, x9, type_list<y9>
942     >::sort<>,
943     build_type_map<
944       x0, y0, x1, y1, x2, y2, x3, y3, x4, y4,
945       x5, y5, x6, y6, x7, y7, x8, y8, x9, y9
946     >::cluster<>::sort<>::transform<sort_transform>
947   >();
948 
949   FATAL_EXPECT_SAME<
950     build_type_map<
951       x1, type_list<y0, y1, y2, y3, y4>::sort<>,
952       x2, type_list<x8, x9, z0, z2>::sort<>,
953       x3, type_list<y5, y6, y7, y8, y9>::sort<>,
954       x4, type_list<z1, z2, z3, z4, z5, z6, z7, z8, z9>::sort<>,
955       x5, type_list<z9, y0, x1>::sort<>
956     >::sort<>,
957     build_type_map<
958       x1, y0, x1, y1, x1, y2, x1, y3, x1, y4,
959       x2, x8, x2, x9, x2, z0, x2, z2,
960       x3, y5, x3, y6, x3, y7, x3, y8, x3, y9,
961       x4, z1, x4, z2, x4, z3, x4, z4, x4, z5, x4, z6, x4, z7, x4, z8, x4, z9,
962       x5, z9, x5, y0, x5, x1
963     >::cluster<>::sort<>::transform<sort_transform>
964   >();
965 }
966 
967 ///////////
968 // visit //
969 ///////////
970 
971 template <typename TExpectedKey, typename...>
972 struct visit_test_visitor {
973   using key = TExpectedKey;
974   using match = std::false_type;
975 
976   template <typename T>
operator ()fatal::visit_test_visitor977   void operator ()(T &&...) const {
978     FATAL_WARN_UNREACHABLE();
979   }
980 };
981 
982 template <typename TExpectedKey, typename TExpectedMapped>
983 struct visit_test_visitor<TExpectedKey, TExpectedMapped> {
984   using key = TExpectedKey;
985   using match = std::true_type;
986 
987   template <typename TActualKey, typename TActualMapped>
operator ()fatal::visit_test_visitor988   void operator ()(type_pair<TActualKey, TActualMapped>) const {
989     FATAL_EXPECT_SAME<TExpectedKey, TActualKey>();
990     FATAL_EXPECT_SAME<TExpectedMapped, TActualMapped>();
991   }
992 };
993 
994 #define CHECK_VISIT(Map, ...) \
995   do { \
996     using map = Map; \
997     using visitor = visit_test_visitor<__VA_ARGS__>; \
998     using key = visitor::key; \
999     auto const actual = map::template visit<key>(visitor()); \
1000     auto const expected = visitor::match::value; \
1001     FATAL_EXPECT_EQ(expected, actual); \
1002   } while (false)
1003 
1004 
FATAL_TEST(type_map,visit)1005 FATAL_TEST(type_map, visit) {
1006   using map0 = build_type_map<
1007     int, bool,
1008     double, float,
1009     std::string, std::vector<int>
1010   >;
1011 
1012   CHECK_VISIT(map0, int, bool);
1013   CHECK_VISIT(map0, double, float);
1014   CHECK_VISIT(map0, std::string, std::vector<int>);
1015 
1016   CHECK_VISIT(map0, bool);
1017   CHECK_VISIT(map0, float);
1018   CHECK_VISIT(map0, std::vector<int>);
1019   CHECK_VISIT(map0, long);
1020 }
1021 
1022 //////////////////////////
1023 // binary_search::exact //
1024 //////////////////////////
1025 
1026 template <typename T>
1027 struct bs_visitor {
1028   template <T Key, T Mapped, std::size_t Index>
operator ()fatal::bs_visitor1029   void operator ()(
1030     indexed_type_tag<
1031       type_pair<
1032         std::integral_constant<T, Key>,
1033         std::integral_constant<T, Mapped>
1034       >,
1035       Index
1036     >,
1037     T const &,
1038     T &key,
1039     T &mapped,
1040     std::size_t &index
1041   ) {
1042     key = Key;
1043     mapped = Mapped;
1044     index = Index;
1045   }
1046 };
1047 
1048 template <
1049   typename T,
1050   bool Result, T Needle, T ExpectedMapped, std::size_t ExpectedIndex,
1051   typename TMap, T Empty
1052 >
check_bs_exact()1053 void check_bs_exact() {
1054   auto key = Empty;
1055   auto mapped = Empty;
1056   std::size_t index = TMap::size;
1057 
1058   auto result = TMap::template binary_search<type_value_comparer>::exact(
1059     Needle, bs_visitor<T>(), key, mapped, index
1060   );
1061 
1062   auto const expectedResult = Result;
1063   FATAL_EXPECT_EQ(expectedResult, result);
1064   auto const expectedKey = Result ? Needle : Empty;
1065   FATAL_EXPECT_EQ(expectedKey, key);
1066   auto const expectedMapped = Result ? ExpectedMapped : Empty;
1067   FATAL_EXPECT_EQ(expectedMapped, mapped);
1068   auto const expectedIndex = ExpectedIndex;
1069   FATAL_EXPECT_EQ(expectedIndex, index);
1070 }
1071 
FATAL_TEST(type_map,binary_search_exact)1072 FATAL_TEST(type_map, binary_search_exact) {
1073   typedef chr_map<> empty;
1074 
1075   FATAL_VLOG(1) << "empty";
1076   check_bs_exact<char, false, '-', '\0', empty::size, empty, '\0'>();
1077   check_bs_exact<int, false, 3, -1, empty::size, empty, -1>();
1078 
1079   typedef chr_map<'x', 'X'> one;
1080 
1081   FATAL_VLOG(1) << "one";
1082   check_bs_exact<char, false, '-', '\0', one::size, one, '\0'>();
1083   check_bs_exact<char, true, 'x', 'X', 0, one, '\0'>();
1084 
1085   typedef chr_map<'x', 'X', 'y', 'Y'> two;
1086 
1087   FATAL_VLOG(1) << "two";
1088   check_bs_exact<char, false, '-', '\0', two::size, two, '\0'>();
1089   check_bs_exact<char, true, 'x', 'X', 0, two, '\0'>();
1090   check_bs_exact<char, true, 'y', 'Y', 1, two, '\0'>();
1091 
1092   typedef chr_map<'a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U'> aeiou;
1093 
1094   FATAL_VLOG(1) << "aeiou";
1095   check_bs_exact<char, false, 'x', '\0', aeiou::size, aeiou, '\0'>();
1096 
1097   check_bs_exact<char, true, 'a', 'A', 0, aeiou, '\0'>();
1098   check_bs_exact<char, true, 'e', 'E', 1, aeiou, '\0'>();
1099   check_bs_exact<char, true, 'i', 'I', 2, aeiou, '\0'>();
1100   check_bs_exact<char, true, 'o', 'O', 3, aeiou, '\0'>();
1101   check_bs_exact<char, true, 'u', 'U', 4, aeiou, '\0'>();
1102 
1103   typedef int_map<
1104     3, 2, 7, 3, 31, 5, 127, 7, 8191, 13, 131071, 17, 524287, 19, 2147483647, 31
1105   > mp;
1106 
1107   FATAL_VLOG(1) << "mp";
1108   check_bs_exact<int, false, -1, -1, mp::size, mp, -1>();
1109   check_bs_exact<int, false, 0, -1, mp::size, mp, -1>();
1110   check_bs_exact<int, false, 63, -1, mp::size, mp, -1>();
1111   check_bs_exact<int, false, 63, -1, mp::size, mp, -1>();
1112 
1113   check_bs_exact<int, true, 3, 2, 0, mp, -1>();
1114   check_bs_exact<int, true, 7, 3, 1, mp, -1>();
1115   check_bs_exact<int, true, 31, 5, 2, mp, -1>();
1116   check_bs_exact<int, true, 127, 7, 3, mp, -1>();
1117   check_bs_exact<int, true, 8191, 13, 4, mp, -1>();
1118   check_bs_exact<int, true, 131071, 17, 5, mp, -1>();
1119   check_bs_exact<int, true, 524287, 19, 6, mp, -1>();
1120   check_bs_exact<int, true, 2147483647, 31, 7, mp, -1>();
1121 }
1122 
1123 ////////////////////////////////
1124 // binary_search::lower_bound //
1125 ////////////////////////////////
1126 
1127 template <
1128   typename T,
1129   bool Result, T Needle, T ExpectedKey, T ExpectedMapped,
1130   std::size_t ExpectedIndex, typename TMap, T Empty
1131 >
check_bs_lower_bound()1132 void check_bs_lower_bound() {
1133   auto key = Empty;
1134   auto mapped = Empty;
1135   std::size_t index = TMap::size;
1136 
1137   auto result = TMap::template binary_search<type_value_comparer>::lower_bound(
1138     Needle, bs_visitor<T>(), key, mapped, index
1139   );
1140 
1141   auto const expectedResult = Result;
1142   FATAL_EXPECT_EQ(expectedResult, result);
1143   auto const expectedKey = ExpectedKey;
1144   FATAL_EXPECT_EQ(expectedKey, key);
1145   auto const expectedMapped = ExpectedMapped;
1146   FATAL_EXPECT_EQ(expectedMapped, mapped);
1147   auto const expectedIndex = ExpectedIndex;
1148   FATAL_EXPECT_EQ(expectedIndex, index);
1149 }
1150 
FATAL_TEST(type_map,binary_search_lower_bound)1151 FATAL_TEST(type_map, binary_search_lower_bound) {
1152   typedef chr_map<> empty;
1153 
1154   FATAL_VLOG(1) << "empty";
1155   check_bs_lower_bound<char, false, '-', '\0', '\0', empty::size,
1156     empty, '\0'
1157   >();
1158   check_bs_lower_bound<int,  false, 3,   -1,   -1, empty::size, empty, -1>();
1159 
1160   typedef chr_map<'x', 'X'> one;
1161 
1162   FATAL_VLOG(1) << "one";
1163   check_bs_lower_bound<char, false, 'w', '\0', '\0', one::size, one, '\0'>();
1164   check_bs_lower_bound<char, true,  'x', 'x',  'X',  0, one, '\0'>();
1165   check_bs_lower_bound<char, true,  'y', 'x',  'X',  0, one, '\0'>();
1166 
1167   typedef chr_map<'x', 'X', 'y', 'Y'> two;
1168 
1169   FATAL_VLOG(1) << "two";
1170   check_bs_lower_bound<char, false, 'w', '\0', '\0', two::size, two, '\0'>();
1171   check_bs_lower_bound<char, true,  'x', 'x',  'X',  0, two, '\0'>();
1172   check_bs_lower_bound<char, true,  'y', 'y',  'Y',  1, two, '\0'>();
1173   check_bs_lower_bound<char, true,  'z', 'y',  'Y',  1, two, '\0'>();
1174 
1175   typedef chr_map<'a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U'> aeiou;
1176 
1177   FATAL_VLOG(1) << "aeiou";
1178   check_bs_lower_bound<char, false, 'a' - 1, '\0', '\0', aeiou::size,
1179     aeiou, '\0'
1180   >();
1181   check_bs_lower_bound<char, true,  'a',     'a',  'A',  0, aeiou, '\0'>();
1182   check_bs_lower_bound<char, true,  'e',     'e',  'E',  1, aeiou, '\0'>();
1183   check_bs_lower_bound<char, true,  'i',     'i',  'I',  2, aeiou, '\0'>();
1184   check_bs_lower_bound<char, true,  'o',     'o',  'O',  3, aeiou, '\0'>();
1185   check_bs_lower_bound<char, true,  'u',     'u',  'U',  4, aeiou, '\0'>();
1186   check_bs_lower_bound<char, true,  'x',     'u',  'U',  4, aeiou, '\0'>();
1187 
1188   typedef int_map<
1189     3, 2, 7, 3, 31, 5, 127, 7, 8191, 13, 131071, 17, 524287, 19
1190   > mp;
1191 
1192   FATAL_VLOG(1) << "mp";
1193   check_bs_lower_bound<int, false, -1,        -1,     -1, mp::size, mp, -1>();
1194   check_bs_lower_bound<int, false, 0,         -1,     -1, mp::size, mp, -1>();
1195   check_bs_lower_bound<int, false, 2,         -1,     -1, mp::size, mp, -1>();
1196   check_bs_lower_bound<int, true,  3,         3,      2,  0, mp, -1>();
1197   check_bs_lower_bound<int, true,  4,         3,      2,  0, mp, -1>();
1198   check_bs_lower_bound<int, true,  6,         3,      2,  0, mp, -1>();
1199   check_bs_lower_bound<int, true,  7,         7,      3,  1, mp, -1>();
1200   check_bs_lower_bound<int, true,  8,         7,      3,  1, mp, -1>();
1201   check_bs_lower_bound<int, true,  30,        7,      3,  1, mp, -1>();
1202   check_bs_lower_bound<int, true,  31,        31,     5,  2, mp, -1>();
1203   check_bs_lower_bound<int, true,  32,        31,     5,  2, mp, -1>();
1204   check_bs_lower_bound<int, true,  126,       31,     5,  2, mp, -1>();
1205   check_bs_lower_bound<int, true,  127,       127,    7,  3, mp, -1>();
1206   check_bs_lower_bound<int, true,  128,       127,    7,  3, mp, -1>();
1207   check_bs_lower_bound<int, true,  8190,      127,    7,  3, mp, -1>();
1208   check_bs_lower_bound<int, true,  8191,      8191,   13, 4, mp, -1>();
1209   check_bs_lower_bound<int, true,  8192,      8191,   13, 4, mp, -1>();
1210   check_bs_lower_bound<int, true,  131070,    8191,   13, 4, mp, -1>();
1211   check_bs_lower_bound<int, true,  131071,    131071, 17, 5, mp, -1>();
1212   check_bs_lower_bound<int, true,  131072,    131071, 17, 5, mp, -1>();
1213   check_bs_lower_bound<int, true,  524286,    131071, 17, 5, mp, -1>();
1214   check_bs_lower_bound<int, true,  524287,    524287, 19, 6, mp, -1>();
1215   check_bs_lower_bound<int, true,  524288,    524287, 19, 6, mp, -1>();
1216 }
1217 
1218 ////////////////////////////////
1219 // binary_search::upper_bound //
1220 ////////////////////////////////
1221 
1222 template <
1223   typename T,
1224   bool Result, T Needle, T ExpectedKey, T ExpectedMapped,
1225   std::size_t ExpectedIndex, typename TMap, T Empty
1226 >
check_bs_upper_bound()1227 void check_bs_upper_bound() {
1228   auto key = Empty;
1229   auto mapped = Empty;
1230   std::size_t index = TMap::size;
1231 
1232   auto result = TMap::template binary_search<type_value_comparer>::upper_bound(
1233     Needle, bs_visitor<T>(), key, mapped, index
1234   );
1235 
1236   auto const expectedResult = Result;
1237   FATAL_EXPECT_EQ(expectedResult, result);
1238   auto const expectedKey = ExpectedKey;
1239   FATAL_EXPECT_EQ(expectedKey, key);
1240   auto const expectedMapped = ExpectedMapped;
1241   FATAL_EXPECT_EQ(expectedMapped, mapped);
1242   auto const expectedIndex = ExpectedIndex;
1243   FATAL_EXPECT_EQ(expectedIndex, index);
1244 }
1245 
FATAL_TEST(type_map,binary_search_upper_bound)1246 FATAL_TEST(type_map, binary_search_upper_bound) {
1247   typedef chr_map<> empty;
1248 
1249   FATAL_VLOG(1) << "empty";
1250   check_bs_upper_bound<char, false, '-', '\0', '\0', empty::size,
1251     empty, '\0'
1252   >();
1253   check_bs_upper_bound<int,  false, 3,   -1,   -1,   empty::size, empty, -1>();
1254 
1255   typedef chr_map<'x', 'X'> one;
1256 
1257   FATAL_VLOG(1) << "one";
1258   check_bs_upper_bound<char, true,  'w', 'x',  'X',  0, one, '\0'>();
1259   check_bs_upper_bound<char, false, 'x', '\0', '\0', one::size, one, '\0'>();
1260   check_bs_upper_bound<char, false, 'y', '\0', '\0', one::size, one, '\0'>();
1261 
1262   typedef chr_map<'x', 'X', 'y', 'Y'> two;
1263 
1264   FATAL_VLOG(1) << "two";
1265   check_bs_upper_bound<char, true,  'w', 'x',  'X',  0, two, '\0'>();
1266   check_bs_upper_bound<char, true,  'x', 'y',  'Y',  1, two, '\0'>();
1267   check_bs_upper_bound<char, false, 'y', '\0', '\0', two::size, two, '\0'>();
1268   check_bs_upper_bound<char, false, 'z', '\0', '\0', two::size, two, '\0'>();
1269 
1270   typedef chr_map<'a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U'> aeiou;
1271 
1272   FATAL_VLOG(1) << "aeiou";
1273   check_bs_upper_bound<char, true, 'a' - 1, 'a',  'A',  0, aeiou, '\0'>();
1274   check_bs_upper_bound<char, true, 'a',     'e',  'E',  1, aeiou, '\0'>();
1275   check_bs_upper_bound<char, true, 'e',     'i',  'I',  2, aeiou, '\0'>();
1276   check_bs_upper_bound<char, true, 'i',     'o',  'O',  3, aeiou, '\0'>();
1277   check_bs_upper_bound<char, true, 'o',     'u',  'U',  4, aeiou, '\0'>();
1278   check_bs_upper_bound<char, false, 'u',    '\0', '\0', aeiou::size,
1279     aeiou, '\0'
1280   >();
1281 
1282   typedef int_map<
1283     3, 2, 7, 3, 31, 5, 127, 7, 8191, 13, 131071, 17, 524287, 19
1284   > mp;
1285 
1286   FATAL_VLOG(1) << "mp";
1287   check_bs_upper_bound<int, true,  -1,         3,      2,  0, mp, -1>();
1288   check_bs_upper_bound<int, true,  0,          3,      2,  0, mp, -1>();
1289   check_bs_upper_bound<int, true,  2,          3,      2,  0, mp, -1>();
1290   check_bs_upper_bound<int, true,  3,          7,      3,  1, mp, -1>();
1291   check_bs_upper_bound<int, true,  4,          7,      3,  1, mp, -1>();
1292   check_bs_upper_bound<int, true,  6,          7,      3,  1, mp, -1>();
1293   check_bs_upper_bound<int, true,  7,          31,     5,  2, mp, -1>();
1294   check_bs_upper_bound<int, true,  8,          31,     5,  2, mp, -1>();
1295   check_bs_upper_bound<int, true,  30,         31,     5,  2, mp, -1>();
1296   check_bs_upper_bound<int, true,  31,         127,    7,  3, mp, -1>();
1297   check_bs_upper_bound<int, true,  32,         127,    7,  3, mp, -1>();
1298   check_bs_upper_bound<int, true,  126,        127,    7,  3, mp, -1>();
1299   check_bs_upper_bound<int, true,  127,        8191,   13, 4, mp, -1>();
1300   check_bs_upper_bound<int, true,  128,        8191,   13, 4, mp, -1>();
1301   check_bs_upper_bound<int, true,  8190,       8191,   13, 4, mp, -1>();
1302   check_bs_upper_bound<int, true,  8191,       131071, 17, 5, mp, -1>();
1303   check_bs_upper_bound<int, true,  8192,       131071, 17, 5, mp, -1>();
1304   check_bs_upper_bound<int, true,  131070,     131071, 17, 5, mp, -1>();
1305   check_bs_upper_bound<int, true,  131071,     524287, 19, 6, mp, -1>();
1306   check_bs_upper_bound<int, true,  131072,     524287, 19, 6, mp, -1>();
1307   check_bs_upper_bound<int, true,  524286,     524287, 19, 6, mp, -1>();
1308   check_bs_upper_bound<int, false, 524287,     -1,     -1, mp::size, mp, -1>();
1309   check_bs_upper_bound<int, false, 524288,     -1,     -1, mp::size, mp, -1>();
1310 }
1311 
1312 //////////////
1313 // type_get //
1314 //////////////
1315 
1316 template <typename TMap>
1317 struct check_type_get_visitor {
1318   template <typename T, std::size_t Index>
operator ()fatal::check_type_get_visitor1319   void operator ()(indexed_type_tag<T, Index> const &) {
1320     FATAL_EXPECT_SAME<T, typename type_get<Index>::template from<TMap>>();
1321 
1322     FATAL_EXPECT_SAME<
1323       typename TMap::contents::template at<Index>,
1324       typename type_get<Index>::template from<TMap>
1325     >();
1326   }
1327 };
1328 
1329 template <typename... Args>
1330 void check_type_get() {
1331   typedef build_type_map<Args...> map;
1332   map::contents::foreach(check_type_get_visitor<map>());
1333 }
1334 
1335 FATAL_TEST(type_get, type_map) {
1336   check_type_get<>();
1337   check_type_get<void, void>();
1338   check_type_get<int, double>();
1339   check_type_get<int, bool, float, long>();
1340   check_type_get<
1341     type_list<bool, int>,
1342     type_list<std::string, std::string>,
1343     type_list<std::string, std::string, void>,
1344     build_type_map<float, double>
1345   >();
1346 }
1347 
1348 /////////////////////////
1349 // type_map_from::list //
1350 /////////////////////////
1351 
1352 FATAL_TEST(type_map, type_map_from_list) {
1353   typedef type_list<int, bool, double> list;
1354 
1355   typedef type_map<
1356      type_pair<type1_t<int>, int>,
1357      type_pair<type1_t<bool>, bool>,
1358      type_pair<type1_t<double>, double>
1359   > expected1;
1360   FATAL_EXPECT_SAME<expected1, type_map_from<type1_t>::list<list>>();
1361 
1362   typedef type_map<
1363      type_pair<type1_t<int>, type2_t<int>>,
1364      type_pair<type1_t<bool>, type2_t<bool>>,
1365      type_pair<type1_t<double>, type2_t<double>>
1366   > expected2;
1367   FATAL_EXPECT_SAME<expected2, type_map_from<type1_t, type2_t>::list<list>>();
1368 
1369   typedef type_map<
1370      type_pair<int, int>,
1371      type_pair<bool, bool>,
1372      type_pair<double, double>
1373   > expected3;
1374   FATAL_EXPECT_SAME<expected3, type_map_from<>::list<list>>();
1375 }
1376 
1377 /////////////////////
1378 // clustered_index //
1379 /////////////////////
1380 
1381 template <typename L1, typename L2, typename L3, typename L4>
1382 struct clustered_index_metadata {
1383   typedef L1 l1;
1384   typedef L2 l2;
1385   typedef L3 l3;
1386   typedef L4 l4;
1387 };
1388 
1389 template <typename T> struct get_l1_impl { typedef typename T::l1 type; };
1390 template <typename T> using get_l1 = typename get_l1_impl<T>::type;
1391 template <typename T> struct get_l2_impl { typedef typename T::l2 type; };
1392 template <typename T> using get_l2 = typename get_l2_impl<T>::type;
1393 template <typename T> struct get_l3_impl { typedef typename T::l3 type; };
1394 template <typename T> using get_l3 = typename get_l3_impl<T>::type;
1395 template <typename T> struct get_l4_impl { typedef typename T::l4 type; };
1396 template <typename T> using get_l4 = typename get_l4_impl<T>::type;
1397 
1398 template <typename TInput, typename TExpected>
1399 void check_clustered_index() {
1400   using expected = full_recursive_type_sort<TExpected>;
1401   using actual = full_recursive_type_sort<
1402     clustered_index<TInput, get_l1, get_l2, get_l3, get_l4>
1403   >;
1404 
1405   FATAL_EXPECT_SAME<expected, actual>();
1406 }
1407 
1408 FATAL_TEST(type_map, clustered_index) {
1409   check_clustered_index<type_list<>, type_map<>>();
1410 
1411   typedef clustered_index_metadata<w0, x0, y0, z0> d0;
1412   typedef clustered_index_metadata<w1, x1, y1, z1> d1;
1413   typedef clustered_index_metadata<w2, x2, y2, z2> d2;
1414   typedef clustered_index_metadata<w3, x3, y3, z3> d3;
1415   typedef clustered_index_metadata<w4, x4, y4, z4> d4;
1416   typedef clustered_index_metadata<w5, x5, y5, z5> d5;
1417   typedef clustered_index_metadata<w6, x6, y6, z6> d6;
1418   typedef clustered_index_metadata<w7, x7, y7, z7> d7;
1419   typedef clustered_index_metadata<w8, x8, y8, z8> d8;
1420   typedef clustered_index_metadata<w9, x9, y9, z9> d9;
1421 
1422   check_clustered_index<
1423     type_list<d0>,
1424     build_type_map<
1425       w0, build_type_map<x0, build_type_map<y0, build_type_map<z0, d0>>>
1426     >
1427   >();
1428 
1429   check_clustered_index<
1430     type_list<d0, d1, d2, d3, d4, d5, d6, d7, d8, d9>,
1431     build_type_map<
1432       w0, build_type_map<x0, build_type_map<y0, build_type_map<z0, d0>>>,
1433       w1, build_type_map<x1, build_type_map<y1, build_type_map<z1, d1>>>,
1434       w2, build_type_map<x2, build_type_map<y2, build_type_map<z2, d2>>>,
1435       w3, build_type_map<x3, build_type_map<y3, build_type_map<z3, d3>>>,
1436       w4, build_type_map<x4, build_type_map<y4, build_type_map<z4, d4>>>,
1437       w5, build_type_map<x5, build_type_map<y5, build_type_map<z5, d5>>>,
1438       w6, build_type_map<x6, build_type_map<y6, build_type_map<z6, d6>>>,
1439       w7, build_type_map<x7, build_type_map<y7, build_type_map<z7, d7>>>,
1440       w8, build_type_map<x8, build_type_map<y8, build_type_map<z8, d8>>>,
1441       w9, build_type_map<x9, build_type_map<y9, build_type_map<z9, d9>>>
1442     >
1443   >();
1444 
1445   typedef clustered_index_metadata<w1, x1, y1, z1> d111;
1446   typedef clustered_index_metadata<w1, x1, y1, z2> d112;
1447   typedef clustered_index_metadata<w1, x1, y1, z3> d113;
1448   typedef clustered_index_metadata<w1, x1, y1, z4> d114;
1449   typedef clustered_index_metadata<w1, x1, y2, z1> d121;
1450   typedef clustered_index_metadata<w1, x1, y2, z2> d122;
1451   typedef clustered_index_metadata<w1, x1, y2, z3> d123;
1452   typedef clustered_index_metadata<w1, x1, y2, z4> d124;
1453   typedef clustered_index_metadata<w1, x1, y3, z1> d131;
1454   typedef clustered_index_metadata<w1, x1, y3, z2> d132;
1455   typedef clustered_index_metadata<w1, x1, y3, z3> d133;
1456   typedef clustered_index_metadata<w1, x1, y3, z4> d134;
1457   typedef clustered_index_metadata<w1, x1, y4, z1> d141;
1458   typedef clustered_index_metadata<w1, x1, y4, z2> d142;
1459   typedef clustered_index_metadata<w1, x1, y4, z3> d143;
1460   typedef clustered_index_metadata<w1, x1, y4, z4> d144;
1461   typedef clustered_index_metadata<w1, x2, y1, z1> d211;
1462   typedef clustered_index_metadata<w1, x2, y1, z2> d212;
1463   typedef clustered_index_metadata<w1, x2, y1, z3> d213;
1464   typedef clustered_index_metadata<w1, x2, y1, z4> d214;
1465   typedef clustered_index_metadata<w1, x2, y2, z1> d221;
1466   typedef clustered_index_metadata<w1, x2, y2, z2> d222;
1467   typedef clustered_index_metadata<w1, x2, y2, z3> d223;
1468   typedef clustered_index_metadata<w1, x2, y2, z4> d224;
1469   typedef clustered_index_metadata<w1, x2, y3, z1> d231;
1470   typedef clustered_index_metadata<w1, x2, y3, z2> d232;
1471   typedef clustered_index_metadata<w1, x2, y3, z3> d233;
1472   typedef clustered_index_metadata<w1, x2, y3, z4> d234;
1473   typedef clustered_index_metadata<w1, x2, y4, z1> d241;
1474   typedef clustered_index_metadata<w1, x2, y4, z2> d242;
1475   typedef clustered_index_metadata<w1, x2, y4, z3> d243;
1476   typedef clustered_index_metadata<w1, x2, y4, z4> d244;
1477   typedef clustered_index_metadata<w1, x3, y1, z1> d311;
1478   typedef clustered_index_metadata<w1, x3, y1, z2> d312;
1479   typedef clustered_index_metadata<w1, x3, y1, z3> d313;
1480   typedef clustered_index_metadata<w1, x3, y1, z4> d314;
1481   typedef clustered_index_metadata<w1, x3, y2, z1> d321;
1482   typedef clustered_index_metadata<w1, x3, y2, z2> d322;
1483   typedef clustered_index_metadata<w1, x3, y2, z3> d323;
1484   typedef clustered_index_metadata<w1, x3, y2, z4> d324;
1485   typedef clustered_index_metadata<w1, x3, y3, z1> d331;
1486   typedef clustered_index_metadata<w1, x3, y3, z2> d332;
1487   typedef clustered_index_metadata<w1, x3, y3, z3> d333;
1488   typedef clustered_index_metadata<w1, x3, y3, z4> d334;
1489   typedef clustered_index_metadata<w1, x3, y4, z1> d341;
1490   typedef clustered_index_metadata<w1, x3, y4, z2> d342;
1491   typedef clustered_index_metadata<w1, x3, y4, z3> d343;
1492   typedef clustered_index_metadata<w1, x3, y4, z4> d344;
1493   typedef clustered_index_metadata<w1, x4, y1, z1> d411;
1494   typedef clustered_index_metadata<w1, x4, y1, z2> d412;
1495   typedef clustered_index_metadata<w1, x4, y1, z3> d413;
1496   typedef clustered_index_metadata<w1, x4, y1, z4> d414;
1497   typedef clustered_index_metadata<w1, x4, y2, z1> d421;
1498   typedef clustered_index_metadata<w1, x4, y2, z2> d422;
1499   typedef clustered_index_metadata<w1, x4, y2, z3> d423;
1500   typedef clustered_index_metadata<w1, x4, y2, z4> d424;
1501   typedef clustered_index_metadata<w1, x4, y3, z1> d431;
1502   typedef clustered_index_metadata<w1, x4, y3, z2> d432;
1503   typedef clustered_index_metadata<w1, x4, y3, z3> d433;
1504   typedef clustered_index_metadata<w1, x4, y3, z4> d434;
1505   typedef clustered_index_metadata<w1, x4, y4, z1> d441;
1506   typedef clustered_index_metadata<w1, x4, y4, z2> d442;
1507   typedef clustered_index_metadata<w1, x4, y4, z3> d443;
1508   typedef clustered_index_metadata<w1, x4, y4, z4> d444;
1509 
1510   check_clustered_index<
1511     type_list<
1512       d111, d111, d112, d113, d114, d121, d122, d123, d124,
1513       d131, d132, d133, d134, d141, d142, d143, d144,
1514       d211, d212, d213, d214, d221, d222, d223, d224,
1515       d231, d231, d232, d233, d234, d241, d242, d243, d244,
1516       d311, d312, d313, d314, d321, d322, d323, d324,
1517       d331, d332, d333, d334, d341, d341, d342, d343, d344,
1518       d411, d412, d413, d414, d421, d422, d423, d424,
1519       d431, d432, d433, d434, d441, d441, d442, d443, d444
1520     >,
1521     build_type_map<
1522       w1, build_type_map<
1523         x1, build_type_map<
1524           y1, build_type_map<z1, d111, z1, d111, z2, d112, z3, d113, z4, d114>,
1525           y2, build_type_map<z1, d121, z2, d122, z3, d123, z4, d124>,
1526           y3, build_type_map<z1, d131, z2, d132, z3, d133, z4, d134>,
1527           y4, build_type_map<z1, d141, z2, d142, z3, d143, z4, d144>
1528         >,
1529         x2, build_type_map<
1530           y1, build_type_map<z1, d211, z2, d212, z3, d213, z4, d214>,
1531           y2, build_type_map<z1, d221, z2, d222, z3, d223, z4, d224>,
1532           y3, build_type_map<z1, d231, z1, d231, z2, d232, z3, d233, z4, d234>,
1533           y4, build_type_map<z1, d241, z2, d242, z3, d243, z4, d244>
1534         >,
1535         x3, build_type_map<
1536           y1, build_type_map<z1, d311, z2, d312, z3, d313, z4, d314>,
1537           y2, build_type_map<z1, d321, z2, d322, z3, d323, z4, d324>,
1538           y3, build_type_map<z1, d331, z2, d332, z3, d333, z4, d334>,
1539           y4, build_type_map<z1, d341, z1, d341, z2, d342, z3, d343, z4, d344>
1540         >,
1541         x4, build_type_map<
1542           y1, build_type_map<z1, d411, z2, d412, z3, d413, z4, d414>,
1543           y2, build_type_map<z1, d421, z2, d422, z3, d423, z4, d424>,
1544           y3, build_type_map<z1, d431, z2, d432, z3, d433, z4, d434>,
1545           y4, build_type_map<z1, d441, z1, d441, z2, d442, z3, d443, z4, d444>
1546         >
1547       >
1548     >
1549   >();
1550 }
1551 
1552 } // namespace fatal {
1553