proxy.h 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. decltype(auto) dereference() const { return *impl_; }
  18. void increment() { ++impl_; }
  19. bool equal_to(proxy const & other) const { return impl_ == other.impl_; }
  20. protected:
  21. auto & impl() const { return impl_; }
  22. };
  23. template <typename Iter, typename Self>
  24. class proxy<Iter, Self, std::forward_iterator_tag> : public facade<Self> {
  25. private:
  26. Iter impl_;
  27. public:
  28. proxy(Iter impl = {}) : impl_(impl) {}
  29. decltype(auto) dereference() const { return *impl_; }
  30. void increment() { ++impl_; }
  31. bool equal_to(proxy 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>
  37. : public facade<Self> {
  38. private:
  39. Iter impl_;
  40. public:
  41. proxy(Iter impl = {}) : impl_(impl) {}
  42. decltype(auto) dereference() const { return *impl_; }
  43. void increment() { ++impl_; }
  44. void decrement() { --impl_; }
  45. bool equal_to(proxy const & other) const { return impl_ == other.impl_; }
  46. protected:
  47. auto & impl() const { return impl_; }
  48. };
  49. template <typename Iter, typename Self>
  50. class proxy<Iter, Self, std::random_access_iterator_tag>
  51. : public facade<Self> {
  52. public:
  53. using difference_type =
  54. typename std::iterator_traits<Iter>::difference_type;
  55. private:
  56. Iter impl_;
  57. public:
  58. proxy(Iter impl = {}) : impl_(impl) {}
  59. decltype(auto) dereference() const { return *impl_; }
  60. void advance(difference_type off) { impl_ += off; }
  61. difference_type distance_to(proxy const & other) const {
  62. return impl_ - other.impl_;
  63. }
  64. protected:
  65. auto & impl() const { return impl_; }
  66. };
  67. }