Guest User

Untitled

a guest
Jun 22nd, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.70 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <iostream>
  4. #include <exception>
  5. #include <functional>
  6. #include <vector>
  7. #include <cassert>
  8. #include <cstdint>
  9. #include <type_traits>
  10.  
  11. using namespace std;
  12.  
  13. // Used for decltype(lambda(args ...)).
  14. template<class A> A undefined() {
  15. throw exception();
  16. }
  17.  
  18. template<template<class T> class F, class T> class remove_outer { };
  19. template<template<class T> class F, class A> class remove_outer<F, F<A>> {
  20. public:
  21. typedef A type;
  22. };
  23.  
  24. class Source {
  25. public:
  26. virtual uint64_t readBits(int bits) = 0;
  27. };
  28.  
  29. template<class A> class Gen {
  30. public:
  31. function<A(Source&)> run;
  32.  
  33. template<class F> Gen(const F& f)
  34. : run(std::move(f)) { }
  35.  
  36. template<class F> auto map (const F& f) const
  37. -> Gen<decltype(f(undefined<A>()))> {
  38. Gen<A> lhs = *this;
  39. return Gen<decltype(f(undefined<A>()))>([lhs, f] (Source& s) {
  40. const auto a = lhs.run(s);
  41. return f(a);
  42. });
  43. }
  44.  
  45. // LOL, this signature.
  46. template<class F> auto flatMap (const F& f) const
  47. -> Gen<typename remove_outer<Gen, decltype(f(undefined<A>()))>::type> {
  48. Gen<A> lhs = *this;
  49. typedef typename remove_outer<Gen, decltype(f(undefined<A>()))>::type Result;
  50.  
  51. return Gen<Result>([lhs, f] (Source& s) {
  52. const auto a = lhs.run(s);
  53. const auto gb = f(a);
  54. return gb.run(s);
  55. });
  56. }
  57.  
  58. template<class B> Gen<B*> widen() const {
  59. return map([] (A a) -> B* {
  60. return a;
  61. });
  62. }
  63. };
  64.  
  65. template<class A, class B> Gen<pair<A, B>> operator * (const Gen<A>& lhs, const Gen<B>& rhs) {
  66. return Gen<pair<A, B>>([lhs, rhs] (Source& s) -> pair<A, B> {
  67. const auto a = lhs.run(s);
  68. const auto b = rhs.run(s);
  69. return make_pair(a, b);
  70. });
  71. }
  72.  
  73. template<class F, class A, class B>
  74. auto mapN (const F& f, const Gen<A>& genA, const Gen<B>& genB) -> Gen<typename result_of<decltype(f)>::type> {
  75. return (genA * genB).map([f] (const pair<A, B>& p) {
  76. return f(p.first, p.second);
  77. });
  78. }
  79. template<class F, class A, class B, class C>
  80. auto mapN (const F& f, const Gen<A>& genA, const Gen<B>& genB, const Gen<C>& genC) -> Gen<typename result_of<decltype(f)>::type> {
  81. return (genA * genB * genC).map([f] (const pair<pair<A, B>, C>& p) {
  82. return f(p.first.first, p.first.second, p.second);
  83. });
  84. }
  85.  
  86. namespace gen {
  87. template<class A> Gen<A> pure(const A& a) {
  88. return Gen<A>([a] (Source& s) { return a; });
  89. }
  90.  
  91. template<class F> auto delay(const F& suspension)
  92. -> Gen<typename remove_outer<Gen, decltype(suspension())>::type> {
  93. typedef typename remove_outer<Gen, decltype(suspension())>::type Result;
  94. return Gen<Result>([suspension] (Source& s) {
  95. return suspension().run(s);
  96. });
  97. }
  98.  
  99. Gen<int> int_ = Gen<int>([] (Source& s) { return (int) s.readBits(32); });
  100.  
  101. Gen<int> intBits(int bits) {
  102. assert(bits >= 1);
  103. assert(bits <= 32);
  104.  
  105. return Gen<int>([bits] (Source& s) { return (int) s.readBits(bits); });
  106. }
  107.  
  108. template<class A> Gen<vector<A>> vecN(const Gen<A>& ga, size_t size) {
  109. return Gen<vector<A>>([ga, size] (Source& s) {
  110. std::cerr << size << std::endl;
  111. vector<A> result;
  112. result.reserve(size);
  113. for (size_t i = 0; i < size; i++) {
  114. result.push_back(ga.run(s));
  115. }
  116. return result;
  117. });
  118. }
  119.  
  120. template<class A> Gen<vector<A>> vec(const Gen<A>& ga) {
  121. // For illustrative purposes limit the size to 255.
  122. return intBits(8).flatMap([ga] (int size) -> Gen<vector<A>> { return vecN(ga, size); });
  123. }
  124.  
  125. Gen<bool> bool_ = Gen<bool>([] (Source& s) { return s.readBits(1) == 1; });
  126.  
  127. template<class T> class type {
  128. public:
  129. template<class A, class B> static Gen<T> of(const Gen<A>& genA, const Gen<B>& genB) {
  130. return (genA * genB).map([] (const pair<A, B>& p) {
  131. return T(p.first, p.second);
  132. });
  133. }
  134. template<class A, class B, class C> static Gen<T> of(const Gen<A>& genA, const Gen<B>& genB, const Gen<C>& genC) {
  135. return (genA * genB * genC).map([] (const pair<pair<A, B>, C>& p) {
  136. return T(p.first.first, p.first.second, p.second);
  137. });
  138. }
  139. };
  140.  
  141. template<class T> class new_ {
  142. public:
  143. template<class A, class B> static Gen<T*> of(const Gen<A>& genA, const Gen<B>& genB) {
  144. return (genA * genB).map([] (const pair<A, B>& p) {
  145. return new T(p.first, p.second);
  146. });
  147. }
  148. template<class A, class B, class C> static Gen<T*> of(const Gen<A>& genA, const Gen<B>& genB, const Gen<C>& genC) {
  149. return (genA * genB * genC).map([] (const pair<pair<A, B>, C>& p) {
  150. return new T(p.first.first, p.first.second, p.second);
  151. });
  152. }
  153. };
  154. };
  155.  
  156. // For illustration purposes.
  157. class RandomSource : public Source {
  158. public:
  159. virtual uint64_t readBits(int bits) {
  160. uint64_t mask = (((uint64_t) 1) << bits) - 1;
  161. uint64_t value = (((uint64_t) rand()) << 32) | ((uint64_t) rand());
  162. return value & mask;
  163. }
  164. };
Add Comment
Please, Sign In to add comment