iota_view.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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> struct iota_view {
  11. public:
  12. constexpr static inline bool has_size_v = std::is_constructible_v<T, Bound>;
  13. class iterator : facade<iterator> {
  14. public:
  15. using sentinal_type = Bound;
  16. iterator(T value, Bound bound) : value_(value), bound_(bound) {}
  17. T const & dereference() const { return value_; }
  18. void increment() const { ++value_; }
  19. bool at_end() const { return value_ == bound_; }
  20. std::ptrdiff_t distance_to(iterator const & other) const {
  21. return other.value_ - value_;
  22. }
  23. private:
  24. T value_;
  25. Bound bound_;
  26. };
  27. private:
  28. T value_;
  29. Bound bound_;
  30. public:
  31. iota_view(T value, Bound bound) : value_(value), bound_(bound) {}
  32. auto begin() const { return iterator(value_, bound_); }
  33. auto end() const {
  34. if constexpr (has_size_v) {
  35. return iterator(bound_, bound_);
  36. } else {
  37. return bound_;
  38. }
  39. }
  40. bool empty() const { return begin().at_end(); }
  41. auto size() const -> std::enable_if_t<has_size_v, size_t> {
  42. return begin().distance_to(end());
  43. }
  44. };
  45. }
  46. namespace stream::ranges::views {
  47. template <typename T, typename Bound> auto iota(T value, Bound bound) {
  48. return iota_view(value, bound);
  49. }
  50. }