// // iota_view.h // stream // // Created by Sam Jaffe on 3/29/23. // #pragma once #include namespace stream::ranges { template struct iota_view { public: constexpr static inline bool has_size_v = std::is_constructible_v; class iterator : facade { public: using sentinal_type = Bound; iterator(T value, Bound bound) : value_(value), bound_(bound) {} T const & dereference() const { return value_; } void increment() const { ++value_; } bool at_end() const { return value_ == bound_; } std::ptrdiff_t distance_to(iterator const & other) const { return other.value_ - value_; } private: T value_; Bound bound_; }; private: T value_; Bound bound_; public: iota_view(T value, Bound bound) : value_(value), bound_(bound) {} auto begin() const { return iterator(value_, bound_); } auto end() const { if constexpr (has_size_v) { return iterator(bound_, bound_); } else { return bound_; } } bool empty() const { return begin().at_end(); } auto size() const -> std::enable_if_t { return begin().distance_to(end()); } }; } namespace stream::ranges::views { template auto iota(T value, Bound bound) { return iota_view(value, bound); } }