fork download
  1. #include <cstddef>
  2.  
  3. template<typename... Ts> struct types {};
  4. template<typename T, typename U>
  5. struct concat;
  6. template<typename... Ts, typename... Us>
  7. struct concat< types<Ts...>, types<Us...> > {
  8. typedef types<Ts..., Us...> result;
  9. };
  10. template<typename Ts, typename Us>
  11. using Concat = typename concat<Ts, Us>::result;
  12.  
  13. template<std::size_t n, typename Ts>
  14. struct split;
  15. template<std::size_t n, typename... Ts>
  16. struct split<n, types<Ts...>> {
  17. typedef split<n/2, types<Ts...>> one;
  18. typedef split<n-n/2, typename one::right> two;
  19. typedef Concat< typename one::left, typename two::left > left;
  20. typedef typename two::right right;
  21. };
  22. template<typename... Ts>
  23. struct split<0, types<Ts...>> {
  24. typedef types<> left;
  25. typedef types<Ts...> right;
  26. };
  27. template<typename T, typename... Ts>
  28. struct split<1, types<T, Ts...>> {
  29. typedef types<T> left;
  30. typedef types<Ts...> right;
  31. };
  32. template<template<typename, typename>class OP, typename State, typename Ts>
  33. struct fold_helper;
  34. template<template<typename, typename>class OP, typename State, typename... Ts>
  35. struct fold_helper<OP, State, types<Ts...>> {
  36. private:
  37. typedef split<sizeof...(Ts)/2, types<Ts...>> parts;
  38. typedef typename parts::left left;
  39. typedef typename parts::right right;
  40. typedef typename fold_helper<OP, State, left>::result left_result;
  41. public:
  42. typedef typename fold_helper<OP, left_result, right>::result result;
  43. };
  44. template<template<typename, typename>class OP, typename State>
  45. struct fold_helper<OP, State, types<>> {
  46. typedef State result;
  47. };
  48. template<template<typename, typename>class OP, typename State, typename T>
  49. struct fold_helper<OP, State, types<T>> {
  50. typedef typename OP<State,T>::type result;
  51. };
  52. template<template<typename, typename>class OP, typename State, typename... Ts>
  53. struct fold {
  54. typedef typename fold_helper<OP, State, types<Ts...>>::result type;
  55. };
  56. template<template<typename, typename>class OP, typename State, typename... Ts>
  57. using Fold = typename fold<OP, State, Ts...>::type;
  58.  
  59. template<typename left, typename right>
  60. struct op_test {
  61. typedef int type;
  62. };
  63.  
  64. template<int n>
  65. struct counter {enum{value=n};};
  66.  
  67. template<typename left, typename right>
  68. struct sum;
  69. template<int a, int b>
  70. struct sum<counter<a>, counter<b>> {
  71. typedef counter<a+b> type;
  72. };
  73.  
  74. #include <iostream>
  75.  
  76. int main() {
  77. Fold< op_test, double, int, char, char*, int* > foo = 8;
  78. std::cout << Fold<sum, counter<0>, counter<5>, counter<9>, counter<-7>>::value << "\n";
  79. }
  80.  
  81.  
Success #stdin #stdout 0s 3340KB
stdin
Standard input is empty
stdout
7