transform.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #pragma once
  2. #include <functional>
  3. #include <stream/forward.h>
  4. #include <stream/detail/traits.h>
  5. #include <stream/iterator/transform_iterator.h>
  6. #include <stream/detail/macro.h>
  7. namespace stream::ranges {
  8. template <typename S, typename Proj> class transform_view {
  9. private:
  10. private:
  11. S stream_;
  12. Proj projection_;
  13. public:
  14. transform_view(S && stream, Proj projection)
  15. : stream_(FWD(stream)), projection_(projection) {}
  16. auto begin() const { return transform_iterator(stream_.begin(), invoke()); }
  17. auto end() const {
  18. if constexpr (detail::is_sentinal_v<S>) {
  19. return stream_.end();
  20. } else {
  21. return transform_iterator(stream_.end(), invoke());
  22. }
  23. }
  24. SFINAE(detail::has_empty_v<S>, bool) empty() const { return stream_.empty(); }
  25. SFINAE(detail::has_size_v<S>, size_t) size() { return stream_.size(); }
  26. private:
  27. auto invoke() const {
  28. return std::function([this](detail::cref_t<S> t) -> decltype(auto) {
  29. return std::invoke(projection_, t);
  30. });
  31. }
  32. };
  33. template <typename S, typename Proj>
  34. transform_view(S &&, Proj) -> transform_view<S, Proj>;
  35. }
  36. namespace stream::ranges::views {
  37. template <typename Proj> class transform {
  38. public:
  39. transform(Proj const & projection) : projection_(projection) {}
  40. template <typename Stream>
  41. friend auto operator|(Stream && stream, transform map) {
  42. // TODO: if constexpr transform_view
  43. return transform_view(FWD(stream), std::move(map.projection_));
  44. }
  45. private:
  46. Proj projection_;
  47. };
  48. }
  49. #include <stream/detail/undef.h>