stream_helpers.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. //
  2. // stream_helpers.h
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 4/4/23.
  6. //
  7. #pragma once
  8. #include <iterator/end_aware_iterator.h>
  9. #include <iterator/proxy.h>
  10. #include <stream/detail/traits.h>
  11. namespace ranges = stream::ranges;
  12. namespace views = stream::ranges::views;
  13. #include <iterator/detail/macro.h>
  14. #define SELF() (*static_cast<CRTP const *>(this))
  15. /**
  16. * There are the following types of iterators/containers that we are interested
  17. * in:
  18. * - Does the object use common iterators or sentinel iterators
  19. * - Does the object have a size/empty
  20. */
  21. template <typename It>
  22. class remaining_iterator : public iterator::end_aware_iterator<It> {
  23. public:
  24. using super_t = iterator::end_aware_iterator<It>;
  25. public:
  26. using super_t::super_t;
  27. friend auto operator-(remaining_iterator const & it, iterator::sentinel_t) {
  28. return std::distance(super_t::impl(), super_t::end());
  29. }
  30. };
  31. MAKE_ITERATOR_FACADE_TYPEDEFS_T(remaining_iterator);
  32. template <typename CRTP> struct Sized {
  33. size_t size() const { return SELF().impl().size(); }
  34. bool empty() const { return SELF().impl().size() == 0; }
  35. };
  36. template <typename CRTP> struct Common {
  37. auto begin() const { return SELF().impl().begin(); }
  38. auto end() const { return SELF().impl().end(); }
  39. };
  40. template <typename CRTP> struct Sentinel {
  41. auto begin() const { return iterator::end_aware_iterator(SELF().impl()); }
  42. auto end() const { return iterator::sentinel; }
  43. };
  44. template <typename CRTP> struct SizedSentinel {
  45. auto begin() const { return remaining_iterator(SELF().impl()); }
  46. auto end() const { return iterator::sentinel; }
  47. };
  48. template <typename C, template <typename> class... Traits>
  49. class Range : public Traits<Range<C, Traits...>>... {
  50. private:
  51. C impl_;
  52. public:
  53. Range() = default;
  54. Range(C impl) : impl_(std::move(impl)) {}
  55. template <typename T> Range(std::initializer_list<T> init) : impl_(init) {}
  56. auto & impl() const { return impl_; }
  57. };
  58. #include <iterator/detail/undef.h>