| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- #pragma once
- #include <functional>
- #include <iterator/proxy.h>
- #include <stream/detail/traits.h>
- #define FWD(x) std::forward<decltype(x)>(x)
- namespace stream::ranges {
- template <typename It, typename Proj>
- class transform_iterator : public proxy<It, transform_iterator<It, Proj>> {
- private:
- using super_t = proxy<It, transform_iterator<It, Proj>>;
- private:
- Proj projection_;
- public:
- transform_iterator() = default;
- transform_iterator(It iter, Proj projection)
- : super_t(std::move(iter)), projection_(projection) {}
- decltype(auto) dereference() const {
- return projection_(super_t::dereference());
- }
- };
- template <typename S, typename T> class transform_view {
- public:
- using Proj = std::function<T(traits::cref_t<S>)>;
- private:
- S stream_;
- Proj projection_;
- public:
- transform_view(S && stream, Proj projection)
- : stream_(FWD(stream)), projection_(projection) {}
- template <typename F>
- transform_view(S && stream, F projection)
- : stream_(FWD(stream)), projection_(projection) {}
- auto begin() const {
- return transform_iterator(stream_.begin(), projection_);
- }
- auto end() const { return transform_iterator(stream_.end(), projection_); }
- bool empty() const { return stream_.empty(); }
- size_t size() const { return stream_.size(); }
- };
- template <typename S, typename R, typename T>
- transform_view(S &&, std::function<R(T)>) -> transform_view<S, R>;
- template <typename S, typename F>
- transform_view(S &&, F)
- -> transform_view<S, std::invoke_result_t<F, traits::cref_t<S>>>;
- }
- MAKE_ITERATOR_FACADE_TYPEDEFS_T(stream::ranges::transform_iterator);
- namespace stream::ranges::views {
- template <typename Proj> class transform {
- public:
- transform(Proj const & projection) : projection_(projection) {}
- template <typename T, typename R>
- transform(R (*ptr)(T))
- : projection_([ptr](auto & t) -> R { return ptr(t); }) {}
- template <typename T, typename R>
- transform(R T::*ptr)
- : projection_([ptr](auto & t) -> R const & { return t.*ptr; }) {}
- template <typename T, typename R>
- transform(R (T::*ptr)() const)
- : projection_([ptr](auto & t) -> R { return (t.*ptr)(); }) {}
- template <typename T, typename R>
- transform(R (T::*ptr)() const noexcept)
- : projection_([ptr](auto & t) -> R { return (t.*ptr)(); }) {}
- template <typename Stream>
- friend auto operator|(Stream && stream, transform map) {
- // TODO: if constexpr transform_view
- return transform_view(FWD(stream), std::move(map.projection_));
- }
- private:
- Proj projection_;
- };
- template <typename Proj> transform(Proj const &) -> transform<Proj>;
- template <typename T, typename R>
- transform(R (*ptr)(T)) -> transform<std::function<R(T const &)>>;
- template <typename T, typename R>
- transform(R T::*ptr) -> transform<std::function<R const &(T const &)>>;
- template <typename T, typename R>
- transform(R (T::*ptr)() const) -> transform<std::function<R(T const &)>>;
- template <typename T, typename R>
- transform(R (T::*ptr)() const noexcept)
- -> transform<std::function<R(T const &)>>;
- }
- #undef FWD
|