proxy.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #pragma once
  2. #include <iterator/facade.h>
  3. #include <iterator/forwards.h>
  4. #include <iterator/detail/macro.h>
  5. namespace iterator {
  6. template <typename It, typename Self, typename Cat>
  7. class proxy : public facade<Self, category::single_pass> {
  8. public:
  9. using single_pass_iterator = void;
  10. private:
  11. It impl_;
  12. public:
  13. proxy() = default;
  14. proxy(It impl) : impl_(impl) {}
  15. template <typename... Args> proxy(Args &&... args) : impl_(FWD(args)...) {}
  16. decltype(auto) dereference() const { return *impl_; }
  17. void increment() { ++impl_; }
  18. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  19. SFINAE(detail::has_sentinel_type_v<It>) bool at_end() const {
  20. return impl() == typename It::sentinel_type();
  21. }
  22. protected:
  23. auto impl() const { return impl_; }
  24. };
  25. template <typename It, typename Self>
  26. class proxy<It, Self, std::forward_iterator_tag>
  27. : public facade<Self, category::forward> {
  28. private:
  29. It impl_;
  30. public:
  31. proxy() = default;
  32. proxy(It impl) : impl_(impl) {}
  33. template <typename... Args> proxy(Args &&... args) : impl_(FWD(args)...) {}
  34. decltype(auto) dereference() const { return *impl_; }
  35. void increment() { ++impl_; }
  36. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  37. SFINAE(detail::has_sentinel_type_v<It>) bool at_end() const {
  38. return impl() == typename It::sentinel_type();
  39. }
  40. protected:
  41. auto impl() const { return impl_; }
  42. };
  43. template <typename It, typename Self>
  44. class proxy<It, Self, std::bidirectional_iterator_tag>
  45. : public facade<Self, category::bidirectional> {
  46. private:
  47. It impl_;
  48. public:
  49. proxy() = default;
  50. proxy(It impl) : impl_(impl) {}
  51. template <typename... Args> proxy(Args &&... args) : impl_(FWD(args)...) {}
  52. decltype(auto) dereference() const { return *impl_; }
  53. void increment() { ++impl_; }
  54. void decrement() { --impl_; }
  55. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  56. SFINAE(detail::has_sentinel_type_v<It>) bool at_end() const {
  57. return impl() == typename It::sentinel_type();
  58. }
  59. protected:
  60. auto impl() const { return impl_; }
  61. };
  62. template <typename It, typename Self>
  63. class proxy<It, Self, std::random_access_iterator_tag>
  64. : public facade<Self, category::random_access> {
  65. public:
  66. using difference_type = typename std::iterator_traits<It>::difference_type;
  67. private:
  68. It impl_;
  69. public:
  70. proxy() = default;
  71. proxy(It impl) : impl_(impl) {}
  72. template <typename... Args> proxy(Args &&... args) : impl_(FWD(args)...) {}
  73. decltype(auto) dereference() const { return *impl_; }
  74. void advance(difference_type off) { impl_ += off; }
  75. difference_type distance_to(Self const & other) const {
  76. return other.impl_ - impl_;
  77. }
  78. template <typename S, REQUIRES((detail::is_sentinel_v<It, S>))>
  79. friend auto operator-(S sentinel, Self const &self) {
  80. return sentinel - self.impl();
  81. }
  82. SFINAE(detail::has_sentinel_type_v<It>) bool at_end() const {
  83. return (typename It::sentinel_type() - impl()) <= 0;
  84. }
  85. protected:
  86. auto impl() const { return impl_; }
  87. };
  88. }
  89. #include <iterator/detail/undef.h>