LIEF: Library to Instrument Executable Formats Version 0.15.1
Loading...
Searching...
No Matches
iterators.hpp
Go to the documentation of this file.
1/* Copyright 2017 - 2024 R. Thomas
2 * Copyright 2017 - 2024 Quarkslab
3 * Copyright 2017 - 2021, NVIDIA CORPORATION. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#ifndef LIEF_ITERATORS_H
18#define LIEF_ITERATORS_H
19#include <ostream>
20#include <cmath>
21#include <cstddef>
22#include <cassert>
23#include <iterator>
24#include <functional>
25#include <algorithm>
26#include <type_traits>
27#include <vector>
28
29
30namespace LIEF {
31
32template<class T>
33using decay_t = typename std::decay<T>::type;
34
35template<class T>
36using add_const_t = typename std::add_const<T>::type;
37
38template<class T>
39using remove_const_t = typename std::remove_const<T>::type;
40
41template< class T >
42using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
43
44
46template<class T, typename U = typename decay_t<T>::value_type,
47 class ITERATOR_T = typename decay_t<T>::iterator>
49 public:
50 using iterator_category = std::bidirectional_iterator_tag;
52 using difference_type = ptrdiff_t;
53 using pointer = typename std::remove_pointer<U>::type*;
54 using reference = typename std::remove_pointer<U>::type&;
55
56 using container_type = T; // e.g. std::vector<Section*>&
57 using DT_VAL = U; // e.g. Section*
58 using DT = decay_t<T>; // e.g. std::vector<Section>
61
62 ref_iterator(T container) :
63 container_{std::forward<T>(container)}
64 {
65 it_ = std::begin(container_);
66 }
67
69 container_{copy.container_},
70 it_{std::begin(container_)},
71 distance_{copy.distance_}
72 {
73 std::advance(it_, distance_);
74 }
75
76
78 swap(other);
79 return *this;
80 }
81
82 void swap(ref_iterator& other) noexcept {
83 std::swap(const_cast<add_lvalue_reference_t<remove_const_t<DT>>>(container_),
84 const_cast<add_lvalue_reference_t<remove_const_t<DT>>>(other.container_));
85 std::swap(it_, other.it_);
86 std::swap(distance_, other.distance_);
87 }
88
89
91 it_ = std::next(it_);
92 distance_++;
93 return *this;
94 }
95
97 ref_iterator retval = *this;
98 ++(*this);
99 return retval;
100 }
101
103 if (it_ != std::begin(container_)) {
104 it_ = std::prev(it_);
105 distance_--;
106 }
107 return *this;
108 }
109
111 ref_iterator retval = *this;
112 --(*this);
113 return retval;
114 }
115
116
118 std::advance(it_, movement);
119 distance_ += movement;
120 return *this;
121 }
122
123
125 return (*this) += -movement;
126 }
127
128
129 typename std::enable_if<!std::is_const<ref_t>::value, remove_const_t<ref_t>>::type
130 operator[](size_t n) {
131 return const_cast<remove_const_t<ref_t>>(static_cast<const ref_iterator*>(this)->operator[](n));
132 }
133
134
136 assert(n < size() && "integrity error: out of bound");
137
138 auto* no_const_this = const_cast<ref_iterator*>(this);
139
140 typename ref_iterator::difference_type saved_dist = std::distance(std::begin(no_const_this->container_), no_const_this->it_);
141 no_const_this->it_ = std::begin(no_const_this->container_);
142 std::advance(no_const_this->it_, n);
143
144 auto&& v = const_cast<add_const_t<ref_t>>(no_const_this->operator*());
145
146 no_const_this->it_ = std::begin(no_const_this->container_);
147 std::advance(no_const_this->it_, saved_dist);
148
149 return v;
150 }
151
153 ref_iterator tmp = *this;
154 return tmp += n;
155 }
156
157
159 ref_iterator tmp = *this;
160 return tmp -= n;
161 }
162
163
165 return distance_ - rhs.distance_;
166 }
167
168 bool operator<(const ref_iterator& rhs) const {
169 return (rhs - *this) > 0;
170 }
171
172
173 bool operator>(const ref_iterator& rhs) const {
174 return rhs < *this;
175 }
176
177
178 bool operator>=(const ref_iterator& rhs) const {
179 return !(*this < rhs);
180 }
181
182
183 bool operator<=(const ref_iterator& rhs) const {
184 return !(*this > rhs);
185 }
186
188 return container_;
189 }
190
192 return begin();
193 }
194
196 ref_iterator it = ref_iterator{container_};
197 it.it_ = std::end(it.container_);
198 it.distance_ = it.size();
199 return it;
200 }
201
203 return end();
204 }
205
206 bool operator==(const ref_iterator& other) const {
207 return (size() == other.size() && distance_ == other.distance_);
208 }
209
210 bool operator!=(const ref_iterator& other) const {
211 return !(*this == other);
212 }
213
214 size_t size() const {
215 return container_.size();
216 }
217
218 bool empty() const {
219 return container_.empty();
220 }
221
222 typename std::enable_if<!std::is_const<ref_t>::value, remove_const_t<ref_t>>::type
224 return const_cast<remove_const_t<ref_t>>(static_cast<const ref_iterator*>(this)->operator*());
225 }
226
227 template<typename V = DT_VAL>
228 typename std::enable_if<std::is_pointer<V>::value, add_const_t<ref_t>>::type
229 operator*() const {
230 assert(*it_ && "integrity error: nullptr");
231 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
232 }
233
234 template<typename V = DT_VAL>
235 typename std::enable_if<!std::is_pointer<V>::value, add_const_t<ref_t>>::type
236 operator*() const {
237 return const_cast<add_const_t<ref_t>>(*(it_));
238 }
239
240
241 typename std::enable_if<!std::is_const<pointer_t>::value, pointer_t>::type
243 return const_cast<remove_const_t<pointer_t>>(static_cast<const ref_iterator*>(this)->operator->());
244 }
245
247 return const_cast<add_const_t<pointer_t>>(&(operator*()));
248 }
249
250 protected:
251 T container_;
252 ITERATOR_T it_;
253 typename ref_iterator::difference_type distance_{};
254};
255
256
258template<class T, typename U = typename decay_t<T>::value_type, class CT = typename std::add_const<T>::type>
260
261
263template<class T, typename U = typename decay_t<T>::value_type,
264 class ITERATOR_T = typename decay_t<T>::iterator>
266
267 public:
268 using iterator_category = std::forward_iterator_tag;
270 using difference_type = ptrdiff_t;
271 using pointer = typename std::remove_pointer<U>::type*;
272 using reference = typename std::remove_pointer<U>::type&;
273
274 using container_type = T;
275 using DT_VAL = U;
276 using DT = decay_t<T>;
279 using filter_t = std::function<bool (const typename DT::value_type&)>;
280
281 filter_iterator(T container, filter_t filter) :
282 container_{std::forward<T>(container)},
283 filters_{}
284 {
285
286 it_ = std::begin(container_);
287
288 filters_.push_back(filter),
289 it_ = std::begin(container_);
290
291 if (it_ != std::end(container_)) {
292 if (!std::all_of(std::begin(filters_), std::end(filters_), [this] (const filter_t& f) {return f(*it_);})) {
293 next();
294 }
295 }
296 }
297
298 filter_iterator(T container, const std::vector<filter_t>& filters) :
299 container_{std::forward<T>(container)},
300 filters_{filters}
301 {
302
303 it_ = std::begin(container_);
304
305 if (it_ != std::end(container_)) {
306 if (!std::all_of(std::begin(filters_), std::end(filters_), [this] (const filter_t& f) {return f(*it_);})) {
307 next();
308 }
309 }
310 }
311
312 filter_iterator(T container) :
313 container_{std::forward<T>(container)},
314 filters_{}
315 {
316 it_ = std::begin(container_);
317 }
318
320 container_{copy.container_},
321 it_{std::begin(container_)},
322 filters_{copy.filters_},
323 distance_{copy.distance_}
324 {
325 std::advance(it_, distance_);
326 }
327
329 swap(other);
330 return *this;
331 }
332
333 void swap(filter_iterator& other) noexcept {
334 std::swap(const_cast<remove_const_t<DT>&>(container_), const_cast<remove_const_t<DT>&>(other.container_));
335 std::swap(it_, other.it_);
336 std::swap(filters_, other.filters_);
337 std::swap(size_c_, other.size_c_);
338 std::swap(distance_, other.distance_);
339 }
340
341
343 filters_.push_back(func);
344 size_c_ = 0;
345 return *this;
346 }
347
349 next();
350 return *this;
351 }
352
354 filter_iterator retval = *this;
355 ++(*this);
356 return retval;
357 }
358
360 return {container_, filters_};
361 }
362
364 return begin();
365 }
366
368 // we don't need filter for the end iterator
369 filter_iterator it_end{container_};
370
371 it_end.it_ = it_end.container_.end();
372 it_end.distance_ = it_end.container_.size();
373
374 return it_end;
375 }
376
378 return end();
379 }
380
381 typename std::enable_if<!std::is_const<ref_t>::value, remove_const_t<ref_t>>::type
383 return const_cast<remove_const_t<ref_t>>(static_cast<const filter_iterator*>(this)->operator*());
384 }
385
386 template<typename V = DT_VAL>
387 typename std::enable_if<std::is_pointer<V>::value, add_const_t<ref_t>>::type
388 operator*() const {
389 assert(*it_ && "integrity error: nullptr");
390 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
391 }
392
393 template<typename V = DT_VAL>
394 typename std::enable_if<!std::is_pointer<V>::value, add_const_t<ref_t>>::type
395 operator*() const {
396 return const_cast<add_const_t<ref_t>>(*(it_));
397 }
398
399
400 typename std::enable_if<!std::is_const<ref_t>::value, remove_const_t<ref_t>>::type
401 operator[](size_t n) {
402 return const_cast<remove_const_t<ref_t>>(static_cast<const filter_iterator*>(this)->operator[](n));
403 }
404
406 assert(n < size() && "integrity error: out of bound");
407
408 auto it = begin();
409 std::advance(it, n);
410 return const_cast<add_const_t<ref_t>>(*it);
411 }
412
413
414 typename std::enable_if<!std::is_const<pointer_t>::value, pointer_t>::type
416 return const_cast<remove_const_t<pointer_t>>(static_cast<const filter_iterator*>(this)->operator->());
417 }
418
420 return const_cast<add_const_t<pointer_t>>(&(operator*()));
421 }
422
423 size_t size() const {
424 if (filters_.empty()) {
425 return container_.size();
426 }
427
428 if (size_c_ > 0) {
429 return size_c_;
430 }
431 filter_iterator it = begin();
432 size_t size = 0;
433
434 auto end_iter = std::end(it);
435 for (; it != end_iter; ++it) ++size;
436 size_c_ = size;
437 return size_c_;
438 }
439
440
441 bool empty() const {
442 return size() == 0;
443 }
444
445
446 bool operator==(const filter_iterator& other) const {
447 return (container_.size() == other.container_.size() && distance_ == other.distance_);
448 }
449
450 bool operator!=(const filter_iterator& other) const {
451 return !(*this == other);
452 }
453
454 protected:
455 void next() {
456 if (it_ == std::end(container_)) {
457 distance_ = container_.size();
458 return;
459 }
460
461 do {
462 it_ = std::next(it_);
463 distance_++;
464 } while(it_ != std::end(container_) &&
465 !std::all_of(std::begin(filters_), std::end(filters_),
466 [this] (const filter_t& f) { return f(*it_); }));
467
468 }
469
470
471 mutable size_t size_c_ = 0;
472 T container_;
473 ITERATOR_T it_;
474 std::vector<filter_t> filters_;
475 typename filter_iterator::difference_type distance_ = 0;
476};
477
479template<class T, typename U = typename decay_t<T>::value_type,
480 class CT = typename std::add_const<T>::type>
482
483
484template <typename IteratorT>
486 public:
487 using IteratorTy = IteratorT;
488 iterator_range(IteratorT it_begin, IteratorT it_end)
489 : begin_(std::move(it_begin)),
490 end_(std::move(it_end)) {}
491
492 IteratorT begin() const { return begin_; }
493 IteratorT end() const { return end_; }
494 bool empty() const { return begin_ == end_; }
495 private:
496 IteratorT begin_;
497 IteratorT end_;
498};
499
500template <class T> iterator_range<T> make_range(T x, T y) {
501 return iterator_range<T>(std::move(x), std::move(y));
502}
503
504}
505
506#endif
Iterator which return a ref on container's values given predicates.
Definition iterators.hpp:265
std::enable_if<!std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:395
bool operator==(const filter_iterator &other) const
Definition iterators.hpp:446
filter_iterator(const filter_iterator &copy)
Definition iterators.hpp:319
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:405
filter_iterator cend() const
Definition iterators.hpp:377
typename std::remove_pointer< U >::type * pointer
Definition iterators.hpp:271
filter_iterator(T container, filter_t filter)
Definition iterators.hpp:281
std::forward_iterator_tag iterator_category
Definition iterators.hpp:268
filter_iterator(T container)
Definition iterators.hpp:312
void swap(filter_iterator &other) noexcept
Definition iterators.hpp:333
filter_iterator & operator++()
Definition iterators.hpp:348
std::enable_if<!std::is_const< pointer_t >::value, pointer_t >::type operator->()
Definition iterators.hpp:415
filter_iterator(T container, const std::vector< filter_t > &filters)
Definition iterators.hpp:298
filter_iterator end() const
Definition iterators.hpp:367
typename filter_iterator::pointer pointer_t
Definition iterators.hpp:278
filter_iterator & operator=(filter_iterator other)
Definition iterators.hpp:328
decay_t< U > value_type
Definition iterators.hpp:269
typename filter_iterator::reference ref_t
Definition iterators.hpp:277
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator*()
Definition iterators.hpp:382
filter_iterator begin() const
Definition iterators.hpp:359
bool empty() const
Definition iterators.hpp:441
U DT_VAL
Definition iterators.hpp:275
ptrdiff_t difference_type
Definition iterators.hpp:270
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:419
std::function< bool(const typename DT::value_type &)> filter_t
Definition iterators.hpp:279
size_t size() const
Definition iterators.hpp:423
std::enable_if< std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:388
bool operator!=(const filter_iterator &other) const
Definition iterators.hpp:450
T container_type
Definition iterators.hpp:274
filter_iterator operator++(int)
Definition iterators.hpp:353
decay_t< T > DT
Definition iterators.hpp:276
filter_iterator cbegin() const
Definition iterators.hpp:363
filter_iterator & def(filter_t func)
Definition iterators.hpp:342
typename std::remove_pointer< U >::type & reference
Definition iterators.hpp:272
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator[](size_t n)
Definition iterators.hpp:401
Definition iterators.hpp:485
IteratorT begin() const
Definition iterators.hpp:492
IteratorT end() const
Definition iterators.hpp:493
bool empty() const
Definition iterators.hpp:494
iterator_range(IteratorT it_begin, IteratorT it_end)
Definition iterators.hpp:488
IteratorT IteratorTy
Definition iterators.hpp:487
Iterator which returns reference on container's values.
Definition iterators.hpp:48
bool operator<=(const ref_iterator &rhs) const
Definition iterators.hpp:183
ref_iterator & operator--()
Definition iterators.hpp:102
size_t size() const
Definition iterators.hpp:214
ref_iterator & operator++()
Definition iterators.hpp:90
void swap(ref_iterator &other) noexcept
Definition iterators.hpp:82
bool operator<(const ref_iterator &rhs) const
Definition iterators.hpp:168
ref_iterator operator-(typename ref_iterator::difference_type n) const
Definition iterators.hpp:158
ref_iterator operator++(int)
Definition iterators.hpp:96
ref_iterator begin() const
Definition iterators.hpp:187
T container_type
Definition iterators.hpp:56
typename ref_iterator::reference ref_t
Definition iterators.hpp:59
ref_iterator operator--(int)
Definition iterators.hpp:110
ref_iterator cend() const
Definition iterators.hpp:202
ref_iterator & operator+=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:117
std::bidirectional_iterator_tag iterator_category
Definition iterators.hpp:50
ptrdiff_t difference_type
Definition iterators.hpp:52
ref_iterator operator+(typename ref_iterator::difference_type n) const
Definition iterators.hpp:152
typename std::remove_pointer< U >::type & reference
Definition iterators.hpp:54
ref_iterator cbegin() const
Definition iterators.hpp:191
bool empty() const
Definition iterators.hpp:218
ref_iterator & operator=(ref_iterator other)
Definition iterators.hpp:77
typename std::remove_pointer< U >::type * pointer
Definition iterators.hpp:53
bool operator!=(const ref_iterator &other) const
Definition iterators.hpp:210
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator[](size_t n)
Definition iterators.hpp:130
bool operator>(const ref_iterator &rhs) const
Definition iterators.hpp:173
bool operator>=(const ref_iterator &rhs) const
Definition iterators.hpp:178
ref_iterator(const ref_iterator &copy)
Definition iterators.hpp:68
ref_iterator end() const
Definition iterators.hpp:195
std::enable_if< std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:229
std::enable_if<!std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:236
ref_iterator & operator-=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:124
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:135
decay_t< U > value_type
Definition iterators.hpp:51
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator*()
Definition iterators.hpp:223
ref_iterator::difference_type operator-(const ref_iterator &rhs) const
Definition iterators.hpp:164
U DT_VAL
Definition iterators.hpp:57
typename ref_iterator::pointer pointer_t
Definition iterators.hpp:60
ref_iterator(T container)
Definition iterators.hpp:62
std::enable_if<!std::is_const< pointer_t >::value, pointer_t >::type operator->()
Definition iterators.hpp:242
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:246
bool operator==(const ref_iterator &other) const
Definition iterators.hpp:206
decay_t< T > DT
Definition iterators.hpp:58
LIEF namespace.
Definition Abstract/Binary.hpp:32
typename std::add_lvalue_reference< T >::type add_lvalue_reference_t
Definition iterators.hpp:42
typename std::remove_const< T >::type remove_const_t
Definition iterators.hpp:39
iterator_range< T > make_range(T x, T y)
Definition iterators.hpp:500
typename std::decay< T >::type decay_t
Definition iterators.hpp:33
typename std::add_const< T >::type add_const_t
Definition iterators.hpp:36