fork download
  1. #include <iostream>
  2.  
  3. #pragma mark - Tape
  4.  
  5. constexpr int Blank = -1;
  6.  
  7. template<int... xs>
  8. class Tape {
  9. public:
  10. using type = Tape<xs...>;
  11. constexpr static int length = sizeof...(xs);
  12. };
  13.  
  14. #pragma mark - Print
  15.  
  16. template<class T>
  17. void print(T);
  18.  
  19. template<>
  20. void print(Tape<>) {
  21. std::cout << std::endl;
  22. }
  23.  
  24. template<int x, int... xs>
  25. void print(Tape<x, xs...>) {
  26. if (x == Blank) {
  27. std::cout << "_ ";
  28. } else {
  29. std::cout << x << " ";
  30. }
  31. print(Tape<xs...>());
  32. }
  33.  
  34. #pragma mark - Concatenate
  35.  
  36. template<class, class>
  37. class Concatenate;
  38.  
  39. template<int... xs, int... ys>
  40. class Concatenate<Tape<xs...>, Tape<ys...>> {
  41. public:
  42. using type = Tape<xs..., ys...>;
  43. };
  44.  
  45. #pragma mark - Invert
  46.  
  47. template<class>
  48. class Invert;
  49.  
  50. template<>
  51. class Invert<Tape<>> {
  52. public:
  53. using type = Tape<>;
  54. };
  55.  
  56. template<int x, int... xs>
  57. class Invert<Tape<x, xs...>> {
  58. public:
  59. using type = typename Concatenate<
  60. typename Invert<Tape<xs...>>::type,
  61. Tape<x>
  62. >::type;
  63. };
  64.  
  65. int main() {
  66. using tapeA = Tape<1, 2, 3>;
  67. using tapeB = Tape<4, 5, 6>;
  68. using tapeAB = typename Concatenate<tapeA, tapeB>::type;
  69. print(tapeAB());
  70.  
  71. using tapeC = typename Invert<tapeAB>::type;
  72. print(tapeC());
  73.  
  74. return 0;
  75. }
Success #stdin #stdout 0s 3412KB
stdin
Standard input is empty
stdout
1 2 3 4 5 6 
6 5 4 3 2 1