common_iterator.h 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. //
  2. // common_iterator.h
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 4/2/23.
  6. //
  7. #pragma once
  8. #include <iterator/proxy.h>
  9. #include <stream/forward.h>
  10. #include <stream/detail/macro.h>
  11. namespace stream::ranges {
  12. template <typename It, typename S>
  13. class common_iterator : public proxy<It, common_iterator<It, S>> {
  14. public:
  15. static_assert(!std::is_same_v<It, S>, "cannot operator on common types");
  16. using super_t = proxy<It, common_iterator<It, S>>;
  17. using sentinel_type = common_iterator;
  18. public:
  19. using super_t::super_t;
  20. common_iterator(S) : super_t() {}
  21. SFINAE(super_t::category_enum == iterator::category::random_access)
  22. auto distance_to(common_iterator const & other) const {
  23. if (at_end()) {
  24. return other.at_end() ? 0 : -(S() - other);
  25. } else if (other.at_end()) {
  26. return S() - *this;
  27. } else {
  28. return super_t::distance_to(other);
  29. }
  30. }
  31. bool equal_to(common_iterator const & other) const {
  32. return (at_end() && other.at_end()) || super_t::impl() == other.impl();
  33. }
  34. bool at_end() const { return super_t::impl() == S(); }
  35. };
  36. }
  37. MAKE_ITERATOR_FACADE_TYPEDEFS_T(stream::ranges::common_iterator);
  38. #include <stream/detail/undef.h>