// // iota.h // stream // // Created by Sam Jaffe on 3/29/23. // #pragma once #include #include namespace stream::ranges { template class iota_iterator : public facade> { public: using sentinal_type = Bound; iota_iterator() = default; iota_iterator(T value, Bound bound) : value_(value), bound_(bound) {} T const & dereference() const { return value_; } void increment() { ++value_; } bool at_end() const { return value_ == bound_; } // Some weird bug in dependent template instantiation??? bool equal_to(iota_iterator const & other) const { return value_ == other.value_; } std::ptrdiff_t distance_to(iota_iterator const & other) const { return other.value_ - value_; } private: T value_; Bound bound_; }; template struct iota_view { public: constexpr static inline bool has_size_v = std::is_constructible_v; private: T value_; Bound bound_; public: iota_view(T value, Bound bound) : value_(value), bound_(bound) {} auto begin() const { return iota_iterator(value_, bound_); } auto end() const { if constexpr (has_size_v) { return iota_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); } } MAKE_ITERATOR_FACADE_TYPEDEFS_T(stream::ranges::iota_iterator);