stream.hpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. * File stream.hpp
  3. *
  4. * Stream style functional composition
  5. *
  6. * @author Sam Jaffe
  7. *
  8. */
  9. #pragma once
  10. #include <algorithm>
  11. #include <functional>
  12. #include <iterator>
  13. #include <utility>
  14. namespace stream {
  15. template <typename T> class stream {
  16. public:
  17. virtual ~stream() = default;
  18. // template<template <class...> class C>
  19. // C<T> complete() const;
  20. };
  21. template <typename T, typename It> class iter_stream : public stream<T> {
  22. public:
  23. virtual ~iter_stream() = default;
  24. template <template <class...> class C> C<T> complete() const {
  25. C<T> out;
  26. std::copy(begin(), end(), std::back_inserter(out));
  27. return out;
  28. }
  29. typedef It const_iterator;
  30. virtual const_iterator begin() const = 0;
  31. virtual const_iterator end() const = 0;
  32. };
  33. template <typename T, template <class...> class C>
  34. class cont_stream : public iter_stream<T, typename C<T>::const_iterator> {
  35. public:
  36. typedef typename C<T>::value_type value_type;
  37. typedef iter_stream<T, typename C<T>::const_iterator> super;
  38. typedef typename super::const_iterator const_iterator;
  39. public:
  40. cont_stream(const C<T> & data) : super(), data(&data), owning(false) {}
  41. cont_stream(C<T> && data)
  42. : super(), data(new C<T>(std::forward<C<T>>(data))), owning(true) {}
  43. virtual ~cont_stream() {
  44. if (owning && data) delete data;
  45. }
  46. virtual const_iterator begin() const { return data->begin(); }
  47. virtual const_iterator end() const { return data->end(); }
  48. private:
  49. const bool owning;
  50. const C<T> * data;
  51. };
  52. template <typename InStream, typename O, typename F>
  53. struct map_stream_iterator {
  54. public:
  55. typedef typename InStream::value_type value_type;
  56. typedef value_type & reference;
  57. typedef value_type * pointer;
  58. typedef std::ptrdiff_t difference_type;
  59. typedef std::input_iterator_tag iterator_category;
  60. typedef typename InStream::const_iterator Impl;
  61. public:
  62. map_stream_iterator(Impl it, F func) : impl(it), f(func) {}
  63. O operator*() const { return f(*impl); }
  64. map_stream_iterator & operator++() {
  65. ++impl;
  66. return *this;
  67. }
  68. map_stream_iterator operator++(int) {
  69. map_stream_iterator tmp(*this);
  70. operator++();
  71. return tmp;
  72. }
  73. bool operator==(const map_stream_iterator & other) const {
  74. return impl == other.impl;
  75. }
  76. bool operator!=(const map_stream_iterator & other) const {
  77. return impl != other.impl;
  78. }
  79. private:
  80. F f;
  81. Impl impl;
  82. };
  83. template <typename O, typename I, typename InStream>
  84. class map_stream
  85. : public iter_stream<
  86. O, map_stream_iterator<InStream, O, std::function<O(I)>>> {
  87. public:
  88. typedef O value_type;
  89. typedef iter_stream<O,
  90. map_stream_iterator<InStream, O, std::function<O(I)>>>
  91. super;
  92. typedef typename super::const_iterator const_iterator;
  93. public:
  94. map_stream(const InStream & in, std::function<O(I)> func)
  95. : super(), in(in), f(func) {}
  96. virtual ~map_stream() = default;
  97. virtual const_iterator begin() const {
  98. return const_iterator(in.begin(), f);
  99. }
  100. virtual const_iterator end() const { return const_iterator(in.end(), f); }
  101. private:
  102. const InStream in;
  103. std::function<O(I)> f;
  104. };
  105. template <typename InStream> struct filter_stream_iterator {
  106. public:
  107. typedef typename InStream::value_type value_type;
  108. typedef value_type & reference;
  109. typedef value_type * pointer;
  110. typedef std::ptrdiff_t difference_type;
  111. typedef std::input_iterator_tag iterator_category;
  112. typedef typename InStream::const_iterator Impl;
  113. public:
  114. filter_stream_iterator(Impl it, Impl end,
  115. std::function<bool(value_type)> predicate)
  116. : impl(it), end(end), pred(predicate) {}
  117. value_type operator*() const { return *impl; }
  118. filter_stream_iterator & operator++() {
  119. do {
  120. ++impl;
  121. } while (impl != end && !pred(*impl));
  122. return *this;
  123. }
  124. filter_stream_iterator operator++(int) {
  125. filter_stream_iterator tmp(*this);
  126. operator++();
  127. return tmp;
  128. }
  129. bool operator==(const filter_stream_iterator & other) const {
  130. return impl == other.impl;
  131. }
  132. bool operator!=(const filter_stream_iterator & other) const {
  133. return impl != other.impl;
  134. }
  135. private:
  136. std::function<bool(value_type)> pred;
  137. Impl impl;
  138. Impl end;
  139. };
  140. template <typename T, typename InStream>
  141. class filter_stream
  142. : public iter_stream<T, filter_stream_iterator<InStream>> {
  143. public:
  144. typedef T value_type;
  145. typedef iter_stream<T, filter_stream_iterator<InStream>> super;
  146. typedef typename super::const_iterator const_iterator;
  147. public:
  148. filter_stream(const InStream & in, std::function<bool(T)> predicate)
  149. : super(), in(in), pred(predicate) {}
  150. virtual ~filter_stream() = default;
  151. virtual const_iterator begin() const {
  152. return const_iterator(in.begin(), in.end(), pred);
  153. }
  154. virtual const_iterator end() const {
  155. return const_iterator(in.end(), in.end(), pred);
  156. }
  157. private:
  158. const InStream in;
  159. std::function<bool(T)> pred;
  160. };
  161. template <typename Cons> struct cons_stream_iterator {
  162. public:
  163. typedef typename Cons::value_type InStream;
  164. typedef typename InStream::value_type value_type;
  165. typedef value_type & reference;
  166. typedef value_type * pointer;
  167. typedef std::ptrdiff_t difference_type;
  168. typedef std::input_iterator_tag iterator_category;
  169. typedef typename Cons::const_iterator ConsIter;
  170. typedef typename InStream::const_iterator StreamIter;
  171. public:
  172. cons_stream_iterator(ConsIter iter) : citer(iter) {}
  173. cons_stream_iterator & operator++() {
  174. if (scurr == send) {
  175. ++citer;
  176. scurr = citer->begin();
  177. send = citer->end();
  178. } else {
  179. ++scurr;
  180. }
  181. return *this;
  182. }
  183. cons_stream_iterator operator++(int) {
  184. cons_stream_iterator tmp(*this);
  185. operator++();
  186. return tmp;
  187. }
  188. bool operator==(const cons_stream_iterator & other) const {
  189. return citer == other.citer && scurr == other.scurr;
  190. }
  191. bool operator!=(const cons_stream_iterator & other) const {
  192. return citer != other.citer || scurr != other.scurr;
  193. }
  194. private:
  195. ConsIter citer;
  196. StreamIter scurr;
  197. StreamIter send;
  198. };
  199. template <typename T, typename InStream>
  200. class cons_stream
  201. : public iter_stream<T, cons_stream_iterator<std::vector<InStream>>> {
  202. public:
  203. typedef T value_type;
  204. typedef iter_stream<T, cons_stream_iterator<std::list<InStream>>> super;
  205. typedef typename super::const_iterator const_iterator;
  206. public:
  207. virtual ~cons_stream() = default;
  208. virtual const_iterator begin() const { return const_iterator(in.begin()); }
  209. virtual const_iterator end() const { return const_iterator(in.end()); }
  210. private:
  211. std::list<InStream> in;
  212. };
  213. template <typename GenIter, typename It> struct flatmap_stream_iterator {
  214. public:
  215. typedef typename GenIter::value_type MapStream;
  216. typedef typename It::value_type value_type;
  217. typedef value_type & reference;
  218. typedef value_type * pointer;
  219. typedef std::ptrdiff_t difference_type;
  220. typedef std::input_iterator_tag iterator_category;
  221. public:
  222. flatmap_stream_iterator(GenIter gen) : generator(gen) {}
  223. value_type operator*() {
  224. if (!mapped) {
  225. mapped = new MapStream(std::forward<MapStream>(*generator));
  226. curr = mapped->begin();
  227. end = mapped->end();
  228. }
  229. return *curr;
  230. }
  231. flatmap_stream_iterator & operator++() {
  232. ++curr;
  233. if (curr == end) {
  234. ++generator;
  235. delete mapped;
  236. mapped = nullptr;
  237. }
  238. return *this;
  239. }
  240. flatmap_stream_iterator operator++(int) {
  241. flatmap_stream_iterator tmp(*this);
  242. operator++();
  243. return tmp;
  244. }
  245. private:
  246. GenIter generator;
  247. MapStream * mapped = nullptr;
  248. It curr;
  249. It end;
  250. };
  251. template <typename O, typename I, typename InStream, typename MapStream>
  252. class flatmap_stream
  253. : public iter_stream<
  254. O, flatmap_stream_iterator<typename InStream::const_iterator,
  255. typename MapStream::const_iterator>> {};
  256. template <typename T, template <class...> class C>
  257. cont_stream<T, C> make_stream(const C<T> & data) {
  258. return cont_stream<T, C>(data);
  259. }
  260. template <typename F, typename InStream>
  261. auto map(const InStream & stream, F func) -> map_stream<
  262. decltype(func(std::declval<typename InStream::value_type>())),
  263. typename InStream::value_type, InStream> {
  264. using I = typename InStream::value_type;
  265. using O = decltype(func(std::declval<I>()));
  266. return map_stream<O, I, InStream>(stream, func);
  267. }
  268. template <typename P, typename InStream>
  269. auto filter(const InStream & stream, P predicate)
  270. -> filter_stream<typename InStream::value_type, InStream> {
  271. using T = typename InStream::value_type;
  272. return filter_stream<T, InStream>(stream, predicate);
  273. }
  274. template <typename P, typename F, typename InStream>
  275. auto map_if(const InStream & stream, P predicate, F func)
  276. -> decltype(map(std::declval<decltype(filter(stream, predicate))>(),
  277. func)) {
  278. return map(filter(stream, predicate), func);
  279. }
  280. // void flatMap(const InStream& stream, F func)
  281. template <typename F, typename InStream, typename Arg1>
  282. auto reduce(const InStream & stream, F func, Arg1 accum) -> Arg1 {
  283. std::for_each(stream.begin(), stream.end(),
  284. [&accum, func](typename InStream::value_type i) {
  285. accum = func(accum, i);
  286. });
  287. return accum;
  288. }
  289. }