subrange.h 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. #pragma once
  2. #include <iterator>
  3. #include <iterator/detail/facade_traits.h>
  4. #include <stream/forward.h>
  5. #include <iterator/detail/macro.h>
  6. namespace stream::ranges {
  7. template <typename It, typename S = It> class subrange {
  8. private:
  9. It begin_;
  10. S end_;
  11. public:
  12. subrange(It begin, S end) : begin_(begin), end_(end) {}
  13. template <typename C, REQUIRES(detail::is_container_v<C>)>
  14. subrange(C && container)
  15. : subrange(std::begin(container), std::end(container)) {
  16. // TODO: permissible dangling
  17. static_assert(std::is_reference_v<C>,
  18. "Cannot access iterator of a temporary");
  19. }
  20. auto begin() const { return begin_; }
  21. auto end() const { return end_; }
  22. bool empty() const { return begin_ == end_; }
  23. SFINAE(detail::has_distance_to_v<It>, size_t) size() const {
  24. return end_ - begin_;
  25. }
  26. };
  27. template <typename It, typename S> subrange(It, S) -> subrange<It, S>;
  28. template <typename C>
  29. subrange(C &&) -> subrange<detail::begin_t<C>, detail::end_t<C>>;
  30. }
  31. #include <iterator/detail/undef.h>