test-tuplelist.C 19 KB

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