LIEF: Library to Instrument Executable Formats Version 2.0.0
Loading...
Searching...
No Matches
iterators.hpp
Go to the documentation of this file.
1/* Copyright 2017 - 2026 R. Thomas
2 * Copyright 2017 - 2026 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 <type_traits>
20#include <algorithm>
21#include <cassert>
22#include <cstddef>
23#include <functional>
24#include <iterator>
25#include <vector>
26
28
29namespace LIEF {
30
31template<class T>
32using decay_t = std::decay_t<T>;
33
34template<class T>
35using add_const_t = std::add_const_t<T>;
36
37template<class T>
38using remove_const_t = std::remove_const_t<T>;
39
40template<class T>
41using add_lvalue_reference_t = std::add_lvalue_reference_t<T>;
42
43
45template<class T, typename U = typename decay_t<T>::value_type,
46 class ITERATOR_T = typename decay_t<T>::iterator>
48 template<class, typename, class>
49 friend class ref_iterator;
50
51 public:
52 using iterator_category = std::bidirectional_iterator_tag;
54 using difference_type = ptrdiff_t;
55 using pointer = std::remove_pointer_t<U>*;
56 using reference = std::remove_pointer_t<U>&;
57
58 using container_type = T; // e.g. std::vector<Section*>&
59 using DT_VAL = U; // e.g. Section*
60 using DT = decay_t<T>; // e.g. std::vector<Section>
63
64 ref_iterator(ref_iterator&& other) noexcept :
65 container_{std::forward<T>(other.container_)},
66 it_{std::begin(container_)},
67 distance_{other.distance_} {
68 std::advance(it_, distance_);
69 }
70
71 ref_iterator& operator=(ref_iterator&& other) noexcept {
72 if (other == &this) {
73 return *this;
74 }
75 container_ = std::forward<T>(other.container_);
76 it_ = std::begin(other.container_);
77 distance_ = other.distance_;
78 std::advance(it_, distance_);
79 return *this;
80 }
81
82 template<class T2, typename U2, class IT2,
83 typename = std::enable_if_t<
84 !std::is_same_v<ref_iterator, ref_iterator<T2, U2, IT2>> &&
85 std::is_same_v<decay_t<T>, decay_t<T2>>
86 >>
88 container_{
89 const_cast<add_lvalue_reference_t<remove_const_t<DT>>>(other.container_)
90 },
91 it_{std::begin(container_)},
92 distance_{other.distance_} {
93 std::advance(it_, distance_);
94 }
95
96 template<class T2, typename U2, class IT2,
97 typename = std::enable_if_t<
98 !std::is_same_v<ref_iterator, ref_iterator<T2, U2, IT2>> &&
99 std::is_same_v<decay_t<T>, decay_t<T2>>
100 >>
101 // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
103 container_{const_cast<add_lvalue_reference_t<remove_const_t<DT>>>(
104 std::forward<T2>(other.container_)
105 )},
106 it_{std::begin(container_)},
107 distance_{other.distance_} {
108 std::advance(it_, distance_);
109 }
110
111 ~ref_iterator() = default;
112
113 ref_iterator(T container) :
114 container_{std::forward<T>(container)},
115 it_(std::begin(container_)) {}
116
118 container_{copy.container_},
119 it_{std::begin(container_)},
120 distance_{copy.distance_} {
121 std::advance(it_, distance_);
122 }
123
125 swap(other);
126 return *this;
127 }
128
129 void swap(ref_iterator& other) noexcept {
130 std::swap(
131 const_cast<add_lvalue_reference_t<remove_const_t<DT>>>(container_),
132 const_cast<add_lvalue_reference_t<remove_const_t<DT>>>(other.container_)
133 );
134 std::swap(it_, other.it_);
135 std::swap(distance_, other.distance_);
136 }
137
138
140 it_ = std::next(it_);
141 distance_++;
142 return *this;
143 }
144
146 ref_iterator retval = *this;
147 ++(*this);
148 return retval;
149 }
150
152 if (it_ != std::begin(container_)) {
153 it_ = std::prev(it_);
154 distance_--;
155 }
156 return *this;
157 }
158
160 ref_iterator retval = *this;
161 --(*this);
162 return retval;
163 }
164
165
167 const typename ref_iterator::difference_type& movement
169 std::advance(it_, movement);
170 distance_ += movement;
171 return *this;
172 }
173
174
176 const typename ref_iterator::difference_type& movement
178 return (*this) += -movement;
179 }
180
181
182 std::enable_if_t<!std::is_const_v<ref_t>, remove_const_t<ref_t>>
183 operator[](size_t n) {
184 return const_cast<remove_const_t<ref_t>>(
185 static_cast<const ref_iterator*>(this)->operator[](n)
186 );
187 }
188
189
191 assert(n < size() && "integrity error: out of bound");
192
193 auto* no_const_this = const_cast<ref_iterator*>(this);
194
195 typename ref_iterator::difference_type saved_dist =
196 std::distance(std::begin(no_const_this->container_), no_const_this->it_);
197 no_const_this->it_ = std::begin(no_const_this->container_);
198 std::advance(no_const_this->it_, n);
199
200 auto&& v = const_cast<add_const_t<ref_t>>(no_const_this->operator*());
201
202 no_const_this->it_ = std::begin(no_const_this->container_);
203 std::advance(no_const_this->it_, saved_dist);
204
205 return v;
206 }
207
209 ref_iterator tmp = *this;
210 return tmp += n;
211 }
212
213
215 ref_iterator tmp = *this;
216 return tmp -= n;
217 }
218
219
221 return distance_ - rhs.distance_;
222 }
223
224 bool operator<(const ref_iterator& rhs) const {
225 return (rhs - *this) > 0;
226 }
227
228
229 bool operator>(const ref_iterator& rhs) const {
230 return rhs < *this;
231 }
232
233
234 bool operator>=(const ref_iterator& rhs) const {
235 return !(*this < rhs);
236 }
237
238
239 bool operator<=(const ref_iterator& rhs) const {
240 return !(*this > rhs);
241 }
242
244 return container_;
245 }
246
248 return begin();
249 }
250
252 ref_iterator it = ref_iterator{container_};
253 it.it_ = std::end(it.container_);
254 it.distance_ = it.size();
255 return it;
256 }
257
259 return end();
260 }
261
262 bool operator==(const ref_iterator& other) const {
263 return (size() == other.size() && distance_ == other.distance_);
264 }
265
266 bool operator!=(const ref_iterator& other) const {
267 return !(*this == other);
268 }
269
270 size_t size() const {
271 return container_.size();
272 }
273
274 bool empty() const {
275 return container_.empty();
276 }
277
278 std::enable_if_t<!std::is_const_v<ref_t>, remove_const_t<ref_t>> operator*() {
279 return const_cast<remove_const_t<ref_t>>(
280 static_cast<const ref_iterator*>(this)->operator*()
281 );
282 }
283
284 template<typename V = DT_VAL>
285 std::enable_if_t<std::is_pointer_v<V>, add_const_t<ref_t>> operator*() const {
286 assert(*it_ && "integrity error: nullptr");
287 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
288 }
289
290 template<typename V = DT_VAL>
291 std::enable_if_t<!std::is_pointer_v<V>, add_const_t<ref_t>> operator*() const {
292 return const_cast<add_const_t<ref_t>>(*(it_));
293 }
294
295
296 std::enable_if_t<!std::is_const_v<pointer_t>, pointer_t> operator->() {
297 return const_cast<remove_const_t<pointer_t>>(
298 static_cast<const ref_iterator*>(this)->operator->()
299 );
300 }
301
303 return const_cast<add_const_t<pointer_t>>(&(operator*()));
304 }
305
306 protected:
307 T container_;
308 ITERATOR_T it_;
309 typename ref_iterator::difference_type distance_{};
310};
311
312
314template<class T, typename U = typename decay_t<T>::value_type,
315 class CT = std::add_const_t<T>>
318
319
321template<class T, typename U = typename decay_t<T>::value_type,
322 class ITERATOR_T = typename decay_t<T>::iterator>
324
325 public:
326 using iterator_category = std::forward_iterator_tag;
328 using difference_type = ptrdiff_t;
329 using pointer = std::remove_pointer_t<U>*;
330 using reference = std::remove_pointer_t<U>&;
331
332 using container_type = T;
333 using DT_VAL = U;
334 using DT = decay_t<T>;
337 using filter_t = std::function<bool(const typename DT::value_type&)>;
338
340 size_c_(other.size_c_),
341 size_cached_(other.size_cached_),
342 container_(std::forward<T>(other.container_)),
343 it_(std::begin(container_)),
344 filters_{std::move(other.filters_)},
345 distance_(other.distance_) {
346 std::advance(it_, distance_);
347 }
348
350 if (this == &other) {
351 return *this;
352 }
353
354 size_c_ = other.size_c_;
355 size_cached_ = other.size_cached_;
356 container_ = std::forward<T>(other.container_);
357 it_ = std::begin(container_);
358 filters_ = std::move(other.filters_);
359 distance_ = other.distance_;
360
361 std::advance(it_, distance_);
362
363 return *this;
364 }
365
366 ~filter_iterator() = default;
367
368 filter_iterator(T container, filter_t filter) :
369 container_{std::forward<T>(container)},
370 it_(std::begin(container_)),
371 filters_{} {
372
373
374 filters_.push_back(filter);
375
376 if (it_ != std::end(container_)) {
377 if (!std::all_of(std::begin(filters_), std::end(filters_),
378 [this](const filter_t& f) { return f(*it_); }))
379 {
380 next();
381 }
382 }
383 }
384
385 filter_iterator(T container, const std::vector<filter_t>& filters) :
386 container_{std::forward<T>(container)},
387 it_(std::begin(container_)),
388 filters_{filters} {
389
390
391 if (it_ != std::end(container_)) {
392 if (!std::all_of(std::begin(filters_), std::end(filters_),
393 [this](const filter_t& f) { return f(*it_); }))
394 {
395 next();
396 }
397 }
398 }
399
400 filter_iterator(T container) :
401 container_{std::forward<T>(container)},
402 it_(std::begin(container_)),
403 filters_{} {}
404
406 container_{copy.container_},
407 it_{std::begin(container_)},
408 filters_{copy.filters_},
409 distance_{copy.distance_} {
410 std::advance(it_, distance_);
411 }
412
414 swap(other);
415 return *this;
416 }
417
418 void swap(filter_iterator& other) noexcept {
419 std::swap(const_cast<remove_const_t<DT>&>(container_),
420 const_cast<remove_const_t<DT>&>(other.container_));
421 std::swap(it_, other.it_);
422 std::swap(filters_, other.filters_);
423 std::swap(size_c_, other.size_c_);
424 std::swap(size_cached_, other.size_cached_);
425 std::swap(distance_, other.distance_);
426 }
427
428
430 filters_.push_back(func);
431 size_c_ = 0;
432 size_cached_ = false;
433 return *this;
434 }
435
437 next();
438 return *this;
439 }
440
442 filter_iterator retval = *this;
443 ++(*this);
444 return retval;
445 }
446
448 return {container_, filters_};
449 }
450
452 return begin();
453 }
454
456 // we don't need filter for the end iterator
457 filter_iterator it_end{container_};
458
459 it_end.it_ = it_end.container_.end();
460 it_end.distance_ = it_end.container_.size();
461
462 return it_end;
463 }
464
466 return end();
467 }
468
469 std::enable_if_t<!std::is_const_v<ref_t>, remove_const_t<ref_t>> operator*() {
470 return const_cast<remove_const_t<ref_t>>(
471 static_cast<const filter_iterator*>(this)->operator*()
472 );
473 }
474
475 template<typename V = DT_VAL>
476 std::enable_if_t<std::is_pointer_v<V>, add_const_t<ref_t>> operator*() const {
477 assert(*it_ && "integrity error: nullptr");
478 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
479 }
480
481 template<typename V = DT_VAL>
482 std::enable_if_t<!std::is_pointer_v<V>, add_const_t<ref_t>> operator*() const {
483 return const_cast<add_const_t<ref_t>>(*(it_));
484 }
485
486
487 std::enable_if_t<!std::is_const_v<ref_t>, remove_const_t<ref_t>>
488 operator[](size_t n) {
489 return const_cast<remove_const_t<ref_t>>(
490 static_cast<const filter_iterator*>(this)->operator[](n)
491 );
492 }
493
495 assert(n < size() && "integrity error: out of bound");
496
497 auto it = begin();
498 std::advance(it, n);
499 return const_cast<add_const_t<ref_t>>(*it);
500 }
501
502
503 std::enable_if_t<!std::is_const_v<pointer_t>, pointer_t> operator->() {
504 return const_cast<remove_const_t<pointer_t>>(
505 static_cast<const filter_iterator*>(this)->operator->()
506 );
507 }
508
510 return const_cast<add_const_t<pointer_t>>(&(operator*()));
511 }
512
513 size_t size() const {
514 if (filters_.empty()) {
515 return container_.size();
516 }
517
518 if (size_cached_) {
519 return size_c_;
520 }
521 filter_iterator it = begin();
522 size_t size = 0;
523
524 auto end_iter = it.end();
525 for (; it != end_iter; ++it) {
526 ++size;
527 }
528 size_c_ = size;
529 size_cached_ = true;
530 return size_c_;
531 }
532
533
534 bool empty() const {
535 if (filters_.empty()) {
536 return container_.empty();
537 }
538
539 if (size_cached_) {
540 return size_c_ == 0;
541 }
542
543 return begin() == end();
544 }
545
546
547 bool operator==(const filter_iterator& other) const {
548 return (container_.size() == other.container_.size() &&
549 distance_ == other.distance_);
550 }
551
552 bool operator!=(const filter_iterator& other) const {
553 return !(*this == other);
554 }
555
556 protected:
557 void next() {
558 if (it_ == std::end(container_)) {
559 distance_ = container_.size();
560 return;
561 }
562
563 do {
564 it_ = std::next(it_);
565 distance_++;
566 } while (it_ != std::end(container_) &&
567 !std::all_of(std::begin(filters_), std::end(filters_),
568 [this](const filter_t& f) { return f(*it_); }));
569 }
570
571
572 mutable size_t size_c_ = 0;
573 mutable bool size_cached_ = false;
574 T container_;
575 ITERATOR_T it_;
576 std::vector<filter_t> filters_;
577 typename filter_iterator::difference_type distance_ = 0;
578};
579
581template<class T, typename U = typename decay_t<T>::value_type,
582 class CT = std::add_const_t<T>>
585
586// ----------------------------------------------------------------------------
587// This part is taken from LLVM
588// ----------------------------------------------------------------------------
589
590template<typename IteratorT>
592 public:
593 using IteratorTy = IteratorT;
594 using IteratorDecayTy = std::decay_t<IteratorT>;
595
596 template<class T>
597 iterator_range(T&& it_begin, T&& it_end) :
598 begin_(std::forward<T>(it_begin)),
599 end_(std::forward<T>(it_end)) {}
600
601 IteratorT begin() const {
602 return begin_;
603 }
604 IteratorT end() const {
605 return end_;
606 }
607 bool empty() const {
608 return begin_ == end_;
609 }
610
611 class ReferenceProxy {
612 friend iterator_range;
613
614 IteratorDecayTy it_;
615
616 explicit ReferenceProxy(IteratorDecayTy it) :
617 it_(std::move(it)) {}
618
619 public:
620 using reference = decltype(*std::declval<const IteratorDecayTy&>());
621
622 operator reference() const {
623 return *it_;
624 }
625
626 template<class It = IteratorDecayTy>
627 auto operator->() const -> decltype(&*std::declval<const It&>()) {
628 return &*it_;
629 }
630 };
631
632 ReferenceProxy at(typename IteratorDecayTy::difference_type pos) const {
633 static_assert(IsRandomAccess, "at() needs random access iterator");
634 auto it = begin_;
635 std::advance(it, pos);
636 return ReferenceProxy(std::move(it));
637 }
638
639 ReferenceProxy operator[](typename IteratorDecayTy::difference_type pos) const {
640 return at(pos);
641 }
642
643 std::ptrdiff_t size() const {
644 return std::distance(begin_, end_);
645 }
646
647 protected:
648 enum {
649 IsRandomAccess =
650 std::is_base_of_v<std::random_access_iterator_tag,
651 typename IteratorDecayTy::iterator_category>,
652 IsBidirectional =
653 std::is_base_of_v<std::bidirectional_iterator_tag,
654 typename IteratorDecayTy::iterator_category>,
655 };
656
657 private:
658 IteratorT begin_;
659 IteratorT end_;
660};
661
662template<class T>
664 return iterator_range<T>(std::forward<T>(x), std::forward<T>(y));
665}
666
667}
668
669#if LIEF_HAS_STD_RANGES
670template<typename IteratorT>
671inline constexpr bool
672 std::ranges::enable_borrowed_range<LIEF::iterator_range<IteratorT>> = true;
673#endif
674
675namespace LIEF {
676
677
735template<typename DerivedT, typename IteratorCategoryT, typename T,
736 typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T*,
737 typename ReferenceT = T&>
739 public:
740 using iterator_category = IteratorCategoryT;
741 using value_type = T;
742 using difference_type = DifferenceTypeT;
743 using pointer = PointerT;
744 using reference = ReferenceT;
745
746 protected:
747 enum {
748 IsRandomAccess =
749 std::is_base_of_v<std::random_access_iterator_tag, IteratorCategoryT>,
750 IsBidirectional =
751 std::is_base_of_v<std::bidirectional_iterator_tag, IteratorCategoryT>,
752 };
753
759 class ReferenceProxy {
761
762 DerivedT I;
763
764 ReferenceProxy(DerivedT I) :
765 I(std::move(I)) {}
766
767 public:
768 operator ReferenceT() const {
769 return *I;
770 }
771 };
772
777 class PointerProxy {
778 friend iterator_facade_base;
779
780 ReferenceT R;
781
782 template<typename RefT>
783 PointerProxy(RefT&& R) : // NOLINT(bugprone-forwarding-reference-overload)
784 R(std::forward<RefT>(R)) {}
785
786 public:
787 PointerT operator->() const {
788 return &R;
789 }
790 };
791
792 public:
793 DerivedT operator+(DifferenceTypeT n) const {
794 static_assert(std::is_base_of_v<iterator_facade_base, DerivedT>,
795 "Must pass the derived type to this template!");
796 static_assert(IsRandomAccess,
797 "The '+' operator is only defined for random access iterators.");
798 DerivedT tmp = *static_cast<const DerivedT*>(this);
799 tmp += n;
800 return tmp;
801 }
802 friend DerivedT operator+(DifferenceTypeT n, const DerivedT& i) {
803 static_assert(IsRandomAccess,
804 "The '+' operator is only defined for random access iterators.");
805 return i + n;
806 }
807 DerivedT operator-(DifferenceTypeT n) const {
808 static_assert(IsRandomAccess,
809 "The '-' operator is only defined for random access iterators.");
810 DerivedT tmp = *static_cast<const DerivedT*>(this);
811 tmp -= n;
812 return tmp;
813 }
814
815 DerivedT& operator++() {
816 static_assert(std::is_base_of_v<iterator_facade_base, DerivedT>,
817 "Must pass the derived type to this template!");
818 return static_cast<DerivedT*>(this)->operator+=(1);
819 }
820 DerivedT operator++(int) {
821 DerivedT tmp = *static_cast<DerivedT*>(this);
822 ++*static_cast<DerivedT*>(this);
823 return tmp;
824 }
825 DerivedT& operator--() {
826 static_assert(
827 IsBidirectional,
828 "The decrement operator is only defined for bidirectional iterators."
829 );
830 return static_cast<DerivedT*>(this)->operator-=(1);
831 }
832 DerivedT operator--(int) {
833 static_assert(
834 IsBidirectional,
835 "The decrement operator is only defined for bidirectional iterators."
836 );
837 DerivedT tmp = *static_cast<DerivedT*>(this);
838 --*static_cast<DerivedT*>(this);
839 return tmp;
840 }
841
842#ifndef __cpp_impl_three_way_comparison
843 bool operator!=(const DerivedT& RHS) const {
844 return !(static_cast<const DerivedT&>(*this) == RHS);
845 }
846#endif
847
848 bool operator>(const DerivedT& RHS) const {
849 static_assert(
850 IsRandomAccess,
851 "Relational operators are only defined for random access iterators."
852 );
853 return !(static_cast<const DerivedT&>(*this) < RHS) &&
854 !(static_cast<const DerivedT&>(*this) == RHS);
855 }
856 bool operator<=(const DerivedT& RHS) const {
857 static_assert(
858 IsRandomAccess,
859 "Relational operators are only defined for random access iterators."
860 );
861 return !(static_cast<const DerivedT&>(*this) > RHS);
862 }
863 bool operator>=(const DerivedT& RHS) const {
864 static_assert(
865 IsRandomAccess,
866 "Relational operators are only defined for random access iterators."
867 );
868 return !(static_cast<const DerivedT&>(*this) < RHS);
869 }
870
871 PointerProxy operator->() const {
872 return static_cast<const DerivedT*>(this)->operator*();
873 }
874 ReferenceProxy operator[](DifferenceTypeT n) const {
875 static_assert(IsRandomAccess,
876 "Subscripting is only defined for random access iterators.");
877 return static_cast<const DerivedT*>(this)->operator+(n);
878 }
879};
880
886template<typename DerivedT, typename WrappedIteratorT,
887 typename IteratorCategoryT =
888 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
889 typename T = typename std::iterator_traits<WrappedIteratorT>::value_type,
890 typename DifferenceTypeT =
891 typename std::iterator_traits<WrappedIteratorT>::difference_type,
892 typename PointerT = std::conditional_t<
893 std::is_same_v<T, typename std::iterator_traits<WrappedIteratorT>::
894 value_type>,
895 typename std::iterator_traits<WrappedIteratorT>::pointer, T*
896 >,
897 typename ReferenceT = std::conditional_t<
898 std::is_same_v<T, typename std::iterator_traits<WrappedIteratorT>::
899 value_type>,
900 typename std::iterator_traits<WrappedIteratorT>::reference, T&
901 >>
902class iterator_adaptor_base
903 : public iterator_facade_base<DerivedT, IteratorCategoryT, T, DifferenceTypeT,
904 PointerT, ReferenceT> {
905 using BaseT = typename iterator_adaptor_base::iterator_facade_base;
906
907 protected:
908 WrappedIteratorT I;
909
910 iterator_adaptor_base() = default;
911
912 explicit iterator_adaptor_base(WrappedIteratorT u) :
913 I(std::move(u)) {
914 static_assert(std::is_base_of_v<iterator_adaptor_base, DerivedT>,
915 "Must pass the derived type to this template!");
916 }
917
918 const WrappedIteratorT& wrapped() const {
919 return I;
920 }
921
922 public:
923 using difference_type = DifferenceTypeT;
924
926 static_assert(
927 BaseT::IsRandomAccess,
928 "The '+=' operator is only defined for random access iterators."
929 );
930 I += n;
931 return *static_cast<DerivedT*>(this);
932 }
934 static_assert(
935 BaseT::IsRandomAccess,
936 "The '-=' operator is only defined for random access iterators."
937 );
938 I -= n;
939 return *static_cast<DerivedT*>(this);
940 }
941 using BaseT::operator-;
942 difference_type operator-(const DerivedT& RHS) const {
943 static_assert(BaseT::IsRandomAccess,
944 "The '-' operator is only defined for random access iterators.");
945 return I - RHS.I;
946 }
947
948 // We have to explicitly provide ++ and -- rather than letting the facade
949 // forward to += because WrappedIteratorT might not support +=.
950 using BaseT::operator++;
952 ++I;
953 return *static_cast<DerivedT*>(this);
954 }
955 using BaseT::operator--;
957 static_assert(
958 BaseT::IsBidirectional,
959 "The decrement operator is only defined for bidirectional iterators."
960 );
961 --I;
962 return *static_cast<DerivedT*>(this);
963 }
964
965 friend bool operator==(const iterator_adaptor_base& LHS,
966 const iterator_adaptor_base& RHS) {
967 return LHS.I == RHS.I;
968 }
969 friend bool operator<(const iterator_adaptor_base& LHS,
970 const iterator_adaptor_base& RHS) {
971 static_assert(
972 BaseT::IsRandomAccess,
973 "Relational operators are only defined for random access iterators."
974 );
975 return LHS.I < RHS.I;
976 }
977
978 ReferenceT operator*() const {
979 return *I;
980 }
981};
982
992template<typename WrappedIteratorT,
993 typename T =
994 std::remove_reference_t<decltype(**std::declval<WrappedIteratorT>())>>
996 : iterator_adaptor_base<
997 pointee_iterator<WrappedIteratorT, T>, WrappedIteratorT,
998 typename std::iterator_traits<WrappedIteratorT>::iterator_category, T
999 > {
1000 pointee_iterator() = default;
1001 template<typename U>
1002 pointee_iterator(U&& u) : // NOLINT(bugprone-forwarding-reference-overload)
1003 pointee_iterator::iterator_adaptor_base(std::forward<U>(u)) {}
1004
1005 T& operator*() const {
1006 return **this->I;
1007 }
1008};
1009
1010template<typename RangeT,
1011 typename WrappedIteratorT = decltype(std::begin(std::declval<RangeT>()))>
1012iterator_range<pointee_iterator<WrappedIteratorT>>
1013 make_pointee_range(RangeT&& Range) {
1014 using PointeeIteratorT = pointee_iterator<WrappedIteratorT>;
1015 return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
1016 PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
1017}
1018
1019template<typename WrappedIteratorT,
1020 typename T = decltype(&*std::declval<WrappedIteratorT>())>
1022 : public iterator_adaptor_base<
1023 pointer_iterator<WrappedIteratorT, T>, WrappedIteratorT,
1024 typename std::iterator_traits<WrappedIteratorT>::iterator_category, T
1025 > {
1026 mutable T Ptr;
1027
1028 public:
1029 pointer_iterator() = default;
1030
1031 explicit pointer_iterator(WrappedIteratorT u) :
1032 pointer_iterator::iterator_adaptor_base(std::move(u)) {}
1033
1034 T& operator*() const {
1035 return Ptr = &*this->I;
1036 }
1037};
1038
1039template<typename RangeT,
1040 typename WrappedIteratorT = decltype(std::begin(std::declval<RangeT>()))>
1041iterator_range<pointer_iterator<WrappedIteratorT>>
1042 make_pointer_range(RangeT&& Range) {
1043 using PointerIteratorT = pointer_iterator<WrappedIteratorT>;
1044 return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
1045 PointerIteratorT(std::end(std::forward<RangeT>(Range))));
1046}
1047
1048template<typename WrappedIteratorT,
1049 typename T1 =
1050 std::remove_reference_t<decltype(**std::declval<WrappedIteratorT>())>,
1051 typename T2 = std::add_pointer_t<T1>>
1054}
1055
1056#endif
Iterator which returns a ref on container's values given predicates.
Definition iterators.hpp:323
std::enable_if_t<!std::is_const_v< pointer_t >, pointer_t > operator->()
Definition iterators.hpp:503
bool operator==(const filter_iterator &other) const
Definition iterators.hpp:547
filter_iterator(const filter_iterator &copy)
Definition iterators.hpp:405
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:494
filter_iterator cend() const
Definition iterators.hpp:465
std::enable_if_t< std::is_pointer_v< V >, add_const_t< ref_t > > operator*() const
Definition iterators.hpp:476
filter_iterator(T container, filter_t filter)
Definition iterators.hpp:368
std::forward_iterator_tag iterator_category
Definition iterators.hpp:326
std::enable_if_t<!std::is_const_v< ref_t >, remove_const_t< ref_t > > operator*()
Definition iterators.hpp:469
filter_iterator(T container)
Definition iterators.hpp:400
void swap(filter_iterator &other) noexcept
Definition iterators.hpp:418
filter_iterator & operator++()
Definition iterators.hpp:436
filter_iterator(T container, const std::vector< filter_t > &filters)
Definition iterators.hpp:385
filter_iterator end() const
Definition iterators.hpp:455
typename filter_iterator::pointer pointer_t
Definition iterators.hpp:336
filter_iterator & operator=(filter_iterator other)
Definition iterators.hpp:413
decay_t< Symbol * > value_type
Definition iterators.hpp:327
std::remove_pointer_t< Symbol * > * pointer
Definition iterators.hpp:329
typename filter_iterator::reference ref_t
Definition iterators.hpp:335
filter_iterator begin() const
Definition iterators.hpp:447
bool empty() const
Definition iterators.hpp:534
std::enable_if_t<!std::is_const_v< ref_t >, remove_const_t< ref_t > > operator[](size_t n)
Definition iterators.hpp:488
Symbol * DT_VAL
Definition iterators.hpp:333
ptrdiff_t difference_type
Definition iterators.hpp:328
~filter_iterator()=default
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:509
size_t size() const
Definition iterators.hpp:513
bool operator!=(const filter_iterator &other) const
Definition iterators.hpp:552
std::function< bool(const typename DT::value_type &)> filter_t
Definition iterators.hpp:337
std::enable_if_t<!std::is_pointer_v< V >, add_const_t< ref_t > > operator*() const
Definition iterators.hpp:482
std::remove_pointer_t< Symbol * > & reference
Definition iterators.hpp:330
filter_iterator(filter_iterator &&other) noexcept
Definition iterators.hpp:339
symbols_t & container_type
Definition iterators.hpp:332
filter_iterator operator++(int)
Definition iterators.hpp:441
decay_t< symbols_t & > DT
Definition iterators.hpp:334
filter_iterator cbegin() const
Definition iterators.hpp:451
filter_iterator & def(filter_t func)
Definition iterators.hpp:429
filter_iterator & operator=(filter_iterator &&other) noexcept
Definition iterators.hpp:349
DerivedT & operator++()
Definition iterators.hpp:951
DerivedT & operator--()
Definition iterators.hpp:956
DerivedT & operator-=(difference_type n)
Definition iterators.hpp:933
ReferenceT operator*() const
Definition iterators.hpp:978
friend bool operator<(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:969
friend bool operator==(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:965
DifferenceTypeT difference_type
Definition iterators.hpp:923
DerivedT & operator+=(difference_type n)
Definition iterators.hpp:925
difference_type operator-(const DerivedT &RHS) const
Definition iterators.hpp:942
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterators.hpp:738
DifferenceTypeT difference_type
Definition iterators.hpp:742
PointerProxy operator->() const
Definition iterators.hpp:871
DerivedT & operator--()
Definition iterators.hpp:825
DerivedT operator++(int)
Definition iterators.hpp:820
T value_type
Definition iterators.hpp:741
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
Definition iterators.hpp:802
bool operator>(const DerivedT &RHS) const
Definition iterators.hpp:848
ReferenceProxy operator[](DifferenceTypeT n) const
Definition iterators.hpp:874
ReferenceT reference
Definition iterators.hpp:744
bool operator>=(const DerivedT &RHS) const
Definition iterators.hpp:863
DerivedT operator-(DifferenceTypeT n) const
Definition iterators.hpp:807
DerivedT & operator++()
Definition iterators.hpp:815
PointerT pointer
Definition iterators.hpp:743
DerivedT operator--(int)
Definition iterators.hpp:832
IteratorCategoryT iterator_category
Definition iterators.hpp:740
DerivedT operator+(DifferenceTypeT n) const
Definition iterators.hpp:793
bool operator!=(const DerivedT &RHS) const
Definition iterators.hpp:843
bool operator<=(const DerivedT &RHS) const
Definition iterators.hpp:856
decltype(*std::declval< const IteratorDecayTy & >()) reference
Definition iterators.hpp:620
auto operator->() const -> decltype(&*std::declval< const It & >())
Definition iterators.hpp:627
Definition iterators.hpp:591
IteratorT begin() const
Definition iterators.hpp:601
ReferenceProxy at(typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:632
std::decay_t< assembly::Instruction::Iterator > IteratorDecayTy
Definition iterators.hpp:594
iterator_range(T &&it_begin, T &&it_end)
Definition iterators.hpp:597
IteratorT end() const
Definition iterators.hpp:604
bool empty() const
Definition iterators.hpp:607
ReferenceProxy operator[](typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:639
assembly::Instruction::Iterator IteratorTy
Definition iterators.hpp:593
std::ptrdiff_t size() const
Definition iterators.hpp:643
Definition iterators.hpp:1025
T & operator*() const
Definition iterators.hpp:1034
pointer_iterator(WrappedIteratorT u)
Definition iterators.hpp:1031
Iterator which returns reference on container's values.
Definition iterators.hpp:47
bool operator<=(const ref_iterator &rhs) const
Definition iterators.hpp:239
ref_iterator & operator--()
Definition iterators.hpp:151
size_t size() const
Definition iterators.hpp:270
ref_iterator & operator++()
Definition iterators.hpp:139
void swap(ref_iterator &other) noexcept
Definition iterators.hpp:129
bool operator<(const ref_iterator &rhs) const
Definition iterators.hpp:224
ref_iterator operator-(typename ref_iterator::difference_type n) const
Definition iterators.hpp:214
ref_iterator operator++(int)
Definition iterators.hpp:145
ref_iterator begin() const
Definition iterators.hpp:243
sections_t container_type
Definition iterators.hpp:58
typename ref_iterator::reference ref_t
Definition iterators.hpp:61
ref_iterator operator--(int)
Definition iterators.hpp:159
ref_iterator cend() const
Definition iterators.hpp:258
std::enable_if_t<!std::is_pointer_v< V >, add_const_t< ref_t > > operator*() const
Definition iterators.hpp:291
ref_iterator & operator+=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:166
std::enable_if_t<!std::is_const_v< ref_t >, remove_const_t< ref_t > > operator[](size_t n)
Definition iterators.hpp:183
std::remove_pointer_t< typename decay_t< sections_t >::value_type > & reference
Definition iterators.hpp:56
std::bidirectional_iterator_tag iterator_category
Definition iterators.hpp:52
std::enable_if_t<!std::is_const_v< ref_t >, remove_const_t< ref_t > > operator*()
Definition iterators.hpp:278
std::enable_if_t< std::is_pointer_v< V >, add_const_t< ref_t > > operator*() const
Definition iterators.hpp:285
ref_iterator(ref_iterator &&other) noexcept
Definition iterators.hpp:64
ptrdiff_t difference_type
Definition iterators.hpp:54
ref_iterator operator+(typename ref_iterator::difference_type n) const
Definition iterators.hpp:208
ref_iterator cbegin() const
Definition iterators.hpp:247
bool empty() const
Definition iterators.hpp:274
ref_iterator & operator=(ref_iterator other)
Definition iterators.hpp:124
ref_iterator & operator=(ref_iterator &&other) noexcept
Definition iterators.hpp:71
bool operator!=(const ref_iterator &other) const
Definition iterators.hpp:266
bool operator>(const ref_iterator &rhs) const
Definition iterators.hpp:229
bool operator>=(const ref_iterator &rhs) const
Definition iterators.hpp:234
ref_iterator(const ref_iterator &copy)
Definition iterators.hpp:117
ref_iterator(ref_iterator< T2, U2, IT2 > &&other) noexcept
Definition iterators.hpp:102
ref_iterator end() const
Definition iterators.hpp:251
ref_iterator & operator-=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:175
ref_iterator(const ref_iterator< T2, U2, IT2 > &other)
Definition iterators.hpp:87
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:190
std::remove_pointer_t< typename decay_t< sections_t >::value_type > * pointer
Definition iterators.hpp:55
decay_t< typename decay_t< sections_t >::value_type > value_type
Definition iterators.hpp:53
std::enable_if_t<!std::is_const_v< pointer_t >, pointer_t > operator->()
Definition iterators.hpp:296
ref_iterator::difference_type operator-(const ref_iterator &rhs) const
Definition iterators.hpp:220
typename decay_t< sections_t >::value_type DT_VAL
Definition iterators.hpp:59
typename ref_iterator::pointer pointer_t
Definition iterators.hpp:62
friend class ref_iterator
Definition iterators.hpp:49
ref_iterator(T container)
Definition iterators.hpp:113
~ref_iterator()=default
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:302
bool operator==(const ref_iterator &other) const
Definition iterators.hpp:262
decay_t< sections_t > DT
Definition iterators.hpp:60
#define LIEF_LIFETIMEBOUND
Definition compiler_attributes.hpp:72
@ T
Definition AcceleratorCodes.hpp:97
LIEF namespace.
Definition Abstract/Binary.hpp:41
filter_iterator< CT, U, typename decay_t< CT >::const_iterator > const_filter_iterator
Iterator which returns a const ref on container's values given predicates.
Definition iterators.hpp:583
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
Definition iterators.hpp:1013
iterator_range< T > make_range(T &&x, T &&y)
Definition iterators.hpp:663
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterators.hpp:1042
std::remove_const_t< T > remove_const_t
Definition iterators.hpp:38
ref_iterator< CT, U, typename decay_t< CT >::const_iterator > const_ref_iterator
Iterator which returns a const ref on container's values.
Definition iterators.hpp:316
pointer_iterator< pointee_iterator< WrappedIteratorT, T1 >, T2 > raw_pointer_iterator
Definition iterators.hpp:1052
std::decay_t< T > decay_t
Definition iterators.hpp:32
std::add_const_t< T > add_const_t
Definition iterators.hpp:35
std::add_lvalue_reference_t< T > add_lvalue_reference_t
Definition iterators.hpp:41
An iterator type that allows iterating over the pointees via some other iterator.
Definition iterators.hpp:999
T & operator*() const
Definition iterators.hpp:1005
pointee_iterator(U &&u)
Definition iterators.hpp:1002