proxy.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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>
  41. : public facade<Self> {
  42. private:
  43. Iter impl_;
  44. public:
  45. proxy(Iter impl = {}) : impl_(impl) {}
  46. template <typename... Args>
  47. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  48. decltype(auto) dereference() const { return *impl_; }
  49. void increment() { ++impl_; }
  50. void decrement() { --impl_; }
  51. bool equal_to(Self const & other) const { return impl_ == other.impl_; }
  52. protected:
  53. auto & impl() const { return impl_; }
  54. };
  55. template <typename Iter, typename Self>
  56. class proxy<Iter, Self, std::random_access_iterator_tag>
  57. : public facade<Self> {
  58. public:
  59. using difference_type =
  60. typename std::iterator_traits<Iter>::difference_type;
  61. private:
  62. Iter impl_;
  63. public:
  64. proxy(Iter impl = {}) : impl_(impl) {}
  65. template <typename... Args>
  66. proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
  67. decltype(auto) dereference() const { return *impl_; }
  68. void advance(difference_type off) { impl_ += off; }
  69. // This shouldn't need to be implemented, but for some reason my traits
  70. // are not correctly deducing here.
  71. bool equal_to(Self const & other) const { return distance_to(other) == 0; }
  72. difference_type distance_to(Self const & other) const {
  73. return other.impl_ - impl_;
  74. }
  75. protected:
  76. auto & impl() const { return impl_; }
  77. };
  78. }