proxy.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #include <iterator/facade.h>
  3. #include <iterator/iterator_fwd.hpp>
  4. namespace iterator {
  5. template <typename Iter, typename Self>
  6. class proxy<Iter, Self, std::input_iterator_tag> : public facade<Self> {
  7. public:
  8. using single_pass_iterator = void;
  9. private:
  10. Iter impl_;
  11. public:
  12. proxy(Iter impl = {}) : impl_(impl) {}
  13. template <typename... Args>
  14. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  15. decltype(auto) dereference() const { return *impl_; }
  16. void increment() { ++impl_; }
  17. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  18. protected:
  19. auto & impl() const { return impl_; }
  20. };
  21. template <typename Iter, typename Self>
  22. class proxy<Iter, Self, std::forward_iterator_tag> : public facade<Self> {
  23. private:
  24. Iter impl_;
  25. public:
  26. proxy(Iter impl = {}) : impl_(impl) {}
  27. template <typename... Args>
  28. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  29. decltype(auto) dereference() const { return *impl_; }
  30. void increment() { ++impl_; }
  31. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  32. protected:
  33. auto & impl() const { return impl_; }
  34. };
  35. template <typename Iter, typename Self>
  36. class proxy<Iter, Self, std::bidirectional_iterator_tag> : public facade<Self> {
  37. private:
  38. Iter impl_;
  39. public:
  40. proxy(Iter impl = {}) : impl_(impl) {}
  41. template <typename... Args>
  42. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  43. decltype(auto) dereference() const { return *impl_; }
  44. void increment() { ++impl_; }
  45. void decrement() { --impl_; }
  46. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  47. protected:
  48. auto & impl() const { return impl_; }
  49. };
  50. template <typename Iter, typename Self>
  51. class proxy<Iter, Self, std::random_access_iterator_tag> : public facade<Self> {
  52. public:
  53. using difference_type = typename std::iterator_traits<Iter>::difference_type;
  54. private:
  55. Iter impl_;
  56. public:
  57. proxy(Iter impl = {}) : impl_(impl) {}
  58. template <typename... Args>
  59. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  60. decltype(auto) dereference() const { return *impl_; }
  61. void advance(difference_type off) { impl_ += off; }
  62. // This shouldn't need to be implemented, but for some reason my traits
  63. // are not correctly deducing here.
  64. bool equal_to(Self const & other) const { return distance_to(other) == 0; }
  65. difference_type distance_to(Self const & other) const {
  66. return other.impl_ - impl_;
  67. }
  68. protected:
  69. auto & impl() const { return impl_; }
  70. };
  71. }