stream.hpp 9.1 KB

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