proxy.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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> {
  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>
  16. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  17. decltype(auto) dereference() const { return *impl_; }
  18. void increment() { ++impl_; }
  19. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  20. SFINAE(detail::has_sentinel_type_v, bool) at_end() const {
  21. return impl() == typename It::sentinel_type();
  22. }
  23. protected:
  24. auto & impl() const { return impl_; }
  25. };
  26. template <typename It, typename Self>
  27. class proxy<It, Self, std::forward_iterator_tag> : public facade<Self> {
  28. private:
  29. It impl_;
  30. public:
  31. proxy() = default;
  32. proxy(It impl) : impl_(impl) {}
  33. template <typename... Args>
  34. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  35. decltype(auto) dereference() const { return *impl_; }
  36. void increment() { ++impl_; }
  37. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  38. SFINAE(detail::has_sentinel_type_v, bool) at_end() const {
  39. return impl() == typename It::sentinel_type();
  40. }
  41. protected:
  42. auto & impl() const { return impl_; }
  43. };
  44. template <typename It, typename Self>
  45. class proxy<It, Self, std::bidirectional_iterator_tag> : public facade<Self> {
  46. private:
  47. It impl_;
  48. public:
  49. proxy() = default;
  50. proxy(It impl) : impl_(impl) {}
  51. template <typename... Args>
  52. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  53. decltype(auto) dereference() const { return *impl_; }
  54. void increment() { ++impl_; }
  55. void decrement() { --impl_; }
  56. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  57. SFINAE(detail::has_sentinel_type_v, bool) at_end() const {
  58. return impl() == typename It::sentinel_type();
  59. }
  60. protected:
  61. auto & impl() const { return impl_; }
  62. };
  63. template <typename It, typename Self>
  64. class proxy<It, Self, std::random_access_iterator_tag> : public facade<Self> {
  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>
  73. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  74. decltype(auto) dereference() const { return *impl_; }
  75. void advance(difference_type off) { impl_ += off; }
  76. // This shouldn't need to be implemented, but for some reason my traits
  77. // are not correctly deducing here.
  78. bool equal_to(Self const & other) const { return distance_to(other) == 0; }
  79. difference_type distance_to(Self const & other) const {
  80. return other.impl_ - impl_;
  81. }
  82. SFINAE(detail::has_sentinel_type_v, bool) at_end() const {
  83. return impl() == typename It::sentinel_type();
  84. }
  85. protected:
  86. auto & impl() const { return impl_; }
  87. };
  88. }
  89. #include <iterator/detail/undef.h>