// // interface.h // stream // // Created by Sam Jaffe on 4/6/23. // #pragma once #include #include #include namespace stream::ranges { template class view_interface { private: using category = iterator::category; using difference_type = typename std::iterator_traits::difference_type; constexpr static auto category_enum = detail::category_for_v; constexpr static bool is_common = std::is_same_v; constexpr static bool has_distance = detail::is_sized_sentinel_v; public: SFINAE(category_enum >= category::forward || has_distance) bool empty() const { return self().begin() == self().end(); } SFINAE(category_enum >= category::forward && has_distance) size_t size() const { return self().end() - self().begin(); } SFINAE(category_enum >= category::forward) auto front() const { return *self().begin(); } SFINAE(category_enum >= category::bidirectional && is_common) auto back() const { return *--self().end(); } SFINAE(category_enum >= category::random_access) auto operator[](difference_type off) const { return self().begin()[off]; } protected: self_type & self() { return *static_cast(this); } self_type const & self() const { return *static_cast(this); } }; template class iterator, typename... Ts> using proxy_view_interface = view_interface, Ts...>, detail::sentinel_iterator>; } #include