stream.hpp 9.1 KB

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