interface.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. //
  2. // interface.h
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 4/6/23.
  6. //
  7. #pragma once
  8. #include <stream/forward.h>
  9. #include <stream/detail/traits.h>
  10. #include <stream/detail/macro.h>
  11. namespace stream::ranges {
  12. template <typename self_type, typename It, typename S = It>
  13. class view_interface {
  14. private:
  15. using category = iterator::category;
  16. using difference_type = typename std::iterator_traits<It>::difference_type;
  17. constexpr static auto category_enum = detail::category_for_v<It>;
  18. constexpr static bool is_common = std::is_same_v<It, S>;
  19. constexpr static bool has_distance = detail::is_sized_sentinel_v<It, S>;
  20. public:
  21. SFINAE(category_enum >= category::forward || has_distance)
  22. bool empty() const { return self().begin() == self().end(); }
  23. SFINAE(category_enum >= category::forward && has_distance)
  24. size_t size() const { return self().end() - self().begin(); }
  25. SFINAE(category_enum >= category::forward) auto front() const {
  26. return *self().begin();
  27. }
  28. SFINAE(category_enum >= category::bidirectional && is_common)
  29. auto back() const { return *--self().end(); }
  30. SFINAE(category_enum >= category::random_access)
  31. auto operator[](difference_type off) const { return self().begin()[off]; }
  32. protected:
  33. self_type & self() { return *static_cast<self_type *>(this); }
  34. self_type const & self() const {
  35. return *static_cast<self_type const *>(this);
  36. }
  37. };
  38. template <typename self_type, typename base_type,
  39. template <typename...> class iterator, typename... Ts>
  40. using proxy_view_interface =
  41. view_interface<self_type, iterator<detail::begin_t<base_type>, Ts...>,
  42. detail::sentinel_iterator<base_type, iterator, Ts...>>;
  43. }
  44. #include <stream/detail/undef.h>