tuplelist.C 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file tuplelist.C
  3. /// @brief Test type list library based on tuples.
  4. // (c) Daniel Llorens - 2010
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. #include <iostream>
  10. #include "ra/tuple-dynamic.H"
  11. #include "ra/tuple-list.H"
  12. #include "ra/mpdebug.H"
  13. #include "ra/test.H"
  14. using std::tuple, std::tuple_element, std::is_same_v;
  15. using std::cout, std::endl;
  16. using mp::int_t, mp::ref, mp::int_list;
  17. template <class A>
  18. struct Inc1
  19. {
  20. using type = int_t<A::value+1>;
  21. };
  22. template <class A, class B>
  23. struct Sum2
  24. {
  25. using type = int_t<A::value+B::value>;
  26. };
  27. template <class ... A> struct SumV;
  28. template <class A0, class ... A>
  29. struct SumV<A0, A ...>
  30. {
  31. constexpr static int value = A0::value + SumV<A ...>::value;
  32. };
  33. template <>
  34. struct SumV<>
  35. {
  36. constexpr static int value = 0;
  37. };
  38. template <class A>
  39. struct SamePP
  40. {
  41. template <class B>
  42. struct type
  43. {
  44. constexpr static bool value = is_same_v<A, B>;
  45. };
  46. };
  47. struct True
  48. {
  49. constexpr static bool value = true;
  50. };
  51. int main()
  52. {
  53. TestRecorder tr(std::cout);
  54. // Booleans.
  55. {
  56. static_assert(True::value, "bad True");
  57. }
  58. // Map
  59. {
  60. using A = int_list<5, 6, 3>;
  61. using B = int_list<2, 3, -1>;
  62. static_assert(mp::check_idx<mp::map<mp::sum, A>, 5, 6, 3>::value, "");
  63. static_assert(mp::check_idx<mp::map<mp::sum, A, B>, 7, 9, 2>::value, "");
  64. }
  65. // fold.
  66. {
  67. using A = int_list<5, 6, 3>;
  68. using B = int_list<2, 3, -1>;
  69. static_assert(mp::fold<mp::sum, int_t<1>, A>::value==15, "");
  70. static_assert(mp::fold<mp::sum, int_t<3>, B>::value==7, "");
  71. static_assert(mp::fold<mp::max, int_t<4>, A>::value==6, "");
  72. static_assert(mp::fold<mp::max, void, A>::value==6, "");
  73. static_assert(mp::fold<mp::max, int_t<9>, A>::value==9, "");
  74. static_assert(mp::fold<mp::min, int_t<4>, A>::value==3, "");
  75. static_assert(mp::fold<mp::min, void, A>::value==3, "");
  76. static_assert(mp::fold<mp::min, int_t<1>, A>::value==1, "");
  77. }
  78. // Reductions.
  79. {
  80. using list_ = int_list<>;
  81. using list_1 = int_list<1>;
  82. using list_0 = int_list<0>;
  83. using list_10 = int_list<1, 0>;
  84. using list_01 = int_list<0, 1>;
  85. using list_11 = int_list<1, 1>;
  86. using list_00 = int_list<0, 0>;
  87. static_assert(mp::apply<mp::andb, list_>::value, "bad And");
  88. static_assert(mp::apply<mp::andb, list_1>::value, "bad And");
  89. static_assert(!mp::apply<mp::andb, list_0>::value, "bad And");
  90. static_assert(!mp::apply<mp::andb, list_10>::value, "bad And");
  91. static_assert(!mp::apply<mp::andb, list_01>::value, "bad And");
  92. static_assert(mp::apply<mp::andb, list_11>::value, "bad And");
  93. static_assert(!mp::apply<mp::andb, list_00>::value, "bad And");
  94. static_assert(!mp::apply<mp::orb, list_>::value, "bad Or");
  95. static_assert(mp::apply<mp::orb, list_1>::value, "bad Or");
  96. static_assert(!mp::apply<mp::orb, list_0>::value, "bad Or");
  97. static_assert(mp::apply<mp::orb, list_10>::value, "bad Or");
  98. static_assert(mp::apply<mp::orb, list_01>::value, "bad Or");
  99. static_assert(mp::apply<mp::orb, list_11>::value, "bad Or");
  100. static_assert(!mp::apply<mp::orb, list_00>::value, "bad Or");
  101. static_assert(mp::apply<mp::sum, list_>::value==0, "bad Sum");
  102. static_assert(mp::apply<mp::sum, int_list<2, 4>>::value==6, "bad Sum");
  103. static_assert(mp::apply<mp::prod, list_>::value==1, "bad Prod");
  104. static_assert(mp::apply<mp::prod, int_list<2, 3>>::value==6, "bad Prod");
  105. }
  106. // append.
  107. using A = int_list<0, 2, 3>;
  108. using B = int_list<5, 6, 7>;
  109. using C = int_list<9, 8>;
  110. static_assert(is_same_v<int_list<>, mp::nil>, "");
  111. static_assert(is_same_v<C, tuple<int_t<9>, int_t<8>>>, "");
  112. using O = mp::nil;
  113. using A_B = mp::append<A, B>;
  114. using A_C = mp::append<A, C>;
  115. using C_B = mp::append<C, B>;
  116. static_assert(mp::check_idx<A_B, 0, 2, 3, 5, 6, 7>::value, "bad AB");
  117. static_assert(mp::check_idx<A_C, 0, 2, 3, 9, 8>::value, "bad AB");
  118. static_assert(mp::check_idx<C_B, 9, 8, 5, 6, 7>::value, "bad AB");
  119. static_assert(is_same_v<A, mp::append<A, O>>, "bad A+empty");
  120. static_assert(is_same_v<A, mp::append<O, A>>, "bad empty+A");
  121. // Iota.
  122. static_assert(mp::check_idx<mp::iota<4, 0>, 0, 1, 2, 3>::value, "0a");
  123. static_assert(mp::check_idx<mp::iota<4, 3>, 3, 4, 5, 6>::value, "0b");
  124. static_assert(mp::check_idx<mp::iota<0, 3>>::value, "0c");
  125. static_assert(mp::check_idx<mp::iota<1, 3>, 3>::value, "0d");
  126. static_assert(mp::check_idx<mp::iota<3, -2>, -2, -1, 0>::value, "0e");
  127. static_assert(mp::check_idx<mp::iota<4, 3, -1>, 3, 2, 1, 0>::value, "0a");
  128. // makelist
  129. static_assert(mp::check_idx<mp::makelist<2, int_t<9>>, 9, 9>::value, "1a");
  130. static_assert(mp::check_idx<mp::makelist<0, int_t<9>>>::value, "1b");
  131. // ref
  132. static_assert(ref<tuple<A, B, C>, 0, 0>::value==0, "3a");
  133. static_assert(ref<tuple<A, B, C>, 0, 1>::value==2, "3b");
  134. static_assert(ref<tuple<A, B, C>, 0, 2>::value==3, "3c");
  135. static_assert(ref<tuple<A, B, C>, 1, 0>::value==5, "3d");
  136. static_assert(ref<tuple<A, B, C>, 1, 1>::value==6, "3e");
  137. static_assert(ref<tuple<A, B, C>, 1, 2>::value==7, "3f");
  138. static_assert(ref<tuple<A, B, C>, 2, 0>::value==9, "3g");
  139. static_assert(ref<tuple<A, B, C>, 2, 1>::value==8, "3h");
  140. static_assert(mp::first<B>::value==5 && mp::first<C>::value==9, "3i");
  141. static_assert(mp::last<B>::value==7 && mp::last<C>::value==8, "3j");
  142. // Useful default.
  143. static_assert(mp::len<ref<mp::nil>> ==0, "3i");
  144. // 3-indices.
  145. using S2AB = tuple<A, B>;
  146. using S2BC = tuple<B, C>;
  147. using S3 = tuple<S2AB, S2BC>;
  148. // in S2AB.
  149. static_assert(ref<S3, 0, 0, 0>::value==0, "3j");
  150. static_assert(ref<S3, 0, 0, 1>::value==2, "3k");
  151. static_assert(ref<S3, 0, 0, 2>::value==3, "3l");
  152. static_assert(ref<S3, 0, 1, 0>::value==5, "3m");
  153. static_assert(ref<S3, 0, 1, 1>::value==6, "3n");
  154. static_assert(ref<S3, 0, 1, 2>::value==7, "3o");
  155. // in S2BC.
  156. static_assert(ref<S3, 1, 0, 0>::value==5, "3p");
  157. static_assert(ref<S3, 1, 0, 1>::value==6, "3q");
  158. static_assert(ref<S3, 1, 0, 2>::value==7, "3r");
  159. static_assert(ref<S3, 1, 1, 0>::value==9, "3s");
  160. static_assert(ref<S3, 1, 1, 1>::value==8, "3t");
  161. // index.
  162. static_assert(mp::index<A, int_t<0>>::value==0, "4a");
  163. static_assert(mp::index<A, int_t<2>>::value==1, "4b");
  164. static_assert(mp::index<A, int_t<3>>::value==2, "4c");
  165. static_assert(mp::index<A, int_t<4>>::value==-1, "4d");
  166. static_assert(mp::index<S3, S2BC>::value==1, "4e");
  167. // InvertIndex
  168. {
  169. using II0 = int_list<4, 6, 7, 1>;
  170. using II1 = mp::InvertIndex_<II0>;
  171. static_assert(is_same_v<int_list<-1, 3, -1, -1, 0, -1, 1, 2>, II1>);
  172. }
  173. {
  174. using II0 = int_list<3>;
  175. using II1 = mp::InvertIndex_<II0>;
  176. static_assert(is_same_v<int_list<-1, -1, -1, 0>, II1>);
  177. }
  178. {
  179. using II0 = int_list<>;
  180. using II1 = mp::InvertIndex_<II0>;
  181. static_assert(is_same_v<int_list<>, II1>);
  182. }
  183. // IndexIf.
  184. static_assert(mp::IndexIf<A, SamePP<int_t<0>>::type>::value==0, "5a");
  185. static_assert(mp::IndexIf<A, SamePP<int_t<2>>::type>::value==1, "5b");
  186. static_assert(mp::IndexIf<A, SamePP<int_t<3>>::type>::value==2, "5c");
  187. static_assert(mp::IndexIf<A, SamePP<int_t<9>>::type>::value==-1, "5d");
  188. // findtail.
  189. static_assert(is_same_v<mp::findtail<A, int_t<0>>, A>, "4a");
  190. static_assert(mp::check_idx<mp::findtail<A, int_t<2>>, 2, 3>::value, "4b");
  191. static_assert(mp::check_idx<mp::findtail<A, int_t<3>>, 3>::value, "4c");
  192. static_assert(mp::nilp<mp::findtail<A, int_t<4>>>, "4d");
  193. static_assert(is_same_v<mp::findtail<S3, S2BC>, tuple<S2BC>>, "4e");
  194. // reverse.
  195. static_assert(mp::check_idx<mp::reverse<A_B>, 7, 6, 5, 3, 2, 0>::value, "5a");
  196. static_assert(mp::check_idx<mp::reverse<O>>::value, "5b");
  197. static_assert(is_same_v<mp::reverse<mp::nil>, mp::nil>, "bad reverse");
  198. // drop & take
  199. static_assert(mp::check_idx<mp::drop<A, 0>, 0, 2, 3>::value, "bad 6a");
  200. static_assert(mp::check_idx<mp::drop<A, 1>, 2, 3>::value, "bad 6b");
  201. static_assert(mp::check_idx<mp::drop<A, 2>, 3>::value, "bad 6c");
  202. static_assert(mp::check_idx<mp::drop<A, 3>>::value, "bad 6d");
  203. static_assert(mp::check_idx<mp::take<A, 0>>::value, "bad 6e");
  204. static_assert(mp::check_idx<mp::take<A, 1>, 0>::value, "bad 6f");
  205. static_assert(mp::check_idx<mp::take<A, 2>, 0, 2>::value, "bad 6g");
  206. static_assert(mp::check_idx<mp::take<A, 3>, 0, 2, 3>::value, "bad 6h");
  207. // complement.
  208. {
  209. using case1 = int_list<1>;
  210. static_assert(mp::check_idx<mp::complement<case1, 0>>::value, "");
  211. static_assert(mp::check_idx<mp::complement<case1, 1>, 0>::value, "");
  212. static_assert(mp::check_idx<mp::complement<case1, 2>, 0>::value, "");
  213. static_assert(mp::check_idx<mp::complement<case1, 3>, 0, 2>::value, "");
  214. using list3 = mp::iota<3>;
  215. static_assert(mp::check_idx<mp::complement<list3, 3>>::value, "");
  216. using c36 = mp::complement<list3, 6>;
  217. static_assert(mp::check_idx<c36, 3, 4, 5>::value, "");
  218. static_assert(mp::check_idx<mp::complement<c36, 6>, 0, 1, 2>::value, "");
  219. using case0 = tuple<int_t<0>>;
  220. static_assert(mp::check_idx<mp::complement<case0, 0>>::value, "");
  221. static_assert(mp::check_idx<mp::complement<case0, 1>>::value, "");
  222. static_assert(mp::check_idx<mp::complement<case0, 2>, 1>::value, "");
  223. }
  224. // complement_sorted_list && complement_list.
  225. {
  226. #define _ ,
  227. #define CHECK_COMPLEMENT_SLIST( A, B, C ) \
  228. static_assert(mp::check_idx<mp::complement_sorted_list<int_list A , B > C >::value, "a");
  229. CHECK_COMPLEMENT_SLIST( <1>, int_list<>, )
  230. CHECK_COMPLEMENT_SLIST( <1>, int_list<0>, _ 0)
  231. CHECK_COMPLEMENT_SLIST( <1>, int_list<0 _ 1>, _ 0)
  232. CHECK_COMPLEMENT_SLIST( <1>, int_list<0 _ 1 _ 2>, _ 0 _ 2)
  233. using l2 = mp::iota<2>;
  234. CHECK_COMPLEMENT_SLIST( <0>, l2, _ 1 )
  235. CHECK_COMPLEMENT_SLIST( <1>, l2, _ 0 )
  236. CHECK_COMPLEMENT_SLIST( <>, l2, _ 0 _ 1 )
  237. using l3 = mp::iota<3>;
  238. CHECK_COMPLEMENT_SLIST( <0 _ 1>, l3, _ 2 )
  239. CHECK_COMPLEMENT_SLIST( <0 _ 2>, l3, _ 1 )
  240. CHECK_COMPLEMENT_SLIST( <1 _ 2>, l3, _ 0 )
  241. CHECK_COMPLEMENT_SLIST( <0>, l3, _ 1 _ 2 )
  242. CHECK_COMPLEMENT_SLIST( <1>, l3, _ 0 _ 2 )
  243. CHECK_COMPLEMENT_SLIST( <2>, l3, _ 0 _ 1 )
  244. CHECK_COMPLEMENT_SLIST( <>, l3, _ 0 _ 1 _ 2 )
  245. CHECK_COMPLEMENT_SLIST( <>, mp::nil, )
  246. #undef CHECK_COMPLEMENT_SLIST
  247. #undef _
  248. #define _ ,
  249. #define CHECK_COMPLEMENT_LIST( A, B, C ) \
  250. static_assert(mp::check_idx<mp::complement_list<int_list A , B > C >::value, "a");
  251. using l2 = mp::iota<2>;
  252. CHECK_COMPLEMENT_LIST( <0>, l2, _ 1 )
  253. CHECK_COMPLEMENT_LIST( <1>, l2, _ 0 )
  254. CHECK_COMPLEMENT_LIST( <>, l2, _ 0 _ 1 )
  255. using l3 = mp::iota<3>;
  256. CHECK_COMPLEMENT_LIST( <0 _ 1>, l3, _ 2 )
  257. CHECK_COMPLEMENT_LIST( <0 _ 2>, l3, _ 1 )
  258. CHECK_COMPLEMENT_LIST( <1 _ 2>, l3, _ 0 )
  259. CHECK_COMPLEMENT_LIST( <0>, l3, _ 1 _ 2 )
  260. CHECK_COMPLEMENT_LIST( <1>, l3, _ 0 _ 2 )
  261. CHECK_COMPLEMENT_LIST( <2>, l3, _ 0 _ 1 )
  262. CHECK_COMPLEMENT_LIST( <>, l3, _ 0 _ 1 _ 2 )
  263. CHECK_COMPLEMENT_LIST( <>, mp::nil, )
  264. // this must also work on unserted lists.
  265. CHECK_COMPLEMENT_LIST( <1 _ 0>, l3, _ 2 )
  266. CHECK_COMPLEMENT_LIST( <2 _ 1>, l3, _ 0 )
  267. CHECK_COMPLEMENT_LIST( <2 _ 0>, l3, _ 1 )
  268. using x3 = int_list<2, 0, 1>;
  269. CHECK_COMPLEMENT_LIST( <1 _ 0>, x3, _ 2 )
  270. CHECK_COMPLEMENT_LIST( <2 _ 0>, x3, _ 1 )
  271. CHECK_COMPLEMENT_LIST( <2 _ 1>, x3, _ 0 )
  272. #undef CHECK_COMPLEMENT_LIST
  273. #undef _
  274. }
  275. // MapCons.
  276. {
  277. using a = mp::iota<2>;
  278. using b = mp::iota<2, 1>;
  279. using mc = mp::MapCons<int_t<9>, tuple<a, b>>::type;
  280. static_assert(mp::check_idx<ref<mc, 0>, 9, 0, 1>::value, "a");
  281. static_assert(mp::check_idx<ref<mc, 1>, 9, 1, 2>::value, "b");
  282. }
  283. // Combinations.
  284. {
  285. static_assert(mp::len<mp::combinations<mp::nil, 0>> == 1, "");
  286. using l3 = mp::iota<3>;
  287. using c31 = mp::combinations<l3, 1>;
  288. using c32 = mp::combinations<l3, 2>;
  289. static_assert(mp::len<c31> == 3, "a");
  290. static_assert(mp::check_idx<ref<c31, 0>, 0>::value, "a");
  291. static_assert(mp::check_idx<ref<c31, 1>, 1>::value, "b");
  292. static_assert(mp::check_idx<ref<c31, 2>, 2>::value, "c");
  293. static_assert(mp::len<c32> == 3, "b");
  294. static_assert(mp::check_idx<ref<c32, 0>, 0, 1>::value, "d");
  295. static_assert(mp::check_idx<ref<c32, 1>, 0, 2>::value, "e");
  296. static_assert(mp::check_idx<ref<c32, 2>, 1, 2>::value, "f");
  297. using l4 = mp::iota<4>;
  298. using c40 = mp::combinations<l4, 0>;
  299. using c41 = mp::combinations<l4, 1>;
  300. using c42 = mp::combinations<l4, 2>;
  301. using c43 = mp::combinations<l4, 3>;
  302. using c44 = mp::combinations<l4, 4>;
  303. static_assert(mp::len<c40> == 1, "a");
  304. static_assert(mp::check_idx<ref<c40, 0>>::value, "a");
  305. static_assert(mp::len<c41> == 4, "b");
  306. static_assert(mp::check_idx<ref<c41, 0>, 0>::value, "b");
  307. static_assert(mp::check_idx<ref<c41, 1>, 1>::value, "b");
  308. static_assert(mp::check_idx<ref<c41, 2>, 2>::value, "b");
  309. static_assert(mp::check_idx<ref<c41, 3>, 3>::value, "b");
  310. static_assert(mp::len<c42> == 6, "c");
  311. static_assert(mp::check_idx<ref<c42, 0>, 0, 1>::value, "c");
  312. static_assert(mp::check_idx<ref<c42, 1>, 0, 2>::value, "c");
  313. static_assert(mp::check_idx<ref<c42, 2>, 0, 3>::value, "c");
  314. static_assert(mp::check_idx<ref<c42, 3>, 1, 2>::value, "c");
  315. static_assert(mp::check_idx<ref<c42, 4>, 1, 3>::value, "c");
  316. static_assert(mp::check_idx<ref<c42, 5>, 2, 3>::value, "c");
  317. static_assert(mp::len<c43> == 4, "d");
  318. static_assert(mp::check_idx<ref<c43, 0>, 0, 1, 2>::value, "d");
  319. static_assert(mp::check_idx<ref<c43, 1>, 0, 1, 3>::value, "d");
  320. static_assert(mp::check_idx<ref<c43, 2>, 0, 2, 3>::value, "d");
  321. static_assert(mp::check_idx<ref<c43, 3>, 1, 2, 3>::value, "d");
  322. static_assert(mp::len<c44> == 1, "e");
  323. static_assert(mp::check_idx<ref<c44, 0>, 0, 1, 2, 3>::value, "e");
  324. }
  325. // MapPrepend & ProductAppend.
  326. {
  327. using la = mp::iota<3>;
  328. using ca = mp::combinations<la, 1>;
  329. using lb = mp::iota<3>;
  330. using cb = mp::combinations<lb, 1>;
  331. using test0 = mp::MapPrepend<mp::nil, cb>::type;
  332. static_assert(is_same_v<test0, cb>, "");
  333. using test1 = mp::MapPrepend<la, cb>::type;
  334. static_assert(mp::len<test1> == int(mp::len<cb>), "");
  335. static_assert(mp::check_idx<ref<test1, 0>, 0, 1, 2, 0>::value, "");
  336. static_assert(mp::check_idx<ref<test1, 1>, 0, 1, 2, 1>::value, "");
  337. static_assert(mp::check_idx<ref<test1, 2>, 0, 1, 2, 2>::value, "");
  338. using test2 = mp::ProductAppend<ca, cb>::type;
  339. static_assert(mp::len<test2> == 9, "");
  340. static_assert(mp::check_idx<ref<test2, 0>, 0, 0>::value, "");
  341. static_assert(mp::check_idx<ref<test2, 1>, 0, 1>::value, "");
  342. static_assert(mp::check_idx<ref<test2, 2>, 0, 2>::value, "");
  343. static_assert(mp::check_idx<ref<test2, 3>, 1, 0>::value, "");
  344. static_assert(mp::check_idx<ref<test2, 4>, 1, 1>::value, "");
  345. static_assert(mp::check_idx<ref<test2, 5>, 1, 2>::value, "");
  346. static_assert(mp::check_idx<ref<test2, 6>, 2, 0>::value, "");
  347. static_assert(mp::check_idx<ref<test2, 7>, 2, 1>::value, "");
  348. static_assert(mp::check_idx<ref<test2, 8>, 2, 2>::value, "");
  349. }
  350. // PermutationSign.
  351. {
  352. #define _ ,
  353. #define CHECK_PERM_SIGN( A, B, C ) \
  354. static_assert(mp::PermutationSign<int_list A , int_list B >::value == C, "");
  355. CHECK_PERM_SIGN( <0 _ 1 _ 2>, <0 _ 1 _ 2>, +1 );
  356. CHECK_PERM_SIGN( <0 _ 1 _ 2>, <0 _ 2 _ 1>, -1 );
  357. CHECK_PERM_SIGN( <0 _ 1 _ 2>, <1 _ 2 _ 0>, +1 );
  358. CHECK_PERM_SIGN( <0 _ 1 _ 2>, <2 _ 1 _ 0>, -1 );
  359. CHECK_PERM_SIGN( <0 _ 1 _ 2>, <1 _ 0 _ 2>, -1 );
  360. CHECK_PERM_SIGN( <0 _ 1 _ 2>, <2 _ 0 _ 1>, +1 );
  361. // inverted.
  362. CHECK_PERM_SIGN( <0 _ 1 _ 2>, <0 _ 1 _ 2>, +1 );
  363. CHECK_PERM_SIGN( <0 _ 2 _ 1>, <0 _ 1 _ 2>, -1 );
  364. CHECK_PERM_SIGN( <1 _ 2 _ 0>, <0 _ 1 _ 2>, +1 );
  365. CHECK_PERM_SIGN( <2 _ 1 _ 0>, <0 _ 1 _ 2>, -1 );
  366. CHECK_PERM_SIGN( <1 _ 0 _ 2>, <0 _ 1 _ 2>, -1 );
  367. CHECK_PERM_SIGN( <2 _ 0 _ 1>, <0 _ 1 _ 2>, +1 );
  368. // other cases.
  369. CHECK_PERM_SIGN( <0>, <0>, +1 );
  370. CHECK_PERM_SIGN( <>, <>, +1 );
  371. CHECK_PERM_SIGN( <0>, <1>, 0 );
  372. CHECK_PERM_SIGN( <0>, <>, 0 );
  373. CHECK_PERM_SIGN( <>, <0>, 0 );
  374. #undef CHECK_PERM_SIGN
  375. #undef _
  376. }
  377. // inc
  378. {
  379. using l = int_list<7, 8, 2>;
  380. static_assert(mp::check_idx<l, 7, 8, 2>::value, "bad");
  381. static_assert(mp::check_idx<mp::inc<l, 0>, 8, 8, 2>::value, "bad");
  382. static_assert(mp::check_idx<mp::inc<l, 1>, 7, 9, 2>::value, "bad");
  383. static_assert(mp::check_idx<mp::inc<l, 2>, 7, 8, 3>::value, "bad");
  384. }
  385. // Prod & Sum
  386. {
  387. using l = int_list<3, 5, 7>;
  388. static_assert(mp::apply<mp::prod, l>::value==105, "bad");
  389. static_assert(mp::apply<mp::sum, l>::value==15, "bad");
  390. }
  391. // tuple-dynamic
  392. {
  393. using l = int_list<3, 4, 5>;
  394. tr.test_eq(0, mp::int_list_index<l>(3));
  395. tr.test_eq(1, mp::int_list_index<l>(4));
  396. tr.test_eq(2, mp::int_list_index<l>(5));
  397. tr.test_eq(-1, mp::int_list_index<l>(7));
  398. }
  399. return tr.summary();
  400. };