| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- //
- // interface.h
- // stream
- //
- // Created by Sam Jaffe on 4/6/23.
- //
- #pragma once
- #include <stream/forward.h>
- #include <stream/detail/traits.h>
- #include <stream/detail/macro.h>
- namespace stream::ranges {
- template <typename self_type, typename It, typename S = It>
- class view_interface {
- private:
- using category = iterator::category;
- using difference_type = typename std::iterator_traits<It>::difference_type;
- constexpr static auto category_enum = detail::category_for_v<It>;
- constexpr static bool is_common = std::is_same_v<It, S>;
- constexpr static bool has_distance = detail::is_sized_sentinel_v<It, S>;
- 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<self_type *>(this); }
- self_type const & self() const {
- return *static_cast<self_type const *>(this);
- }
- };
- template <typename self_type, typename base_type,
- template <typename...> class iterator, typename... Ts>
- using proxy_view_interface =
- view_interface<self_type, iterator<detail::begin_t<base_type>, Ts...>,
- detail::sentinel_iterator<base_type, iterator, Ts...>>;
- }
- #include <stream/detail/undef.h>
|