|
|
@@ -1,344 +0,0 @@
|
|
|
-/*
|
|
|
- * File stream.hpp
|
|
|
- *
|
|
|
- * Stream style functional composition
|
|
|
- *
|
|
|
- * @author Sam Jaffe
|
|
|
- *
|
|
|
- */
|
|
|
-
|
|
|
-#pragma once
|
|
|
-
|
|
|
-#include <algorithm>
|
|
|
-#include <functional>
|
|
|
-#include <iterator>
|
|
|
-#include <utility>
|
|
|
-
|
|
|
-namespace stream {
|
|
|
-
|
|
|
- template <typename T> class stream {
|
|
|
- public:
|
|
|
- virtual ~stream() = default;
|
|
|
- // template<template <class...> class C>
|
|
|
- // C<T> complete() const;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename T, typename It> class iter_stream : public stream<T> {
|
|
|
- public:
|
|
|
- virtual ~iter_stream() = default;
|
|
|
- template <template <class...> class C> C<T> complete() const {
|
|
|
- C<T> out;
|
|
|
- std::copy(begin(), end(), std::back_inserter(out));
|
|
|
- return out;
|
|
|
- }
|
|
|
- typedef It const_iterator;
|
|
|
- virtual const_iterator begin() const = 0;
|
|
|
- virtual const_iterator end() const = 0;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename T, template <class...> class C>
|
|
|
- class cont_stream : public iter_stream<T, typename C<T>::const_iterator> {
|
|
|
- public:
|
|
|
- typedef typename C<T>::value_type value_type;
|
|
|
- typedef iter_stream<T, typename C<T>::const_iterator> super;
|
|
|
- typedef typename super::const_iterator const_iterator;
|
|
|
-
|
|
|
- public:
|
|
|
- cont_stream(const C<T> & data) : super(), data(&data), owning(false) {}
|
|
|
- cont_stream(C<T> && data)
|
|
|
- : super(), data(new C<T>(std::forward<C<T>>(data))), owning(true) {}
|
|
|
- virtual ~cont_stream() {
|
|
|
- if (owning && data) delete data;
|
|
|
- }
|
|
|
- virtual const_iterator begin() const { return data->begin(); }
|
|
|
- virtual const_iterator end() const { return data->end(); }
|
|
|
-
|
|
|
- private:
|
|
|
- const bool owning;
|
|
|
- const C<T> * data;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename InStream, typename O, typename F>
|
|
|
- struct map_stream_iterator {
|
|
|
- public:
|
|
|
- typedef typename InStream::value_type value_type;
|
|
|
- typedef value_type & reference;
|
|
|
- typedef value_type * pointer;
|
|
|
- typedef std::ptrdiff_t difference_type;
|
|
|
- typedef std::input_iterator_tag iterator_category;
|
|
|
- typedef typename InStream::const_iterator Impl;
|
|
|
-
|
|
|
- public:
|
|
|
- map_stream_iterator(Impl it, F func) : impl(it), f(func) {}
|
|
|
-
|
|
|
- O operator*() const { return f(*impl); }
|
|
|
-
|
|
|
- map_stream_iterator & operator++() {
|
|
|
- ++impl;
|
|
|
- return *this;
|
|
|
- }
|
|
|
-
|
|
|
- map_stream_iterator operator++(int) {
|
|
|
- map_stream_iterator tmp(*this);
|
|
|
- operator++();
|
|
|
- return tmp;
|
|
|
- }
|
|
|
-
|
|
|
- bool operator==(const map_stream_iterator & other) const {
|
|
|
- return impl == other.impl;
|
|
|
- }
|
|
|
-
|
|
|
- bool operator!=(const map_stream_iterator & other) const {
|
|
|
- return impl != other.impl;
|
|
|
- }
|
|
|
-
|
|
|
- private:
|
|
|
- F f;
|
|
|
- Impl impl;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename O, typename I, typename InStream>
|
|
|
- class map_stream
|
|
|
- : public iter_stream<
|
|
|
- O, map_stream_iterator<InStream, O, std::function<O(I)>>> {
|
|
|
- public:
|
|
|
- typedef O value_type;
|
|
|
- typedef iter_stream<O,
|
|
|
- map_stream_iterator<InStream, O, std::function<O(I)>>>
|
|
|
- super;
|
|
|
- typedef typename super::const_iterator const_iterator;
|
|
|
-
|
|
|
- public:
|
|
|
- map_stream(const InStream & in, std::function<O(I)> func)
|
|
|
- : super(), in(in), f(func) {}
|
|
|
- virtual ~map_stream() = default;
|
|
|
- virtual const_iterator begin() const {
|
|
|
- return const_iterator(in.begin(), f);
|
|
|
- }
|
|
|
- virtual const_iterator end() const { return const_iterator(in.end(), f); }
|
|
|
-
|
|
|
- private:
|
|
|
- const InStream in;
|
|
|
- std::function<O(I)> f;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename InStream> struct filter_stream_iterator {
|
|
|
- public:
|
|
|
- typedef typename InStream::value_type value_type;
|
|
|
- typedef value_type & reference;
|
|
|
- typedef value_type * pointer;
|
|
|
- typedef std::ptrdiff_t difference_type;
|
|
|
- typedef std::input_iterator_tag iterator_category;
|
|
|
- typedef typename InStream::const_iterator Impl;
|
|
|
-
|
|
|
- public:
|
|
|
- filter_stream_iterator(Impl it, Impl end,
|
|
|
- std::function<bool(value_type)> predicate)
|
|
|
- : impl(it), end(end), pred(predicate) {}
|
|
|
-
|
|
|
- value_type operator*() const { return *impl; }
|
|
|
-
|
|
|
- filter_stream_iterator & operator++() {
|
|
|
- do {
|
|
|
- ++impl;
|
|
|
- } while (impl != end && !pred(*impl));
|
|
|
- return *this;
|
|
|
- }
|
|
|
-
|
|
|
- filter_stream_iterator operator++(int) {
|
|
|
- filter_stream_iterator tmp(*this);
|
|
|
- operator++();
|
|
|
- return tmp;
|
|
|
- }
|
|
|
-
|
|
|
- bool operator==(const filter_stream_iterator & other) const {
|
|
|
- return impl == other.impl;
|
|
|
- }
|
|
|
-
|
|
|
- bool operator!=(const filter_stream_iterator & other) const {
|
|
|
- return impl != other.impl;
|
|
|
- }
|
|
|
-
|
|
|
- private:
|
|
|
- std::function<bool(value_type)> pred;
|
|
|
- Impl impl;
|
|
|
- Impl end;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename T, typename InStream>
|
|
|
- class filter_stream
|
|
|
- : public iter_stream<T, filter_stream_iterator<InStream>> {
|
|
|
- public:
|
|
|
- typedef T value_type;
|
|
|
- typedef iter_stream<T, filter_stream_iterator<InStream>> super;
|
|
|
- typedef typename super::const_iterator const_iterator;
|
|
|
-
|
|
|
- public:
|
|
|
- filter_stream(const InStream & in, std::function<bool(T)> predicate)
|
|
|
- : super(), in(in), pred(predicate) {}
|
|
|
- virtual ~filter_stream() = default;
|
|
|
- virtual const_iterator begin() const {
|
|
|
- return const_iterator(in.begin(), in.end(), pred);
|
|
|
- }
|
|
|
- virtual const_iterator end() const {
|
|
|
- return const_iterator(in.end(), in.end(), pred);
|
|
|
- }
|
|
|
-
|
|
|
- private:
|
|
|
- const InStream in;
|
|
|
- std::function<bool(T)> pred;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename Cons> struct cons_stream_iterator {
|
|
|
- public:
|
|
|
- typedef typename Cons::value_type InStream;
|
|
|
- typedef typename InStream::value_type value_type;
|
|
|
- typedef value_type & reference;
|
|
|
- typedef value_type * pointer;
|
|
|
- typedef std::ptrdiff_t difference_type;
|
|
|
- typedef std::input_iterator_tag iterator_category;
|
|
|
-
|
|
|
- typedef typename Cons::const_iterator ConsIter;
|
|
|
- typedef typename InStream::const_iterator StreamIter;
|
|
|
-
|
|
|
- public:
|
|
|
- cons_stream_iterator(ConsIter iter) : citer(iter) {}
|
|
|
-
|
|
|
- cons_stream_iterator & operator++() {
|
|
|
- if (scurr == send) {
|
|
|
- ++citer;
|
|
|
- scurr = citer->begin();
|
|
|
- send = citer->end();
|
|
|
- } else {
|
|
|
- ++scurr;
|
|
|
- }
|
|
|
- return *this;
|
|
|
- }
|
|
|
-
|
|
|
- cons_stream_iterator operator++(int) {
|
|
|
- cons_stream_iterator tmp(*this);
|
|
|
- operator++();
|
|
|
- return tmp;
|
|
|
- }
|
|
|
-
|
|
|
- bool operator==(const cons_stream_iterator & other) const {
|
|
|
- return citer == other.citer && scurr == other.scurr;
|
|
|
- }
|
|
|
-
|
|
|
- bool operator!=(const cons_stream_iterator & other) const {
|
|
|
- return citer != other.citer || scurr != other.scurr;
|
|
|
- }
|
|
|
-
|
|
|
- private:
|
|
|
- ConsIter citer;
|
|
|
- StreamIter scurr;
|
|
|
- StreamIter send;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename T, typename InStream>
|
|
|
- class cons_stream
|
|
|
- : public iter_stream<T, cons_stream_iterator<std::vector<InStream>>> {
|
|
|
- public:
|
|
|
- typedef T value_type;
|
|
|
- typedef iter_stream<T, cons_stream_iterator<std::list<InStream>>> super;
|
|
|
- typedef typename super::const_iterator const_iterator;
|
|
|
-
|
|
|
- public:
|
|
|
- virtual ~cons_stream() = default;
|
|
|
- virtual const_iterator begin() const { return const_iterator(in.begin()); }
|
|
|
- virtual const_iterator end() const { return const_iterator(in.end()); }
|
|
|
-
|
|
|
- private:
|
|
|
- std::list<InStream> in;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename GenIter, typename It> struct flatmap_stream_iterator {
|
|
|
- public:
|
|
|
- typedef typename GenIter::value_type MapStream;
|
|
|
- typedef typename It::value_type value_type;
|
|
|
- typedef value_type & reference;
|
|
|
- typedef value_type * pointer;
|
|
|
- typedef std::ptrdiff_t difference_type;
|
|
|
- typedef std::input_iterator_tag iterator_category;
|
|
|
-
|
|
|
- public:
|
|
|
- flatmap_stream_iterator(GenIter gen) : generator(gen) {}
|
|
|
-
|
|
|
- value_type operator*() {
|
|
|
- if (!mapped) {
|
|
|
- mapped = new MapStream(std::forward<MapStream>(*generator));
|
|
|
- curr = mapped->begin();
|
|
|
- end = mapped->end();
|
|
|
- }
|
|
|
- return *curr;
|
|
|
- }
|
|
|
-
|
|
|
- flatmap_stream_iterator & operator++() {
|
|
|
- ++curr;
|
|
|
- if (curr == end) {
|
|
|
- ++generator;
|
|
|
- delete mapped;
|
|
|
- mapped = nullptr;
|
|
|
- }
|
|
|
- return *this;
|
|
|
- }
|
|
|
-
|
|
|
- flatmap_stream_iterator operator++(int) {
|
|
|
- flatmap_stream_iterator tmp(*this);
|
|
|
- operator++();
|
|
|
- return tmp;
|
|
|
- }
|
|
|
-
|
|
|
- private:
|
|
|
- GenIter generator;
|
|
|
- MapStream * mapped = nullptr;
|
|
|
- It curr;
|
|
|
- It end;
|
|
|
- };
|
|
|
-
|
|
|
- template <typename O, typename I, typename InStream, typename MapStream>
|
|
|
- class flatmap_stream
|
|
|
- : public iter_stream<
|
|
|
- O, flatmap_stream_iterator<typename InStream::const_iterator,
|
|
|
- typename MapStream::const_iterator>> {};
|
|
|
-
|
|
|
- template <typename T, template <class...> class C>
|
|
|
- cont_stream<T, C> make_stream(const C<T> & data) {
|
|
|
- return cont_stream<T, C>(data);
|
|
|
- }
|
|
|
-
|
|
|
- template <typename F, typename InStream>
|
|
|
- auto map(const InStream & stream, F func) -> map_stream<
|
|
|
- decltype(func(std::declval<typename InStream::value_type>())),
|
|
|
- typename InStream::value_type, InStream> {
|
|
|
- using I = typename InStream::value_type;
|
|
|
- using O = decltype(func(std::declval<I>()));
|
|
|
- return map_stream<O, I, InStream>(stream, func);
|
|
|
- }
|
|
|
-
|
|
|
- template <typename P, typename InStream>
|
|
|
- auto filter(const InStream & stream, P predicate)
|
|
|
- -> filter_stream<typename InStream::value_type, InStream> {
|
|
|
- using T = typename InStream::value_type;
|
|
|
- return filter_stream<T, InStream>(stream, predicate);
|
|
|
- }
|
|
|
-
|
|
|
- template <typename P, typename F, typename InStream>
|
|
|
- auto map_if(const InStream & stream, P predicate, F func)
|
|
|
- -> decltype(map(std::declval<decltype(filter(stream, predicate))>(),
|
|
|
- func)) {
|
|
|
- return map(filter(stream, predicate), func);
|
|
|
- }
|
|
|
-
|
|
|
- // void flatMap(const InStream& stream, F func)
|
|
|
-
|
|
|
- template <typename F, typename InStream, typename Arg1>
|
|
|
- auto reduce(const InStream & stream, F func, Arg1 accum) -> Arg1 {
|
|
|
- std::for_each(stream.begin(), stream.end(),
|
|
|
- [&accum, func](typename InStream::value_type i) {
|
|
|
- accum = func(accum, i);
|
|
|
- });
|
|
|
- return accum;
|
|
|
- }
|
|
|
-
|
|
|
-}
|