any.h 2.8 KB

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