Advertisement
Guest User

MoreInsanity

a guest
Feb 18th, 2014
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.05 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5.  
  6. namespace tcalc {
  7.  
  8. template< typename T, T v = T() >
  9. struct Value
  10. {
  11.     enum { val = v };
  12.     typedef T value_type;
  13. };
  14.  
  15. template< typename T, T v >
  16. struct Negate
  17. {
  18.     enum { val = -v };
  19. };
  20.  
  21. // comparision
  22. template< class V1, class V2>
  23. struct Less
  24. {
  25.     enum { val = V1::val < V2::val };
  26. };
  27.  
  28. template< class V1, class V2>
  29. struct LessOrEqual
  30. {
  31.     enum { val = V1::val <= V2::val };
  32. };
  33.  
  34. template< class V1, class V2 >
  35. struct Equal
  36. {
  37.     enum { val = V1::val == V2::val };
  38. };
  39.  
  40. template< class V1, class V2 >
  41. struct Greater
  42. {
  43.     enum { val = V1::val > V2::val };
  44. };
  45.  
  46. template< class V1, class V2 >
  47. struct GreaterOrEqual
  48. {
  49.     enum { val = V1::val >= V2::val };
  50. };
  51.  
  52. template< class V1, class V2 >
  53. class Min
  54. {
  55.     template< class Vi1, class Vi2, int lesser >
  56.     struct MinR;
  57.  
  58.     template< class Vi1, class Vi2 >
  59.     struct MinR< Vi1, Vi2, 1 >
  60.     {
  61.         typedef Vi1 NextType;
  62.     };
  63.  
  64.     template< class Vi1, class Vi2 >
  65.     struct MinR< Vi1, Vi2, 0 >
  66.     {
  67.         typedef Vi2 NextType;
  68.     };
  69.  
  70. public:
  71.     typedef typename MinR< V1, V2, Less< V1, V2 >::val >::NextType NextType;
  72. };
  73.  
  74. template< class V1, class V2 >
  75. class Max
  76. {
  77.     template< class Vi1, class Vi2, int lesser >
  78.     struct MaxR;
  79.  
  80.     template< class Vi1, class Vi2 >
  81.     struct MaxR< Vi1, Vi2, 1 >
  82.     {
  83.         typedef Vi2 NextType;
  84.     };
  85.  
  86.     template< class Vi1, class Vi2 >
  87.     struct MaxR< Vi1, Vi2, 0 >
  88.     {
  89.         typedef Vi1 NextType;
  90.     };
  91.  
  92. public:
  93.     typedef typename MaxR< V1, V2, Less< V1, V2 >::val >::NextType NextType;
  94. };
  95.  
  96. // arithmetic
  97. template< class V1, class V2 >
  98. struct Add
  99. {
  100.     enum { val = V1::val + V2::val };
  101. };
  102.  
  103. template< class V1, class V2 >
  104. struct Sub
  105. {
  106.     enum { val = V1::val - V2::val };
  107. };
  108.  
  109. template< class V1, class V2 >
  110. struct Mul
  111. {
  112.     enum { val = V1::val * V2::val };
  113. };
  114.  
  115. template< class V1, class V2 >
  116. struct Div
  117. {
  118.     enum { val = V1::val / V2::val };
  119. };
  120.  
  121. template< class V, unsigned p >
  122. struct Power
  123. {
  124.     enum { val = Power< V, p - 1 >::val * V::val };
  125. };
  126.  
  127. template< class V >
  128. struct Power< V, 1 >
  129. {
  130.     enum { val = V::val };
  131. };
  132.  
  133. template< class V >
  134. struct Power< V, 0 >
  135. {
  136.     enum { val = 1 };
  137. };
  138.  
  139. // special-purpose
  140. template< unsigned v >
  141. struct Factorial
  142. {
  143.     enum { val = Factorial< v - 1 >::val * v };
  144. };
  145.  
  146. template<>
  147. struct Factorial<0>
  148. {
  149.     enum { val = 1 };
  150. };
  151.  
  152. ////////////////////////////////
  153. namespace container {
  154.  
  155. namespace list {
  156.  
  157. struct NullItem
  158. {
  159.     enum { val };
  160.     static void Print() { cout << endl; }
  161. };
  162.  
  163. template< typename V, typename L >
  164. struct List
  165. {
  166.     enum { val = V::val };
  167.     typedef V value_type;
  168.  
  169.     static void Print()
  170.     {
  171.         cout << val << ", ";
  172.         L::Print();
  173.     }
  174. };
  175.  
  176. template< class List > struct ListLength;
  177.  
  178. template<>
  179. struct ListLength< NullItem >
  180. {
  181.     enum { val = 0 };
  182. };
  183.  
  184. template< class V, class L >
  185. struct ListLength< List< V, L > >
  186. {
  187.     enum { val = 1 + ListLength<L>::val };
  188. };
  189.  
  190. template< class List > struct Next;
  191.  
  192. template< class V, class L >
  193. struct Next< List< V, L > >
  194. {
  195.     typedef L NextType;
  196. };
  197.  
  198. template< class L, int step >
  199. class Advance
  200. {
  201.     typedef typename Next< L >::NextType Forward;
  202. public:
  203.     typedef typename Advance< Forward, step - 1 >::NextType NextType;
  204. };
  205.  
  206. template< class L >
  207. class Advance< L, 1 >
  208. {
  209. public:
  210.     typedef typename Next< L >::NextType NextType;
  211. };
  212.  
  213. template< class L >
  214. class Advance< L, 0 >
  215. {
  216. public:
  217.     typedef L NextType;
  218. };
  219.  
  220. template< class L, int length = ListLength< L >::val >
  221. class Reverse
  222. {
  223.     typedef typename Advance< L, length - 1 >::NextType::value_type Last;
  224. public:
  225.     typedef List< Last, typename Reverse< L, length - 1 >::NextType > NextType;
  226. };
  227.  
  228. template< class L >
  229. class Reverse< L, 1 >
  230. {
  231.     typedef typename L::value_type First;
  232. public:
  233.     typedef List< First, NullItem > NextType;
  234. };
  235.  
  236. template< class L, int length = ListLength< L >::val >
  237. class PopBack
  238. {
  239.     typedef typename Next< L >::NextType Remaining;
  240. public:
  241.     typedef List< typename L::value_type, typename PopBack< Remaining, length - 1 >::NextType > NextType;
  242. };
  243.  
  244. template< class L>
  245. class PopBack< L, 2 >
  246. {
  247. public:
  248.     typedef List< typename L::value_type, NullItem > NextType;
  249. };
  250.  
  251. template< class L >
  252. struct PopFront
  253. {
  254.     typedef typename Next< L >::NextType NextType;
  255. };
  256.  
  257. template< class V, class L >
  258. class PushBack
  259. {
  260.     typedef typename Reverse< L >::NextType Reversed;
  261.     typedef List< V, Reversed > ReversedA;
  262. public:
  263.     typedef typename Reverse< ReversedA >::NextType NextType;
  264. };
  265.  
  266. template< unsigned n, int initial = 0, int until = n + initial, int i = initial, class G = NullItem >
  267. class Generate
  268. {
  269.     typedef List< Value< int, i >, G > NewList;
  270. public:
  271.     typedef typename Generate< n, initial, until, i + 1, NewList >::NextType NextType;
  272. };
  273.  
  274. template< unsigned n, int initial, int until, class G >
  275. class Generate<n, initial, until, until, G>
  276. {
  277. public:
  278.     typedef G NextType;
  279. };
  280.  
  281. template< class L1, class L2 >
  282. class Merge
  283. {
  284.     typedef typename PushBack< typename L2::value_type, L1 >::NextType MergedWithFirst;
  285.     typedef typename Next< L2 >::NextType L2_NextType;
  286. public:
  287.     typedef typename Merge< MergedWithFirst, L2_NextType >::NextType NextType;
  288. };
  289.  
  290. template< class L1 >
  291. class Merge< L1, NullItem >
  292. {
  293. public:
  294.     typedef L1 NextType;
  295. };
  296.  
  297. template< class L, unsigned n, unsigned i = 0 >
  298. class First
  299. {
  300.     typedef List< typename L::value_type, NullItem > Trivial;
  301.  
  302.     template< class Li, unsigned ni, class Ri, unsigned ii >
  303.     class FirstR
  304.     {
  305.         enum { index = ni - ii };
  306.         typedef typename PushBack< typename Advance< Li, index >::NextType, Ri >::NextType Ls;
  307.     public:
  308.         typedef typename FirstR< Li, ni, Ls, ii - 1 >::NextType NextType;
  309.     };
  310.  
  311.     template< class Li, unsigned ni, class Ri >
  312.     class FirstR< Li, ni, Ri, 0 >
  313.     {
  314.     public:
  315.         typedef Ri NextType;
  316.     };
  317.  
  318. public:
  319.     typedef typename FirstR< L, n, Trivial, n - 1 >::NextType NextType;
  320. };
  321.  
  322. template< class L, class Item, unsigned index, unsigned length = ListLength< L >::val >
  323. class InsertAt
  324. {
  325.     typedef typename First<L, index>::NextType L1;
  326.     typedef typename Advance<L, index>::NextType L2;
  327.     typedef typename PushBack< Item, L1 >::NextType L1PlusItem;
  328. public:
  329.     typedef typename Merge< L1PlusItem, L2 >::NextType NextType;
  330. };
  331.  
  332. template< class L, class Item, unsigned index >
  333. class InsertAt< L, Item, index, index >
  334. {
  335. public:
  336.     typedef typename PushBack< Item, L >::NextType NextType;
  337. };
  338.  
  339. template< class L, class Item, unsigned length >
  340. class InsertAt< L, Item, 0, length >
  341. {
  342. public:
  343.     typedef List< Item, L > NextType;
  344. };
  345.  
  346. template< class L, unsigned index >
  347. class EraseByIndex
  348. {
  349.     typedef typename First<L, index>::NextType L1;
  350.     typedef typename Advance<L, index + 1>::NextType L2;
  351. public:
  352.     typedef typename Merge< L1, L2 >::NextType NextType;
  353. };
  354.  
  355. template< class L >
  356. class EraseByIndex< L, 0 >
  357. {
  358. public:
  359.     typedef typename Next<L>::NextType NextType;
  360. };
  361.  
  362. template< class Ls, class it >
  363. class Search
  364. {
  365.     template< class L, class item, unsigned i, int eq >
  366.     class SearchR;
  367.  
  368.     template< class L, class item, unsigned i >
  369.     class SearchR< L, item, i, 1 >
  370.     {
  371.     public:
  372.         enum { val = i };
  373.     };
  374.  
  375.     template< class item, unsigned i >
  376.     class SearchR< NullItem, item, i, 1 >
  377.     {
  378.     public:
  379.         enum { val = i };
  380.     };
  381.  
  382.     template< class item, unsigned i >
  383.     class SearchR< NullItem, item, i, 0 >
  384.     {
  385.     public:
  386.         enum { val = -1 };
  387.     };
  388.  
  389.     template< class L, class item, unsigned i >
  390.     class SearchR< L, item, i, 0 >
  391.     {
  392.         typedef typename Next<L>::NextType NextType;
  393.     public:
  394.         enum { val = SearchR< NextType, item, i + 1, Equal< NextType, item >::val >::val };
  395.     };
  396.  
  397. public:
  398.     enum { val = SearchR< Ls, it, 0, Equal< Ls, it >::val >::val };
  399. };
  400.  
  401. template< class L, class Min = L >
  402. class FindMinimum
  403. {
  404.     typedef typename Next<L>::NextType Forward;
  405.     typedef typename tcalc::Min< L, Min >::NextType CurrentMin;
  406. public:
  407.     typedef typename FindMinimum< Forward, CurrentMin >::NextType NextType;
  408. };
  409.  
  410. template< class Min >
  411. class FindMinimum< NullItem, Min >
  412. {
  413. public:
  414.     typedef Min NextType;
  415. };
  416.  
  417. template< class Ls, class it >
  418. class LowerBound
  419. {
  420.     template< class L, class item, unsigned i, int eq >
  421.     class LowerR;
  422.  
  423.     template< class L, class item, unsigned i >
  424.     class LowerR< L, item, i, 1 >
  425.     {
  426.     public:
  427.         enum { val = i };
  428.     };
  429.  
  430.     template< class item, unsigned i >
  431.     class LowerR< NullItem, item, i, 1 >
  432.     {
  433.     public:
  434.         enum { val = i };
  435.     };
  436.  
  437.     template< class item, unsigned i >
  438.     class LowerR< NullItem, item, i, 0 >
  439.     {
  440.     public:
  441.         enum { val = i };
  442.     };
  443.  
  444.     template< class L, class item, unsigned i >
  445.     class LowerR< L, item, i, 0 >
  446.     {
  447.         typedef typename Next<L>::NextType NextType;
  448.     public:
  449.         enum { val = LowerR< NextType, item, i + 1, GreaterOrEqual< NextType, item >::val >::val };
  450.     };
  451.  
  452. public:
  453.     enum { val = LowerR< Ls, it, 0, GreaterOrEqual< Ls, it >::val >::val };
  454. };
  455.  
  456.  
  457. template< class L1, class L2 >
  458. class MergeSorted
  459. {
  460.     typedef typename FindMinimum< L2 >::NextType E;
  461.     typedef Search< L2, E > Found;
  462.     typedef typename EraseByIndex< L2, Found::val >::NextType L2MinusMin;
  463.  
  464.     typedef LowerBound< L1, E > LB;
  465.     typedef typename InsertAt< L1, E, LB::val >::NextType L1PlusMin;
  466. public:
  467.     typedef typename MergeSorted< L1PlusMin, L2MinusMin >::NextType NextType;
  468. };
  469.  
  470. template< class L1 >
  471. class MergeSorted< L1, NullItem >
  472. {
  473. public:
  474.     typedef L1 NextType;
  475. };
  476.  
  477. template< class L, unsigned length = ListLength< L >::val >
  478. class MergeSort
  479. {
  480.     typedef ListLength< L > Length;
  481.     typedef typename First< L, Length::val / 2 >::NextType L1;
  482.     typedef typename Advance< L, Length::val / 2 >::NextType L2;
  483.  
  484.     typedef typename MergeSort< L1 >::NextType L1_sorted;
  485.     typedef typename MergeSort< L2 >::NextType L2_sorted;
  486. public:
  487.     typedef typename MergeSorted< L1_sorted, L2_sorted >::NextType NextType;
  488. };
  489.  
  490. template< class L >
  491. class MergeSort< L, 2 >
  492. {
  493.     typedef L E1;
  494.     typedef typename Next<L>::NextType E2;
  495.  
  496.     typedef typename Min<E1, E2>::NextType R1;
  497.     typedef typename Max<E1, E2>::NextType R2;
  498. public:
  499.     typedef List< Value< int, R1::val >, List< Value< int, R2::val >, NullItem > > NextType; // TODO: int
  500. };
  501.  
  502. template< class L >
  503. class MergeSort< L, 1 >
  504. {
  505. public:
  506.     typedef L NextType;
  507. };
  508.  
  509. } // namespace list
  510.  
  511. } // namespace container
  512.  
  513. } // namespace tcalc
  514.  
  515.  
  516. int main()
  517. {
  518.     using namespace tcalc;
  519.     using namespace tcalc::container::list;
  520.  
  521.     static const int NUM_ITEMS = 7;
  522.     typedef typename Generate< NUM_ITEMS >::NextType FirstList;
  523.     typedef typename Generate< NUM_ITEMS, NUM_ITEMS / 2 >::NextType SecondList;
  524.  
  525.     typedef typename Merge< FirstList, SecondList >::NextType M;
  526.     typedef typename MergeSort< M >::NextType Sorted;
  527.     Sorted::Print();
  528.  
  529.     return 0;
  530. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement