map.hpp 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #pragma once
  2. #include <iterator/proxy.h>
  3. namespace stream::detail {
  4. template <typename T, typename R>
  5. class map_iterator : public ::iterator::proxy<iterator<T>, map_iterator<T, R>> {
  6. public:
  7. using projection_t = std::function<R(T const &)>;
  8. using super_t = ::iterator::proxy<iterator<T>, map_iterator<T, R>>;
  9. public:
  10. map_iterator(projection_t proj, iterator<T> && impl)
  11. : proj_(std::move(proj)), super_t(std::move(impl)) {}
  12. R dereference() const { return proj_(super_t::dereference()); }
  13. private:
  14. std::function<R(T const &)> proj_;
  15. };
  16. template <typename T, typename R> class map_stream {
  17. public:
  18. template <typename F>
  19. map_stream(F && func, stream_base<T> const & sb) : fun_(func), source_(sb) {}
  20. iterator<R> begin() { return {map_iterator<T, R>{fun_, source_.begin()}}; }
  21. iterator<R> end() { return {map_iterator<T, R>{fun_, source_.end()}}; }
  22. private:
  23. std::function<R(T const &)> fun_;
  24. stream_base<T> source_;
  25. };
  26. template <typename T>
  27. template <typename F>
  28. stream_base<traits::mapped_t<T, F>> stream_base<T>::map(F && func) && {
  29. return std::make_shared<map_stream<T, traits::mapped_t<T, F>>>(
  30. func, std::move(*this));
  31. }
  32. template <typename T>
  33. template <typename F>
  34. stream_base<traits::mapped_t<T, F>> stream_base<T>::map(F && func) const & {
  35. return std::make_shared<map_stream<T, traits::mapped_t<T, F>>>(func, *this);
  36. }
  37. }