Wayverb
mapping_iterator_adapter.h
1 #pragma once
2 
3 #include <iterator>
4 #include <type_traits>
5 
6 namespace util {
7 
14 template <typename It, typename Mapper>
16 public:
17  using iterator_category =
18  typename std::iterator_traits<It>::iterator_category;
19 
20  using value_type = decltype(std::declval<Mapper>()(*std::declval<It>()));
21  using difference_type = typename std::iterator_traits<It>::difference_type;
22  using reference = std::add_lvalue_reference_t<value_type>;
23  using pointer = std::add_pointer_t<reference>;
24 
25  constexpr mapping_iterator_adapter() = default;
26  constexpr explicit mapping_iterator_adapter(It it)
27  : it_(std::move(it)) {}
28 
29  constexpr explicit mapping_iterator_adapter(It it, Mapper mapper)
30  : it_(std::move(it))
31  , mapper_(std::move(mapper)) {}
32 
33  template <class U, class V>
34  constexpr mapping_iterator_adapter(
35  const mapping_iterator_adapter<U, V>& other)
36  : it_(other.it_)
37  , mapper_(other.mapper_) {}
38 
39  template <class U, class V>
40  void swap(mapping_iterator_adapter<U, V>& other) noexcept {
41  using std::swap;
42  swap(it_, other.it_);
43  swap(mapper_, other.mapper_);
44  }
45 
46  template <class U, class V>
47  constexpr mapping_iterator_adapter& operator=(
49  swap(other);
50  return *this;
51  }
52 
53  constexpr mapping_iterator_adapter(const mapping_iterator_adapter&) =
54  default;
55  constexpr mapping_iterator_adapter(mapping_iterator_adapter&&) noexcept =
56  default;
57  constexpr mapping_iterator_adapter& operator=(
58  const mapping_iterator_adapter&) = default;
59  constexpr mapping_iterator_adapter& operator=(
60  mapping_iterator_adapter&&) noexcept = default;
61 
62  constexpr It base() const { return it_; }
63 
64  constexpr value_type operator*() const { return mapper_(*it_); }
65 
66  constexpr auto operator-> () const { return &mapper_(*it_); }
67 
68  constexpr value_type operator[](difference_type n) const {
69  return mapper_(it_[n]);
70  }
71 
72  constexpr mapping_iterator_adapter& operator++() {
73  ++it_;
74  return *this;
75  }
76  constexpr mapping_iterator_adapter& operator--() {
77  --it_;
78  return *this;
79  }
80 
81  constexpr mapping_iterator_adapter operator++(int) {
82  return mapping_iterator_adapter{it_++, mapper_};
83  }
84  constexpr mapping_iterator_adapter operator--(int) {
85  return mapping_iterator_adapter{it_--, mapper_};
86  }
87 
88  constexpr mapping_iterator_adapter operator+(difference_type n) const {
89  auto ret = *this;
90  return ret += n;
91  }
92  constexpr mapping_iterator_adapter operator-(difference_type n) const {
93  auto ret = *this;
94  return ret -= n;
95  }
96 
97  constexpr mapping_iterator_adapter& operator+=(difference_type n) {
98  it_ += n;
99  return *this;
100  }
101 
102  constexpr mapping_iterator_adapter& operator-=(difference_type n) {
103  it_ -= n;
104  return *this;
105  }
106 
107 private:
108  It it_;
109  Mapper mapper_;
110 
111  template <typename U, typename V>
112  friend class mapping_iterator_adapter;
113 };
114 
115 // comparisons ///////////////////////////////////////////////////////////////
116 
117 template <class A, class B, class C, class D>
118 constexpr bool operator==(const mapping_iterator_adapter<A, B>& lhs,
119  const mapping_iterator_adapter<C, D>& rhs) {
120  return lhs.base() == rhs.base();
121 }
122 
123 template <class A, class B, class C, class D>
124 constexpr bool operator!=(const mapping_iterator_adapter<A, B>& lhs,
125  const mapping_iterator_adapter<C, D>& rhs) {
126  return lhs.base() != rhs.base();
127 }
128 
129 template <class A, class B, class C, class D>
130 constexpr bool operator<(const mapping_iterator_adapter<A, B>& lhs,
131  const mapping_iterator_adapter<C, D>& rhs) {
132  return lhs.base() < rhs.base();
133 }
134 
135 template <class A, class B, class C, class D>
136 constexpr bool operator<=(const mapping_iterator_adapter<A, B>& lhs,
137  const mapping_iterator_adapter<C, D>& rhs) {
138  return lhs.base() <= rhs.base();
139 }
140 
141 template <class A, class B, class C, class D>
142 constexpr bool operator>(const mapping_iterator_adapter<A, B>& lhs,
143  const mapping_iterator_adapter<C, D>& rhs) {
144  return lhs.base() > rhs.base();
145 }
146 
147 template <class A, class B, class C, class D>
148 constexpr bool operator>=(const mapping_iterator_adapter<A, B>& lhs,
149  const mapping_iterator_adapter<C, D>& rhs) {
150  return lhs.base() >= rhs.base();
151 }
152 
153 // non-member arithmetic ops /////////////////////////////////////////////////
154 
155 template <class U, class V>
156 constexpr mapping_iterator_adapter<U, V> operator+(
157  typename mapping_iterator_adapter<U, V>::difference_type n,
158  const mapping_iterator_adapter<U, V>& it) {
159  return it + n;
160 }
161 
162 template <class U, class V>
163 constexpr mapping_iterator_adapter<U, V> operator-(
164  typename mapping_iterator_adapter<U, V>::difference_type n,
165  const mapping_iterator_adapter<U, V>& it) {
166  return it - n;
167 }
168 
169 template <class U, class V>
170 constexpr typename mapping_iterator_adapter<U, V>::difference_type operator-(
173  return a.base() - b.base();
174 }
175 
176 // make iterators quickly ////////////////////////////////////////////////////
177 
178 template <class U, class V>
179 constexpr mapping_iterator_adapter<U, V> make_mapping_iterator_adapter(
180  U it, V mapper) {
181  return mapping_iterator_adapter<U, V>{std::move(it), std::move(mapper)};
182 }
183 
184 } // namespace util
Definition: allocator.h:6
Definition: mapping_iterator_adapter.h:15