| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- //
- // common_view.h
- // stream
- //
- // Created by Sam Jaffe on 3/30/23.
- //
- #pragma once
- #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 S>
- class common_iterator : public proxy<It, common_iterator<It, S>> {
- public:
- static_assert(!std::is_same_v<It, S>, "cannot operator on common types");
- using super_t = proxy<It, common_iterator<It, S>>;
- 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 <typename S> class common_view {
- private:
- using iterator = common_iterator<detail::begin_t<S>, detail::end_t<S>>;
- 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<S>, bool) empty() const { return stream_.empty(); }
- SFINAE(detail::has_size_v<S>, bool) size() const { return stream_.size(); }
- };
- template <typename S> common_view(S &&) -> common_view<S>;
- }
- namespace stream::ranges::views {
- struct common {
- template <typename Stream> friend auto operator|(Stream && stream, common) {
- if constexpr (detail::is_sentinal_v<Stream>) {
- return common_view(FWD(stream));
- } else {
- return FWD(stream);
- }
- }
- };
- }
- MAKE_ITERATOR_FACADE_TYPEDEFS_T(stream::ranges::common_iterator);
- #undef FWD
- #include <iterator/detail/undef.h>
|