view.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. //
  2. // view.h
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 3/29/23.
  6. //
  7. #pragma once
  8. namespace stream::ranges {
  9. template <typename T>
  10. class view_iterator : public facade<view_iterator<T>> {
  11. private:
  12. T (*dereference_)(void *){nullptr};
  13. bool (*equal_to_)(void *, void *){nullptr};
  14. void (*increment_)(void *){nullptr};
  15. std::shared_ptr<void> impl_{nullptr};
  16. public:
  17. template <typename It>
  18. view_iterator(It impl)
  19. : dereference_([](void * p) -> T { return **((It *)p); }),
  20. equal_to_(
  21. [](void * l, void * r) { return *((It *)l) == *((It *)r); }),
  22. increment_([](void * p) { ++(*(It *)(p)); }),
  23. impl_(std::make_shared<It>(impl)) {}
  24. T dereference() const { return dereference_(impl_.get()); }
  25. void increment() { increment_(impl_.get()); }
  26. bool equal_to(view_iterator const & other) const {
  27. return impl_ == other.impl_ ||
  28. (impl_ && other.impl_ &&
  29. equal_to_(impl_.get(), other.impl_.get()));
  30. }
  31. };
  32. template <typename T> class view {
  33. private:
  34. using make_iter_t = view_iterator<T>(*)(void*);
  35. private:
  36. std::shared_ptr<void> impl_{nullptr};
  37. make_iter_t begin_{nullptr};
  38. make_iter_t end_{nullptr};
  39. public:
  40. template <typename S>
  41. view(std::shared_ptr<S> impl)
  42. : impl_(impl), begin_(begin_function<S>()), end_(end_function<S>()) {}
  43. template <typename S>
  44. view(S & impl) : view(std::shared_ptr<S>(&impl, [](void *) {})) {}
  45. template <typename S>
  46. view(S const & impl) : view(std::shared_ptr<S const>(&impl, [](void *) {})) {}
  47. template <typename S>
  48. view(S && impl) : view(std::make_shared<S>(std::forward<S>(impl))) {}
  49. auto begin() const { return begin_(impl_.get()); }
  50. auto end() const { return end_(impl_.get()); }
  51. private:
  52. template <typename S>
  53. static make_iter_t begin_function() {
  54. if constexpr (traits::is_sentinal_v<S>) {
  55. return [](void *p) -> view_iterator<T> {
  56. return iterator::sentinel_iterator(static_cast<S *>(p)->begin());
  57. };
  58. } else {
  59. return [](void * p) -> view_iterator<T> {
  60. return static_cast<S *>(p)->begin();
  61. };
  62. }
  63. }
  64. template <typename S>
  65. static make_iter_t end_function() {
  66. if constexpr (traits::is_sentinal_v<S>) {
  67. return [](void *p) -> view_iterator<T> {
  68. return iterator::sentinel_iterator<iter<S>>();
  69. };
  70. } else {
  71. return [](void * p) -> view_iterator<T> {
  72. return static_cast<S *>(p)->end();
  73. };
  74. }
  75. }
  76. };
  77. template <typename S> view(std::shared_ptr<S>) -> view<traits::value_type<S>>;
  78. template <typename S> view(S &) -> view<traits::value_type<S>>;
  79. template <typename S> view(S const &) -> view<traits::value_type<S>>;
  80. template <typename S> view(S &&) -> view<traits::value_type<S>>;
  81. }