LIEF: Library to Instrument Executable Formats Version 1.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 <cstddef>
20#include <cassert>
21#include <iterator>
22#include <functional>
23#include <algorithm>
24#include <type_traits>
25#include <vector>
26
28
29namespace LIEF {
30
31template<class T>
32using decay_t = typename std::decay<T>::type;
33
34template<class T>
35using add_const_t = typename std::add_const<T>::type;
36
37template<class T>
38using remove_const_t = typename std::remove_const<T>::type;
39
40template<class T>
41using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
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 = typename std::remove_pointer<U>::type*;
56 using reference = typename std::remove_pointer<U>::type&;
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 = typename std::enable_if<
84 !std::is_same<ref_iterator, ref_iterator<T2, U2, IT2>>::value &&
85 std::is_same<decay_t<T>, decay_t<T2>>::value
86 >::type>
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 = typename std::enable_if<
98 !std::is_same<ref_iterator, ref_iterator<T2, U2, IT2>>::value &&
99 std::is_same<decay_t<T>, decay_t<T2>>::value
100 >::type>
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 typename std::enable_if<!std::is_const<ref_t>::value,
184 operator[](size_t n) {
185 return const_cast<remove_const_t<ref_t>>(
186 static_cast<const ref_iterator*>(this)->operator[](n)
187 );
188 }
189
190
192 assert(n < size() && "integrity error: out of bound");
193
194 auto* no_const_this = const_cast<ref_iterator*>(this);
195
196 typename ref_iterator::difference_type saved_dist =
197 std::distance(std::begin(no_const_this->container_), no_const_this->it_);
198 no_const_this->it_ = std::begin(no_const_this->container_);
199 std::advance(no_const_this->it_, n);
200
201 auto&& v = const_cast<add_const_t<ref_t>>(no_const_this->operator*());
202
203 no_const_this->it_ = std::begin(no_const_this->container_);
204 std::advance(no_const_this->it_, saved_dist);
205
206 return v;
207 }
208
210 ref_iterator tmp = *this;
211 return tmp += n;
212 }
213
214
216 ref_iterator tmp = *this;
217 return tmp -= n;
218 }
219
220
222 return distance_ - rhs.distance_;
223 }
224
225 bool operator<(const ref_iterator& rhs) const {
226 return (rhs - *this) > 0;
227 }
228
229
230 bool operator>(const ref_iterator& rhs) const {
231 return rhs < *this;
232 }
233
234
235 bool operator>=(const ref_iterator& rhs) const {
236 return !(*this < rhs);
237 }
238
239
240 bool operator<=(const ref_iterator& rhs) const {
241 return !(*this > rhs);
242 }
243
245 return container_;
246 }
247
249 return begin();
250 }
251
253 ref_iterator it = ref_iterator{container_};
254 it.it_ = std::end(it.container_);
255 it.distance_ = it.size();
256 return it;
257 }
258
260 return end();
261 }
262
263 bool operator==(const ref_iterator& other) const {
264 return (size() == other.size() && distance_ == other.distance_);
265 }
266
267 bool operator!=(const ref_iterator& other) const {
268 return !(*this == other);
269 }
270
271 size_t size() const {
272 return container_.size();
273 }
274
275 bool empty() const {
276 return container_.empty();
277 }
278
279 typename std::enable_if<!std::is_const<ref_t>::value,
282 return const_cast<remove_const_t<ref_t>>(
283 static_cast<const ref_iterator*>(this)->operator*()
284 );
285 }
286
287 template<typename V = DT_VAL>
288 typename std::enable_if<std::is_pointer<V>::value, add_const_t<ref_t>>::type
289 operator*() const {
290 assert(*it_ && "integrity error: nullptr");
291 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
292 }
293
294 template<typename V = DT_VAL>
295 typename std::enable_if<!std::is_pointer<V>::value, add_const_t<ref_t>>::type
296 operator*() const {
297 return const_cast<add_const_t<ref_t>>(*(it_));
298 }
299
300
301 typename std::enable_if<!std::is_const<pointer_t>::value, pointer_t>::type
303 return const_cast<remove_const_t<pointer_t>>(
304 static_cast<const ref_iterator*>(this)->operator->()
305 );
306 }
307
309 return const_cast<add_const_t<pointer_t>>(&(operator*()));
310 }
311
312 protected:
313 T container_;
314 ITERATOR_T it_;
315 typename ref_iterator::difference_type distance_{};
316};
317
318
320template<class T, typename U = typename decay_t<T>::value_type,
321 class CT = typename std::add_const<T>::type>
324
325
327template<class T, typename U = typename decay_t<T>::value_type,
328 class ITERATOR_T = typename decay_t<T>::iterator>
330
331 public:
332 using iterator_category = std::forward_iterator_tag;
334 using difference_type = ptrdiff_t;
335 using pointer = typename std::remove_pointer<U>::type*;
336 using reference = typename std::remove_pointer<U>::type&;
337
338 using container_type = T;
339 using DT_VAL = U;
340 using DT = decay_t<T>;
343 using filter_t = std::function<bool(const typename DT::value_type&)>;
344
346 size_c_(other.size_c_),
347 size_cached_(other.size_cached_),
348 container_(std::forward<T>(other.container_)),
349 it_(std::begin(container_)),
350 filters_{std::move(other.filters_)},
351 distance_(other.distance_) {
352 std::advance(it_, distance_);
353 }
354
356 if (this == &other) {
357 return *this;
358 }
359
360 size_c_ = other.size_c_;
361 size_cached_ = other.size_cached_;
362 container_ = std::forward<T>(other.container_);
363 it_ = std::begin(container_);
364 filters_ = std::move(other.filters_);
365 distance_ = other.distance_;
366
367 std::advance(it_, distance_);
368
369 return *this;
370 }
371
372 ~filter_iterator() = default;
373
374 filter_iterator(T container, filter_t filter) :
375 container_{std::forward<T>(container)},
376 it_(std::begin(container_)),
377 filters_{} {
378
379
380 filters_.push_back(filter);
381
382 if (it_ != std::end(container_)) {
383 if (!std::all_of(std::begin(filters_), std::end(filters_),
384 [this](const filter_t& f) { return f(*it_); }))
385 {
386 next();
387 }
388 }
389 }
390
391 filter_iterator(T container, const std::vector<filter_t>& filters) :
392 container_{std::forward<T>(container)},
393 it_(std::begin(container_)),
394 filters_{filters} {
395
396
397 if (it_ != std::end(container_)) {
398 if (!std::all_of(std::begin(filters_), std::end(filters_),
399 [this](const filter_t& f) { return f(*it_); }))
400 {
401 next();
402 }
403 }
404 }
405
406 filter_iterator(T container) :
407 container_{std::forward<T>(container)},
408 it_(std::begin(container_)),
409 filters_{} {}
410
412 container_{copy.container_},
413 it_{std::begin(container_)},
414 filters_{copy.filters_},
415 distance_{copy.distance_} {
416 std::advance(it_, distance_);
417 }
418
420 swap(other);
421 return *this;
422 }
423
424 void swap(filter_iterator& other) noexcept {
425 std::swap(const_cast<remove_const_t<DT>&>(container_),
426 const_cast<remove_const_t<DT>&>(other.container_));
427 std::swap(it_, other.it_);
428 std::swap(filters_, other.filters_);
429 std::swap(size_c_, other.size_c_);
430 std::swap(size_cached_, other.size_cached_);
431 std::swap(distance_, other.distance_);
432 }
433
434
436 filters_.push_back(func);
437 size_c_ = 0;
438 size_cached_ = false;
439 return *this;
440 }
441
443 next();
444 return *this;
445 }
446
448 filter_iterator retval = *this;
449 ++(*this);
450 return retval;
451 }
452
454 return {container_, filters_};
455 }
456
458 return begin();
459 }
460
462 // we don't need filter for the end iterator
463 filter_iterator it_end{container_};
464
465 it_end.it_ = it_end.container_.end();
466 it_end.distance_ = it_end.container_.size();
467
468 return it_end;
469 }
470
472 return end();
473 }
474
475 typename std::enable_if<!std::is_const<ref_t>::value,
478 return const_cast<remove_const_t<ref_t>>(
479 static_cast<const filter_iterator*>(this)->operator*()
480 );
481 }
482
483 template<typename V = DT_VAL>
484 typename std::enable_if<std::is_pointer<V>::value, add_const_t<ref_t>>::type
485 operator*() const {
486 assert(*it_ && "integrity error: nullptr");
487 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
488 }
489
490 template<typename V = DT_VAL>
491 typename std::enable_if<!std::is_pointer<V>::value, add_const_t<ref_t>>::type
492 operator*() const {
493 return const_cast<add_const_t<ref_t>>(*(it_));
494 }
495
496
497 typename std::enable_if<!std::is_const<ref_t>::value,
499 operator[](size_t n) {
500 return const_cast<remove_const_t<ref_t>>(
501 static_cast<const filter_iterator*>(this)->operator[](n)
502 );
503 }
504
506 assert(n < size() && "integrity error: out of bound");
507
508 auto it = begin();
509 std::advance(it, n);
510 return const_cast<add_const_t<ref_t>>(*it);
511 }
512
513
514 typename std::enable_if<!std::is_const<pointer_t>::value, pointer_t>::type
516 return const_cast<remove_const_t<pointer_t>>(
517 static_cast<const filter_iterator*>(this)->operator->()
518 );
519 }
520
522 return const_cast<add_const_t<pointer_t>>(&(operator*()));
523 }
524
525 size_t size() const {
526 if (filters_.empty()) {
527 return container_.size();
528 }
529
530 if (size_cached_) {
531 return size_c_;
532 }
533 filter_iterator it = begin();
534 size_t size = 0;
535
536 auto end_iter = it.end();
537 for (; it != end_iter; ++it) {
538 ++size;
539 }
540 size_c_ = size;
541 size_cached_ = true;
542 return size_c_;
543 }
544
545
546 bool empty() const {
547 if (filters_.empty()) {
548 return container_.empty();
549 }
550
551 if (size_cached_) {
552 return size_c_ == 0;
553 }
554
555 return begin() == end();
556 }
557
558
559 bool operator==(const filter_iterator& other) const {
560 return (container_.size() == other.container_.size() &&
561 distance_ == other.distance_);
562 }
563
564 bool operator!=(const filter_iterator& other) const {
565 return !(*this == other);
566 }
567
568 protected:
569 void next() {
570 if (it_ == std::end(container_)) {
571 distance_ = container_.size();
572 return;
573 }
574
575 do {
576 it_ = std::next(it_);
577 distance_++;
578 } while (it_ != std::end(container_) &&
579 !std::all_of(std::begin(filters_), std::end(filters_),
580 [this](const filter_t& f) { return f(*it_); }));
581 }
582
583
584 mutable size_t size_c_ = 0;
585 mutable bool size_cached_ = false;
586 T container_;
587 ITERATOR_T it_;
588 std::vector<filter_t> filters_;
589 typename filter_iterator::difference_type distance_ = 0;
590};
591
593template<class T, typename U = typename decay_t<T>::value_type,
594 class CT = typename std::add_const<T>::type>
597
598// ----------------------------------------------------------------------------
599// This part is taken from LLVM
600// ----------------------------------------------------------------------------
601
602template<typename IteratorT>
604 public:
605 using IteratorTy = IteratorT;
606 using IteratorDecayTy = typename std::decay<IteratorT>::type;
607
608 template<class T>
609 iterator_range(T&& it_begin, T&& it_end) :
610 begin_(std::forward<T>(it_begin)),
611 end_(std::forward<T>(it_end)) {}
612
613 IteratorT begin() const {
614 return begin_;
615 }
616 IteratorT end() const {
617 return end_;
618 }
619 bool empty() const {
620 return begin_ == end_;
621 }
622
623 class ReferenceProxy {
624 friend iterator_range;
625
626 IteratorDecayTy it_;
627
628 explicit ReferenceProxy(IteratorDecayTy it) :
629 it_(std::move(it)) {}
630
631 public:
632 using reference = decltype(*std::declval<const IteratorDecayTy&>());
633
634 operator reference() const {
635 return *it_;
636 }
637
638 template<class It = IteratorDecayTy>
639 auto operator->() const -> decltype(&*std::declval<const It&>()) {
640 return &*it_;
641 }
642 };
643
644 ReferenceProxy at(typename IteratorDecayTy::difference_type pos) const {
645 static_assert(IsRandomAccess, "at() needs random access iterator");
646 auto it = begin_;
647 std::advance(it, pos);
648 return ReferenceProxy(std::move(it));
649 }
650
651 ReferenceProxy operator[](typename IteratorDecayTy::difference_type pos) const {
652 return at(pos);
653 }
654
655 std::ptrdiff_t size() const {
656 return std::distance(begin_, end_);
657 }
658
659 protected:
660 enum {
661 IsRandomAccess =
662 std::is_base_of<std::random_access_iterator_tag,
663 typename IteratorDecayTy::iterator_category>::value,
664 IsBidirectional =
665 std::is_base_of<std::bidirectional_iterator_tag,
666 typename IteratorDecayTy::iterator_category>::value,
667 };
668
669 private:
670 IteratorT begin_;
671 IteratorT end_;
672};
673
674template<class T>
676 return iterator_range<T>(std::forward<T>(x), std::forward<T>(y));
677}
678
679} // namespace LIEF
680
681#if LIEF_HAS_STD_RANGES
682template<typename IteratorT>
683inline constexpr bool
684 std::ranges::enable_borrowed_range<LIEF::iterator_range<IteratorT>> = true;
685#endif
686
687namespace LIEF {
688
689
747template<typename DerivedT, typename IteratorCategoryT, typename T,
748 typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T*,
749 typename ReferenceT = T&>
751 public:
752 using iterator_category = IteratorCategoryT;
753 using value_type = T;
754 using difference_type = DifferenceTypeT;
755 using pointer = PointerT;
756 using reference = ReferenceT;
757
758 protected:
759 enum {
760 IsRandomAccess =
761 std::is_base_of<std::random_access_iterator_tag, IteratorCategoryT>::value,
762 IsBidirectional =
763 std::is_base_of<std::bidirectional_iterator_tag, IteratorCategoryT>::value,
764 };
765
771 class ReferenceProxy {
773
774 DerivedT I;
775
776 ReferenceProxy(DerivedT I) :
777 I(std::move(I)) {}
778
779 public:
780 operator ReferenceT() const {
781 return *I;
782 }
783 };
784
789 class PointerProxy {
790 friend iterator_facade_base;
791
792 ReferenceT R;
793
794 template<typename RefT>
795 PointerProxy(RefT&& R) : // NOLINT(bugprone-forwarding-reference-overload)
796 R(std::forward<RefT>(R)) {}
797
798 public:
799 PointerT operator->() const {
800 return &R;
801 }
802 };
803
804 public:
805 DerivedT operator+(DifferenceTypeT n) const {
806 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
807 "Must pass the derived type to this template!");
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 friend DerivedT operator+(DifferenceTypeT n, const DerivedT& i) {
815 static_assert(IsRandomAccess,
816 "The '+' operator is only defined for random access iterators.");
817 return i + n;
818 }
819 DerivedT operator-(DifferenceTypeT n) const {
820 static_assert(IsRandomAccess,
821 "The '-' operator is only defined for random access iterators.");
822 DerivedT tmp = *static_cast<const DerivedT*>(this);
823 tmp -= n;
824 return tmp;
825 }
826
827 DerivedT& operator++() {
828 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
829 "Must pass the derived type to this template!");
830 return static_cast<DerivedT*>(this)->operator+=(1);
831 }
832 DerivedT operator++(int) {
833 DerivedT tmp = *static_cast<DerivedT*>(this);
834 ++*static_cast<DerivedT*>(this);
835 return tmp;
836 }
837 DerivedT& operator--() {
838 static_assert(
839 IsBidirectional,
840 "The decrement operator is only defined for bidirectional iterators."
841 );
842 return static_cast<DerivedT*>(this)->operator-=(1);
843 }
844 DerivedT operator--(int) {
845 static_assert(
846 IsBidirectional,
847 "The decrement operator is only defined for bidirectional iterators."
848 );
849 DerivedT tmp = *static_cast<DerivedT*>(this);
850 --*static_cast<DerivedT*>(this);
851 return tmp;
852 }
853
854#ifndef __cpp_impl_three_way_comparison
855 bool operator!=(const DerivedT& RHS) const {
856 return !(static_cast<const DerivedT&>(*this) == RHS);
857 }
858#endif
859
860 bool operator>(const DerivedT& RHS) const {
861 static_assert(
862 IsRandomAccess,
863 "Relational operators are only defined for random access iterators."
864 );
865 return !(static_cast<const DerivedT&>(*this) < RHS) &&
866 !(static_cast<const DerivedT&>(*this) == RHS);
867 }
868 bool operator<=(const DerivedT& RHS) const {
869 static_assert(
870 IsRandomAccess,
871 "Relational operators are only defined for random access iterators."
872 );
873 return !(static_cast<const DerivedT&>(*this) > RHS);
874 }
875 bool operator>=(const DerivedT& RHS) const {
876 static_assert(
877 IsRandomAccess,
878 "Relational operators are only defined for random access iterators."
879 );
880 return !(static_cast<const DerivedT&>(*this) < RHS);
881 }
882
883 PointerProxy operator->() const {
884 return static_cast<const DerivedT*>(this)->operator*();
885 }
886 ReferenceProxy operator[](DifferenceTypeT n) const {
887 static_assert(IsRandomAccess,
888 "Subscripting is only defined for random access iterators.");
889 return static_cast<const DerivedT*>(this)->operator+(n);
890 }
891};
892
898template<typename DerivedT, typename WrappedIteratorT,
899 typename IteratorCategoryT =
900 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
901 typename T = typename std::iterator_traits<WrappedIteratorT>::value_type,
902 typename DifferenceTypeT =
903 typename std::iterator_traits<WrappedIteratorT>::difference_type,
904 typename PointerT = typename std::conditional<
905 std::is_same<T, typename std::iterator_traits<WrappedIteratorT>::
906 value_type>::value,
907 typename std::iterator_traits<WrappedIteratorT>::pointer, T*
908 >::type,
909 typename ReferenceT = typename std::conditional<
910 std::is_same<T, typename std::iterator_traits<WrappedIteratorT>::
911 value_type>::value,
912 typename std::iterator_traits<WrappedIteratorT>::reference, T&
913 >::type>
914class iterator_adaptor_base
915 : public iterator_facade_base<DerivedT, IteratorCategoryT, T, DifferenceTypeT,
916 PointerT, ReferenceT> {
917 using BaseT = typename iterator_adaptor_base::iterator_facade_base;
918
919 protected:
920 WrappedIteratorT I;
921
922 iterator_adaptor_base() = default;
923
924 explicit iterator_adaptor_base(WrappedIteratorT u) :
925 I(std::move(u)) {
926 static_assert(std::is_base_of<iterator_adaptor_base, DerivedT>::value,
927 "Must pass the derived type to this template!");
928 }
929
930 const WrappedIteratorT& wrapped() const {
931 return I;
932 }
933
934 public:
935 using difference_type = DifferenceTypeT;
936
938 static_assert(
939 BaseT::IsRandomAccess,
940 "The '+=' operator is only defined for random access iterators."
941 );
942 I += n;
943 return *static_cast<DerivedT*>(this);
944 }
946 static_assert(
947 BaseT::IsRandomAccess,
948 "The '-=' operator is only defined for random access iterators."
949 );
950 I -= n;
951 return *static_cast<DerivedT*>(this);
952 }
953 using BaseT::operator-;
954 difference_type operator-(const DerivedT& RHS) const {
955 static_assert(BaseT::IsRandomAccess,
956 "The '-' operator is only defined for random access iterators.");
957 return I - RHS.I;
958 }
959
960 // We have to explicitly provide ++ and -- rather than letting the facade
961 // forward to += because WrappedIteratorT might not support +=.
962 using BaseT::operator++;
964 ++I;
965 return *static_cast<DerivedT*>(this);
966 }
967 using BaseT::operator--;
969 static_assert(
970 BaseT::IsBidirectional,
971 "The decrement operator is only defined for bidirectional iterators."
972 );
973 --I;
974 return *static_cast<DerivedT*>(this);
975 }
976
977 friend bool operator==(const iterator_adaptor_base& LHS,
978 const iterator_adaptor_base& RHS) {
979 return LHS.I == RHS.I;
980 }
981 friend bool operator<(const iterator_adaptor_base& LHS,
982 const iterator_adaptor_base& RHS) {
983 static_assert(
984 BaseT::IsRandomAccess,
985 "Relational operators are only defined for random access iterators."
986 );
987 return LHS.I < RHS.I;
988 }
989
990 ReferenceT operator*() const {
991 return *I;
992 }
993};
994
1004template<typename WrappedIteratorT,
1005 typename T = typename std::
1006 remove_reference<decltype(**std::declval<WrappedIteratorT>())>::type>
1008 : iterator_adaptor_base<
1009 pointee_iterator<WrappedIteratorT, T>, WrappedIteratorT,
1010 typename std::iterator_traits<WrappedIteratorT>::iterator_category, T
1011 > {
1012 pointee_iterator() = default;
1013 template<typename U>
1014 pointee_iterator(U&& u) : // NOLINT(bugprone-forwarding-reference-overload)
1015 pointee_iterator::iterator_adaptor_base(std::forward<U>(u)) {}
1016
1017 T& operator*() const {
1018 return **this->I;
1019 }
1020};
1021
1022template<typename RangeT,
1023 typename WrappedIteratorT = decltype(std::begin(std::declval<RangeT>()))>
1024iterator_range<pointee_iterator<WrappedIteratorT>>
1025 make_pointee_range(RangeT&& Range) {
1026 using PointeeIteratorT = pointee_iterator<WrappedIteratorT>;
1027 return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
1028 PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
1029}
1030
1031template<typename WrappedIteratorT,
1032 typename T = decltype(&*std::declval<WrappedIteratorT>())>
1034 : public iterator_adaptor_base<
1035 pointer_iterator<WrappedIteratorT, T>, WrappedIteratorT,
1036 typename std::iterator_traits<WrappedIteratorT>::iterator_category, T
1037 > {
1038 mutable T Ptr;
1039
1040 public:
1041 pointer_iterator() = default;
1042
1043 explicit pointer_iterator(WrappedIteratorT u) :
1044 pointer_iterator::iterator_adaptor_base(std::move(u)) {}
1045
1046 T& operator*() const {
1047 return Ptr = &*this->I;
1048 }
1049};
1050
1051template<typename RangeT,
1052 typename WrappedIteratorT = decltype(std::begin(std::declval<RangeT>()))>
1053iterator_range<pointer_iterator<WrappedIteratorT>>
1054 make_pointer_range(RangeT&& Range) {
1055 using PointerIteratorT = pointer_iterator<WrappedIteratorT>;
1056 return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
1057 PointerIteratorT(std::end(std::forward<RangeT>(Range))));
1058}
1059
1060template<typename WrappedIteratorT,
1061 typename T1 = typename std::
1062 remove_reference<decltype(**std::declval<WrappedIteratorT>())>::type,
1063 typename T2 = typename std::add_pointer<T1>::type>
1066
1067}
1068
1069#endif
Iterator which returns a ref on container's values given predicates.
Definition iterators.hpp:329
std::enable_if<!std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:492
bool operator==(const filter_iterator &other) const
Definition iterators.hpp:559
filter_iterator(const filter_iterator &copy)
Definition iterators.hpp:411
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:505
filter_iterator cend() const
Definition iterators.hpp:471
typename std::remove_pointer< Symbol * >::type * pointer
Definition iterators.hpp:335
filter_iterator(T container, filter_t filter)
Definition iterators.hpp:374
std::forward_iterator_tag iterator_category
Definition iterators.hpp:332
filter_iterator(T container)
Definition iterators.hpp:406
void swap(filter_iterator &other) noexcept
Definition iterators.hpp:424
filter_iterator & operator++()
Definition iterators.hpp:442
std::enable_if<!std::is_const< pointer_t >::value, pointer_t >::type operator->()
Definition iterators.hpp:515
filter_iterator(T container, const std::vector< filter_t > &filters)
Definition iterators.hpp:391
filter_iterator end() const
Definition iterators.hpp:461
typename filter_iterator::pointer pointer_t
Definition iterators.hpp:342
filter_iterator & operator=(filter_iterator other)
Definition iterators.hpp:419
decay_t< Symbol * > value_type
Definition iterators.hpp:333
typename filter_iterator::reference ref_t
Definition iterators.hpp:341
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator*()
Definition iterators.hpp:477
filter_iterator begin() const
Definition iterators.hpp:453
bool empty() const
Definition iterators.hpp:546
Symbol * DT_VAL
Definition iterators.hpp:339
ptrdiff_t difference_type
Definition iterators.hpp:334
~filter_iterator()=default
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:521
size_t size() const
Definition iterators.hpp:525
std::enable_if< std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:485
bool operator!=(const filter_iterator &other) const
Definition iterators.hpp:564
std::function< bool(const typename DT::value_type &)> filter_t
Definition iterators.hpp:343
filter_iterator(filter_iterator &&other) noexcept
Definition iterators.hpp:345
symbols_t & container_type
Definition iterators.hpp:338
filter_iterator operator++(int)
Definition iterators.hpp:447
decay_t< symbols_t & > DT
Definition iterators.hpp:340
filter_iterator cbegin() const
Definition iterators.hpp:457
filter_iterator & def(filter_t func)
Definition iterators.hpp:435
typename std::remove_pointer< Symbol * >::type & reference
Definition iterators.hpp:336
filter_iterator & operator=(filter_iterator &&other) noexcept
Definition iterators.hpp:355
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator[](size_t n)
Definition iterators.hpp:499
DerivedT & operator++()
Definition iterators.hpp:963
DerivedT & operator--()
Definition iterators.hpp:968
DerivedT & operator-=(difference_type n)
Definition iterators.hpp:945
ReferenceT operator*() const
Definition iterators.hpp:990
friend bool operator<(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:981
friend bool operator==(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:977
DifferenceTypeT difference_type
Definition iterators.hpp:935
DerivedT & operator+=(difference_type n)
Definition iterators.hpp:937
difference_type operator-(const DerivedT &RHS) const
Definition iterators.hpp:954
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterators.hpp:750
DifferenceTypeT difference_type
Definition iterators.hpp:754
PointerProxy operator->() const
Definition iterators.hpp:883
DerivedT & operator--()
Definition iterators.hpp:837
DerivedT operator++(int)
Definition iterators.hpp:832
T value_type
Definition iterators.hpp:753
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
Definition iterators.hpp:814
bool operator>(const DerivedT &RHS) const
Definition iterators.hpp:860
ReferenceProxy operator[](DifferenceTypeT n) const
Definition iterators.hpp:886
ReferenceT reference
Definition iterators.hpp:756
bool operator>=(const DerivedT &RHS) const
Definition iterators.hpp:875
DerivedT operator-(DifferenceTypeT n) const
Definition iterators.hpp:819
DerivedT & operator++()
Definition iterators.hpp:827
PointerT pointer
Definition iterators.hpp:755
DerivedT operator--(int)
Definition iterators.hpp:844
IteratorCategoryT iterator_category
Definition iterators.hpp:752
DerivedT operator+(DifferenceTypeT n) const
Definition iterators.hpp:805
bool operator!=(const DerivedT &RHS) const
Definition iterators.hpp:855
bool operator<=(const DerivedT &RHS) const
Definition iterators.hpp:868
decltype(*std::declval< const IteratorDecayTy & >()) reference
Definition iterators.hpp:632
auto operator->() const -> decltype(&*std::declval< const It & >())
Definition iterators.hpp:639
Definition iterators.hpp:603
IteratorT begin() const
Definition iterators.hpp:613
ReferenceProxy at(typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:644
iterator_range(T &&it_begin, T &&it_end)
Definition iterators.hpp:609
IteratorT end() const
Definition iterators.hpp:616
bool empty() const
Definition iterators.hpp:619
ReferenceProxy operator[](typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:651
assembly::Instruction::Iterator IteratorTy
Definition iterators.hpp:605
std::ptrdiff_t size() const
Definition iterators.hpp:655
typename std::decay< assembly::Instruction::Iterator >::type IteratorDecayTy
Definition iterators.hpp:606
Definition iterators.hpp:1037
T & operator*() const
Definition iterators.hpp:1046
pointer_iterator(WrappedIteratorT u)
Definition iterators.hpp:1043
Iterator which returns reference on container's values.
Definition iterators.hpp:47
bool operator<=(const ref_iterator &rhs) const
Definition iterators.hpp:240
ref_iterator & operator--()
Definition iterators.hpp:151
size_t size() const
Definition iterators.hpp:271
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:225
ref_iterator operator-(typename ref_iterator::difference_type n) const
Definition iterators.hpp:215
ref_iterator operator++(int)
Definition iterators.hpp:145
ref_iterator begin() const
Definition iterators.hpp:244
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:259
ref_iterator & operator+=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:166
std::bidirectional_iterator_tag iterator_category
Definition iterators.hpp:52
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:209
typename std::remove_pointer< typename decay_t< sections_t >::value_type >::type & reference
Definition iterators.hpp:56
ref_iterator cbegin() const
Definition iterators.hpp:248
bool empty() const
Definition iterators.hpp:275
ref_iterator & operator=(ref_iterator other)
Definition iterators.hpp:124
typename std::remove_pointer< typename decay_t< sections_t >::value_type >::type * pointer
Definition iterators.hpp:55
ref_iterator & operator=(ref_iterator &&other) noexcept
Definition iterators.hpp:71
bool operator!=(const ref_iterator &other) const
Definition iterators.hpp:267
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator[](size_t n)
Definition iterators.hpp:184
bool operator>(const ref_iterator &rhs) const
Definition iterators.hpp:230
bool operator>=(const ref_iterator &rhs) const
Definition iterators.hpp:235
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:252
std::enable_if< std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:289
std::enable_if<!std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:296
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:191
decay_t< typename decay_t< sections_t >::value_type > value_type
Definition iterators.hpp:53
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator*()
Definition iterators.hpp:281
ref_iterator::difference_type operator-(const ref_iterator &rhs) const
Definition iterators.hpp:221
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
std::enable_if<!std::is_const< pointer_t >::value, pointer_t >::type operator->()
Definition iterators.hpp:302
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:308
bool operator==(const ref_iterator &other) const
Definition iterators.hpp:263
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
typename std::add_lvalue_reference< T >::type add_lvalue_reference_t
Definition iterators.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:595
typename std::remove_const< T >::type remove_const_t
Definition iterators.hpp:38
typename std::decay< T >::type decay_t
Definition iterators.hpp:32
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
Definition iterators.hpp:1025
iterator_range< T > make_range(T &&x, T &&y)
Definition iterators.hpp:675
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterators.hpp:1054
typename std::add_const< T >::type add_const_t
Definition iterators.hpp:35
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:322
pointer_iterator< pointee_iterator< WrappedIteratorT, T1 >, T2 > raw_pointer_iterator
Definition iterators.hpp:1064
An iterator type that allows iterating over the pointees via some other iterator.
Definition iterators.hpp:1011
T & operator*() const
Definition iterators.hpp:1017
pointee_iterator(U &&u)
Definition iterators.hpp:1014