proxy.h 2.9 KB

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