proxy.h 2.6 KB

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