sentinal_iterator.h 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. //
  2. // sentinal_iterator.h
  3. // iterator
  4. //
  5. // Created by Sam Jaffe on 3/30/23.
  6. // Copyright © 2023 Sam Jaffe. All rights reserved.
  7. //
  8. #pragma once
  9. #include <iterator/detail/traits.h>
  10. #include <iterator/facade.h>
  11. #include <iterator/iterator_fwd.hpp>
  12. namespace iterator {
  13. template <typename It>
  14. class sentinal_iterator : public facade<sentinal_iterator<It>> {
  15. public:
  16. using sentinal_type = typename It::sentinal_type;
  17. static constexpr sentinal_type sentinal{};
  18. public:
  19. sentinal_iterator() = default;
  20. sentinal_iterator(It it) : curr_(it) {}
  21. template <typename C, typename = std::enable_if_t<detail::is_container_v<C>>>
  22. sentinal_iterator(C && container) : curr_(std::begin(container)) {
  23. static_assert(std::is_reference_v<C>,
  24. "Cannot access iterator of a temporary");
  25. }
  26. decltype(auto) dereference() const { return *curr_; }
  27. void increment() { ++curr_; }
  28. bool at_end() const { return curr_.at_end() || curr_ == It(); }
  29. bool equal_to(sentinal_iterator const & other) const {
  30. // TODO: Fix this clause
  31. return (at_end() && other.at_end()) || curr_ == other.curr_;
  32. }
  33. private:
  34. It curr_;
  35. };
  36. template <typename C> sentinal_iterator(C &&) -> sentinal_iterator<iter<C>>;
  37. template <typename It> sentinal_iterator(It) -> sentinal_iterator<It>;
  38. }
  39. MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::sentinal_iterator);