iota_view.h 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //
  2. // iota_view.h
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 3/29/23.
  6. //
  7. #pragma once
  8. #include <iterator/facade.h>
  9. namespace stream::ranges {
  10. template <typename T, typename Bound>
  11. class iota_iterator : public facade<iota_iterator<T, Bound>> {
  12. public:
  13. using sentinal_type = Bound;
  14. iota_iterator() = default;
  15. iota_iterator(T value, Bound bound) : value_(value), bound_(bound) {}
  16. T const & dereference() const { return value_; }
  17. void increment() { ++value_; }
  18. bool at_end() const { return value_ == bound_; }
  19. std::ptrdiff_t distance_to(iota_iterator const & other) const {
  20. return other.value_ - value_;
  21. }
  22. private:
  23. T value_;
  24. Bound bound_;
  25. };
  26. template <typename T, typename Bound> struct iota_view {
  27. public:
  28. constexpr static inline bool has_size_v = std::is_constructible_v<T, Bound>;
  29. private:
  30. T value_;
  31. Bound bound_;
  32. public:
  33. iota_view(T value, Bound bound) : value_(value), bound_(bound) {}
  34. auto begin() const { return iota_iterator(value_, bound_); }
  35. auto end() const {
  36. if constexpr (has_size_v) {
  37. return iota_iterator(bound_, bound_);
  38. } else {
  39. return bound_;
  40. }
  41. }
  42. bool empty() const { return begin().at_end(); }
  43. auto size() const -> std::enable_if_t<has_size_v, size_t> {
  44. return begin().distance_to(end());
  45. }
  46. };
  47. }
  48. namespace stream::ranges::views {
  49. template <typename T, typename Bound> auto iota(T value, Bound bound) {
  50. return iota_view(value, bound);
  51. }
  52. }
  53. MAKE_ITERATOR_FACADE_TYPEDEFS_T(stream::ranges::iota_iterator);