// // common_view.h // stream // // Created by Sam Jaffe on 3/30/23. // #pragma once #include #include #include #include #define FWD(x) std::forward(x) namespace stream::ranges { template class common_iterator : public proxy> { public: static_assert(!std::is_same_v, "cannot operator on common types"); using super_t = proxy>; using sentinel_type = common_iterator; public: using super_t::super_t; common_iterator(S) : super_t() {} bool equal_to(common_iterator const & other) const { return (at_end() && other.at_end()) || super_t::impl() == other.impl(); } bool at_end() const { return super_t::impl() == S(); } }; template class common_view { private: using iterator = common_iterator, detail::end_t>; private: S stream_; public: common_view(S && stream) : stream_(FWD(stream)) {} auto begin() const { return iterator(stream_.begin()); } auto end() const { return iterator(stream_.end()); } SFINAE(detail::has_empty_v, bool) empty() const { return stream_.empty(); } SFINAE(detail::has_size_v, bool) size() const { return stream_.size(); } }; template common_view(S &&) -> common_view; } namespace stream::ranges::views { struct common { template friend auto operator|(Stream && stream, common) { if constexpr (detail::is_sentinal_v) { return common_view(FWD(stream)); } else { return FWD(stream); } } }; } MAKE_ITERATOR_FACADE_TYPEDEFS_T(stream::ranges::common_iterator); #undef FWD #include