subrange.h 1.0 KB

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