| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- #pragma once
- #include <functional>
- #include <iterator/proxy.h>
- #include <stream/detail/traits.h>
- #include <stream/forward.h>
- #include <iterator/detail/macro.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());
- }
- bool at_end() const { return super_t::impl().at_end(); }
- };
- template <typename S, typename Proj> class transform_view {
- private:
- private:
- S stream_;
- Proj projection_;
- public:
- transform_view(S && stream, Proj projection)
- : stream_(FWD(stream)), projection_(projection) {}
- auto begin() const { return transform_iterator(stream_.begin(), invoke()); }
- auto end() const {
- if constexpr (detail::is_sentinal_v<S>) {
- return stream_.end();
- } else {
- return transform_iterator(stream_.end(), invoke());
- }
- }
- SFINAE(detail::has_empty_v<S>, bool) empty() const { return stream_.empty(); }
- SFINAE(detail::has_size_v<S>, size_t) size() { return stream_.size(); }
- private:
- auto invoke() const {
- return std::function([this](detail::cref_t<S> t) -> decltype(auto) {
- return std::invoke(projection_, t);
- });
- }
- };
- template <typename S, typename Proj>
- transform_view(S &&, Proj) -> transform_view<S, Proj>;
- }
- 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 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_;
- };
- }
- #undef FWD
- #include <iterator/detail/undef.h>
|