proxy.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #pragma once
  2. #include <iterator/facade.h>
  3. #include <iterator/forwards.h>
  4. namespace iterator {
  5. template <typename It, typename Self, typename Cat>
  6. class Proxy : public Facade<Self> {
  7. public:
  8. static constexpr bool single_pass_iterator = true;
  9. private:
  10. It impl_;
  11. public:
  12. Proxy() = default;
  13. Proxy(It impl) : impl_(impl) {}
  14. template <typename... Args>
  15. Proxy(Args &&... args) : impl_(std::forward<Args>(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. bool at_end() const
  20. requires(has_sentinel<It>)
  21. {
  22. return impl() == typename It::sentinel_type();
  23. }
  24. protected:
  25. auto impl() const { return impl_; }
  26. };
  27. template <typename It, typename Self>
  28. class Proxy<It, Self, std::forward_iterator_tag> : public Facade<Self> {
  29. private:
  30. It impl_;
  31. public:
  32. Proxy() = default;
  33. Proxy(It impl) : impl_(impl) {}
  34. template <typename... Args>
  35. Proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  36. decltype(auto) dereference() const { return *impl_; }
  37. void increment() { ++impl_; }
  38. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  39. bool at_end() const
  40. requires(has_sentinel<It>)
  41. {
  42. return impl() == typename It::sentinel_type();
  43. }
  44. protected:
  45. auto impl() const { return impl_; }
  46. };
  47. template <typename It, typename Self>
  48. class Proxy<It, Self, std::bidirectional_iterator_tag> : public Facade<Self> {
  49. private:
  50. It impl_;
  51. public:
  52. Proxy() = default;
  53. Proxy(It impl) : impl_(impl) {}
  54. template <typename... Args>
  55. Proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  56. decltype(auto) dereference() const { return *impl_; }
  57. void increment() { ++impl_; }
  58. void decrement() { --impl_; }
  59. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  60. bool at_end() const
  61. requires(has_sentinel<It>)
  62. {
  63. return impl() == typename It::sentinel_type();
  64. }
  65. protected:
  66. auto impl() const { return impl_; }
  67. };
  68. template <typename It, typename Self>
  69. class Proxy<It, Self, std::random_access_iterator_tag> : public Facade<Self> {
  70. public:
  71. using difference_type = typename std::iterator_traits<It>::difference_type;
  72. private:
  73. It impl_;
  74. public:
  75. Proxy() = default;
  76. Proxy(It impl) : impl_(impl) {}
  77. template <typename... Args>
  78. Proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  79. decltype(auto) dereference() const { return *impl_; }
  80. void advance(difference_type off) { impl_ += off; }
  81. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  82. difference_type distance_to(Self const & other) const {
  83. return other.impl_ - impl_;
  84. }
  85. friend auto operator-(sentinel_for<It> auto sentinel, Self const & self) {
  86. return sentinel - self.impl();
  87. }
  88. bool at_end() const
  89. requires(has_sentinel<It>)
  90. {
  91. return (typename It::sentinel_type() - impl()) <= 0;
  92. }
  93. protected:
  94. auto impl() const { return impl_; }
  95. };
  96. }