any.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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/forward.h>
  10. #include <stream/detail/traits.h>
  11. #include <stream/iterator/any_iterator.h>
  12. namespace stream::ranges {
  13. template <typename T> class any_view {
  14. private:
  15. template <typename S>
  16. using sentinel_iterator =
  17. common_iterator<detail::begin_t<S>, detail::end_t<S>>;
  18. template <typename S, typename It>
  19. using iter_cast_t =
  20. std::conditional_t<detail::has_sentinal_v<S>, sentinel_iterator<S>, It>;
  21. using make_iter_t = any_iterator<T> (*)(void *);
  22. private:
  23. std::shared_ptr<void> impl_{nullptr};
  24. make_iter_t begin_{nullptr};
  25. make_iter_t end_{nullptr};
  26. public:
  27. template <typename S>
  28. any_view(std::shared_ptr<S> impl)
  29. : impl_(impl), begin_(begin_function<S>()), end_(end_function<S>()) {}
  30. template <typename S>
  31. any_view(S & impl) : any_view(std::shared_ptr<S>(&impl, [](void *) {})) {}
  32. template <typename S>
  33. any_view(S const & impl)
  34. : any_view(std::shared_ptr<S const>(&impl, [](void *) {})) {}
  35. template <typename S>
  36. any_view(S && impl) : any_view(std::make_shared<S>(std::forward<S>(impl))) {}
  37. auto begin() const { return begin_(impl_.get()); }
  38. auto end() const { return end_(impl_.get()); }
  39. private:
  40. template <typename S> static make_iter_t begin_function() {
  41. return [](void * p) -> any_iterator<T> {
  42. return iter_cast_t<S, detail::begin_t<S>>(static_cast<S *>(p)->begin());
  43. };
  44. }
  45. template <typename S> static make_iter_t end_function() {
  46. return [](void * p) -> any_iterator<T> {
  47. return iter_cast_t<S, detail::end_t<S>>(static_cast<S *>(p)->end());
  48. };
  49. }
  50. };
  51. template <typename S>
  52. any_view(std::shared_ptr<S>) -> any_view<detail::value_type<S>>;
  53. template <typename S> any_view(S &) -> any_view<detail::value_type<S>>;
  54. template <typename S> any_view(S const &) -> any_view<detail::value_type<S>>;
  55. template <typename S> any_view(S &&) -> any_view<detail::value_type<S>>;
  56. }