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 // NOLINTNEXTLINE(performance-unnecessary-value-param)
114 ref_iterator(T container) :
115 container_{std::forward<T>(container)},
116 it_(std::begin(container_)) {}
117
119 container_{copy.container_},
120 it_{std::begin(container_)},
121 distance_{copy.distance_} {
122 std::advance(it_, distance_);
123 }
124
126 swap(other);
127 return *this;
128 }
129
130 void swap(ref_iterator& other) noexcept {
131 std::swap(
132 const_cast<add_lvalue_reference_t<remove_const_t<DT>>>(container_),
133 const_cast<add_lvalue_reference_t<remove_const_t<DT>>>(other.container_)
134 );
135 std::swap(it_, other.it_);
136 std::swap(distance_, other.distance_);
137 }
138
139
141 it_ = std::next(it_);
142 distance_++;
143 return *this;
144 }
145
147 ref_iterator retval = *this;
148 ++(*this);
149 return retval;
150 }
151
153 if (it_ != std::begin(container_)) {
154 it_ = std::prev(it_);
155 distance_--;
156 }
157 return *this;
158 }
159
161 ref_iterator retval = *this;
162 --(*this);
163 return retval;
164 }
165
166
168 const typename ref_iterator::difference_type& movement
170 std::advance(it_, movement);
171 distance_ += movement;
172 return *this;
173 }
174
175
177 const typename ref_iterator::difference_type& movement
179 return (*this) += -movement;
180 }
181
182
183 std::enable_if_t<!std::is_const_v<ref_t>, remove_const_t<ref_t>>
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 std::enable_if_t<!std::is_const_v<ref_t>, remove_const_t<ref_t>> operator*() {
280 return const_cast<remove_const_t<ref_t>>(
281 static_cast<const ref_iterator*>(this)->operator*()
282 );
283 }
284
285 template<typename V = DT_VAL>
286 std::enable_if_t<std::is_pointer_v<V>, add_const_t<ref_t>> operator*() const {
287 assert(*it_ && "integrity error: nullptr");
288 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
289 }
290
291 template<typename V = DT_VAL>
292 std::enable_if_t<!std::is_pointer_v<V>, add_const_t<ref_t>> operator*() const {
293 return const_cast<add_const_t<ref_t>>(*(it_));
294 }
295
296
297 std::enable_if_t<!std::is_const_v<pointer_t>, pointer_t> operator->() {
298 return const_cast<remove_const_t<pointer_t>>(
299 static_cast<const ref_iterator*>(this)->operator->()
300 );
301 }
302
304 return const_cast<add_const_t<pointer_t>>(&(operator*()));
305 }
306
307 protected:
308 T container_;
309 ITERATOR_T it_;
310 typename ref_iterator::difference_type distance_{};
311};
312
313
315template<class T, typename U = typename decay_t<T>::value_type,
316 class CT = std::add_const_t<T>>
319
320
322template<class T, typename U = typename decay_t<T>::value_type,
323 class ITERATOR_T = typename decay_t<T>::iterator>
325
326 public:
327 using iterator_category = std::forward_iterator_tag;
329 using difference_type = ptrdiff_t;
330 using pointer = std::remove_pointer_t<U>*;
331 using reference = std::remove_pointer_t<U>&;
332
333 using container_type = T;
334 using DT_VAL = U;
335 using DT = decay_t<T>;
338 using filter_t = std::function<bool(const typename DT::value_type&)>;
339
341 size_c_(other.size_c_),
342 size_cached_(other.size_cached_),
343 container_(std::forward<T>(other.container_)),
344 it_(std::begin(container_)),
345 filters_{std::move(other.filters_)},
346 distance_(other.distance_) {
347 std::advance(it_, distance_);
348 }
349
351 if (this == &other) {
352 return *this;
353 }
354
355 size_c_ = other.size_c_;
356 size_cached_ = other.size_cached_;
357 container_ = std::forward<T>(other.container_);
358 it_ = std::begin(container_);
359 filters_ = std::move(other.filters_);
360 distance_ = other.distance_;
361
362 std::advance(it_, distance_);
363
364 return *this;
365 }
366
367 ~filter_iterator() = default;
368
369 // NOLINTNEXTLINE(performance-unnecessary-value-param)
370 filter_iterator(T container, filter_t filter) :
371 container_{std::forward<T>(container)},
372 it_(std::begin(container_)),
373 filters_{} {
374
375
376 filters_.push_back(std::move(filter));
377
378 if (it_ != std::end(container_)) {
379 if (!std::all_of(std::begin(filters_), std::end(filters_),
380 [this](const filter_t& f) { return f(*it_); }))
381 {
382 next();
383 }
384 }
385 }
386
387 // NOLINTNEXTLINE(performance-unnecessary-value-param)
388 filter_iterator(T container, const std::vector<filter_t>& filters) :
389 container_{std::forward<T>(container)},
390 it_(std::begin(container_)),
391 filters_{filters} {
392
393
394 if (it_ != std::end(container_)) {
395 if (!std::all_of(std::begin(filters_), std::end(filters_),
396 [this](const filter_t& f) { return f(*it_); }))
397 {
398 next();
399 }
400 }
401 }
402
403 // NOLINTNEXTLINE(performance-unnecessary-value-param)
404 filter_iterator(T container) :
405 container_{std::forward<T>(container)},
406 it_(std::begin(container_)),
407 filters_{} {}
408
410 container_{copy.container_},
411 it_{std::begin(container_)},
412 filters_{copy.filters_},
413 distance_{copy.distance_} {
414 std::advance(it_, distance_);
415 }
416
418 swap(other);
419 return *this;
420 }
421
422 void swap(filter_iterator& other) noexcept {
423 std::swap(const_cast<remove_const_t<DT>&>(container_),
424 const_cast<remove_const_t<DT>&>(other.container_));
425 std::swap(it_, other.it_);
426 std::swap(filters_, other.filters_);
427 std::swap(size_c_, other.size_c_);
428 std::swap(size_cached_, other.size_cached_);
429 std::swap(distance_, other.distance_);
430 }
431
432
434 filters_.push_back(func);
435 size_c_ = 0;
436 size_cached_ = false;
437 return *this;
438 }
439
441 next();
442 return *this;
443 }
444
446 filter_iterator retval = *this;
447 ++(*this);
448 return retval;
449 }
450
452 return {container_, filters_};
453 }
454
456 return begin();
457 }
458
460 // we don't need filter for the end iterator
461 filter_iterator it_end{container_};
462
463 it_end.it_ = it_end.container_.end();
464 it_end.distance_ = it_end.container_.size();
465
466 return it_end;
467 }
468
470 return end();
471 }
472
473 std::enable_if_t<!std::is_const_v<ref_t>, remove_const_t<ref_t>> operator*() {
474 return const_cast<remove_const_t<ref_t>>(
475 static_cast<const filter_iterator*>(this)->operator*()
476 );
477 }
478
479 template<typename V = DT_VAL>
480 std::enable_if_t<std::is_pointer_v<V>, add_const_t<ref_t>> operator*() const {
481 assert(*it_ && "integrity error: nullptr");
482 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
483 }
484
485 template<typename V = DT_VAL>
486 std::enable_if_t<!std::is_pointer_v<V>, add_const_t<ref_t>> operator*() const {
487 return const_cast<add_const_t<ref_t>>(*(it_));
488 }
489
490
491 std::enable_if_t<!std::is_const_v<ref_t>, remove_const_t<ref_t>>
492 operator[](size_t n) {
493 return const_cast<remove_const_t<ref_t>>(
494 static_cast<const filter_iterator*>(this)->operator[](n)
495 );
496 }
497
499 assert(n < size() && "integrity error: out of bound");
500
501 auto it = begin();
502 std::advance(it, n);
503 return const_cast<add_const_t<ref_t>>(*it);
504 }
505
506
507 std::enable_if_t<!std::is_const_v<pointer_t>, pointer_t> operator->() {
508 return const_cast<remove_const_t<pointer_t>>(
509 static_cast<const filter_iterator*>(this)->operator->()
510 );
511 }
512
514 return const_cast<add_const_t<pointer_t>>(&(operator*()));
515 }
516
517 size_t size() const {
518 if (filters_.empty()) {
519 return container_.size();
520 }
521
522 if (size_cached_) {
523 return size_c_;
524 }
525 filter_iterator it = begin();
526 size_t size = 0;
527
528 auto end_iter = it.end();
529 for (; it != end_iter; ++it) {
530 ++size;
531 }
532 size_c_ = size;
533 size_cached_ = true;
534 return size_c_;
535 }
536
537
538 bool empty() const {
539 if (filters_.empty()) {
540 return container_.empty();
541 }
542
543 if (size_cached_) {
544 return size_c_ == 0;
545 }
546
547 return begin() == end();
548 }
549
550
551 bool operator==(const filter_iterator& other) const {
552 return (container_.size() == other.container_.size() &&
553 distance_ == other.distance_);
554 }
555
556 bool operator!=(const filter_iterator& other) const {
557 return !(*this == other);
558 }
559
560 protected:
561 void next() {
562 if (it_ == std::end(container_)) {
563 distance_ = container_.size();
564 return;
565 }
566
567 do {
568 it_ = std::next(it_);
569 distance_++;
570 } while (it_ != std::end(container_) &&
571 !std::all_of(std::begin(filters_), std::end(filters_),
572 [this](const filter_t& f) { return f(*it_); }));
573 }
574
575
576 mutable size_t size_c_ = 0;
577 mutable bool size_cached_ = false;
578 T container_;
579 ITERATOR_T it_;
580 std::vector<filter_t> filters_;
581 typename filter_iterator::difference_type distance_ = 0;
582};
583
585template<class T, typename U = typename decay_t<T>::value_type,
586 class CT = std::add_const_t<T>>
589
590// ----------------------------------------------------------------------------
591// This part is taken from LLVM
592// ----------------------------------------------------------------------------
593
594template<typename IteratorT>
596 public:
597 using IteratorTy = IteratorT;
598 using IteratorDecayTy = std::decay_t<IteratorT>;
599
600 template<class T>
601 iterator_range(T&& it_begin, T&& it_end) :
602 begin_(std::forward<T>(it_begin)),
603 end_(std::forward<T>(it_end)) {}
604
605 IteratorT begin() const {
606 return begin_;
607 }
608 IteratorT end() const {
609 return end_;
610 }
611 bool empty() const {
612 return begin_ == end_;
613 }
614
615 class ReferenceProxy {
617
618 IteratorDecayTy it_;
619
620 explicit ReferenceProxy(IteratorDecayTy it) :
621 it_(std::move(it)) {}
622
623 public:
624 using reference = decltype(*std::declval<const IteratorDecayTy&>());
625
626 operator reference() const {
627 return *it_;
628 }
629
630 template<class It = IteratorDecayTy>
631 auto operator->() const -> decltype(&*std::declval<const It&>()) {
632 return &*it_;
633 }
634 };
635
636 ReferenceProxy at(typename IteratorDecayTy::difference_type pos) const {
637 static_assert(IsRandomAccess, "at() needs random access iterator");
638 auto it = begin_;
639 std::advance(it, pos);
640 return ReferenceProxy(std::move(it));
641 }
642
643 ReferenceProxy operator[](typename IteratorDecayTy::difference_type pos) const {
644 return at(pos);
645 }
646
647 std::ptrdiff_t size() const {
648 return std::distance(begin_, end_);
649 }
650
651 protected:
652 static constexpr bool IsRandomAccess =
653 std::is_base_of_v<std::random_access_iterator_tag,
654 typename IteratorDecayTy::iterator_category>;
655 static constexpr bool IsBidirectional =
656 std::is_base_of_v<std::bidirectional_iterator_tag,
657 typename IteratorDecayTy::iterator_category>;
658
659 private:
660 IteratorT begin_;
661 IteratorT end_;
662};
663
664template<class T>
666 return iterator_range<T>(std::forward<T>(x), std::forward<T>(y));
667}
668
669}
670
671#if LIEF_HAS_STD_RANGES
672template<typename IteratorT>
673inline constexpr bool
674 std::ranges::enable_borrowed_range<LIEF::iterator_range<IteratorT>> = true;
675#endif
676
677namespace LIEF {
678
679
737template<typename DerivedT, typename IteratorCategoryT, typename T,
738 typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T*,
739 typename ReferenceT = T&>
740class iterator_facade_base {
741 friend DerivedT;
742 iterator_facade_base() = default;
743
744 public:
745 using iterator_category = IteratorCategoryT;
746 using value_type = T;
747 using difference_type = DifferenceTypeT;
748 using pointer = PointerT;
749 using reference = ReferenceT;
750
751 protected:
752 static constexpr bool IsRandomAccess =
753 std::is_base_of_v<std::random_access_iterator_tag, IteratorCategoryT>;
754 static constexpr bool IsBidirectional =
755 std::is_base_of_v<std::bidirectional_iterator_tag, IteratorCategoryT>;
756
762 class ReferenceProxy {
763 friend iterator_facade_base;
764
765 DerivedT I;
766
767 ReferenceProxy(DerivedT I) :
768 I(std::move(I)) {}
769
770 public:
771 operator ReferenceT() const {
772 return *I;
773 }
774 };
775
780 class PointerProxy {
782
783 ReferenceT R;
784
785 template<typename RefT>
786 PointerProxy(RefT&& R) : // NOLINT(bugprone-forwarding-reference-overload)
787 R(std::forward<RefT>(R)) {}
788
789 public:
790 PointerT operator->() const {
791 return &R;
792 }
793 };
794
795 public:
796 DerivedT operator+(DifferenceTypeT n) const {
797 static_assert(std::is_base_of_v<iterator_facade_base, DerivedT>,
798 "Must pass the derived type to this template!");
799 static_assert(IsRandomAccess,
800 "The '+' operator is only defined for random access iterators.");
801 DerivedT tmp = *static_cast<const DerivedT*>(this);
802 tmp += n;
803 return tmp;
804 }
805 friend DerivedT operator+(DifferenceTypeT n, const DerivedT& i) {
806 static_assert(IsRandomAccess,
807 "The '+' operator is only defined for random access iterators.");
808 return i + n;
809 }
810 DerivedT operator-(DifferenceTypeT n) const {
811 static_assert(IsRandomAccess,
812 "The '-' operator is only defined for random access iterators.");
813 DerivedT tmp = *static_cast<const DerivedT*>(this);
814 tmp -= n;
815 return tmp;
816 }
817
819 static_assert(std::is_base_of_v<iterator_facade_base, DerivedT>,
820 "Must pass the derived type to this template!");
821 return static_cast<DerivedT*>(this)->operator+=(1);
822 }
824 DerivedT tmp = *static_cast<DerivedT*>(this);
825 ++*static_cast<DerivedT*>(this);
826 return tmp;
827 }
829 static_assert(
830 IsBidirectional,
831 "The decrement operator is only defined for bidirectional iterators."
832 );
833 return static_cast<DerivedT*>(this)->operator-=(1);
834 }
836 static_assert(
837 IsBidirectional,
838 "The decrement operator is only defined for bidirectional iterators."
839 );
840 DerivedT tmp = *static_cast<DerivedT*>(this);
841 --*static_cast<DerivedT*>(this);
842 return tmp;
843 }
844
845#ifndef __cpp_impl_three_way_comparison
846 bool operator!=(const DerivedT& RHS) const {
847 return !(static_cast<const DerivedT&>(*this) == RHS);
848 }
849#endif
850
851 bool operator>(const DerivedT& RHS) const {
852 static_assert(
853 IsRandomAccess,
854 "Relational operators are only defined for random access iterators."
855 );
856 return !(static_cast<const DerivedT&>(*this) < RHS) &&
857 !(static_cast<const DerivedT&>(*this) == RHS);
858 }
859 bool operator<=(const DerivedT& RHS) const {
860 static_assert(
861 IsRandomAccess,
862 "Relational operators are only defined for random access iterators."
863 );
864 return !(static_cast<const DerivedT&>(*this) > RHS);
865 }
866 bool operator>=(const DerivedT& RHS) const {
867 static_assert(
868 IsRandomAccess,
869 "Relational operators are only defined for random access iterators."
870 );
871 return !(static_cast<const DerivedT&>(*this) < RHS);
872 }
873
874 PointerProxy operator->() const {
875 return static_cast<const DerivedT*>(this)->operator*();
876 }
877 ReferenceProxy operator[](DifferenceTypeT n) const {
878 static_assert(IsRandomAccess,
879 "Subscripting is only defined for random access iterators.");
880 return static_cast<const DerivedT*>(this)->operator+(n);
881 }
882};
883
889template<typename DerivedT, typename WrappedIteratorT,
890 typename IteratorCategoryT =
891 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
892 typename T = typename std::iterator_traits<WrappedIteratorT>::value_type,
893 typename DifferenceTypeT =
894 typename std::iterator_traits<WrappedIteratorT>::difference_type,
895 typename PointerT = std::conditional_t<
896 std::is_same_v<T, typename std::iterator_traits<WrappedIteratorT>::
897 value_type>,
898 typename std::iterator_traits<WrappedIteratorT>::pointer, T*
899 >,
900 typename ReferenceT = std::conditional_t<
901 std::is_same_v<T, typename std::iterator_traits<WrappedIteratorT>::
902 value_type>,
903 typename std::iterator_traits<WrappedIteratorT>::reference, T&
904 >>
905class iterator_adaptor_base
906 : public iterator_facade_base<DerivedT, IteratorCategoryT, T, DifferenceTypeT,
907 PointerT, ReferenceT> {
908 using BaseT = typename iterator_adaptor_base::iterator_facade_base;
909
910 protected:
911 WrappedIteratorT I;
912
913 iterator_adaptor_base() = default;
914
915 explicit iterator_adaptor_base(WrappedIteratorT u) :
916 I(std::move(u)) {
917 static_assert(std::is_base_of_v<iterator_adaptor_base, DerivedT>,
918 "Must pass the derived type to this template!");
919 }
920
921 const WrappedIteratorT& wrapped() const {
922 return I;
923 }
924
925 public:
926 using difference_type = DifferenceTypeT;
927
929 static_assert(
930 BaseT::IsRandomAccess,
931 "The '+=' operator is only defined for random access iterators."
932 );
933 I += n;
934 return *static_cast<DerivedT*>(this);
935 }
937 static_assert(
938 BaseT::IsRandomAccess,
939 "The '-=' operator is only defined for random access iterators."
940 );
941 I -= n;
942 return *static_cast<DerivedT*>(this);
943 }
944 using BaseT::operator-;
946 static_assert(BaseT::IsRandomAccess,
947 "The '-' operator is only defined for random access iterators.");
948 return I - RHS.I;
949 }
950
951 // We have to explicitly provide ++ and -- rather than letting the facade
952 // forward to += because WrappedIteratorT might not support +=.
953 using BaseT::operator++;
955 ++I;
956 return *static_cast<DerivedT*>(this);
957 }
958 using BaseT::operator--;
960 static_assert(
961 BaseT::IsBidirectional,
962 "The decrement operator is only defined for bidirectional iterators."
963 );
964 --I;
965 return *static_cast<DerivedT*>(this);
966 }
967
968 friend bool operator==(const iterator_adaptor_base& LHS,
969 const iterator_adaptor_base& RHS) {
970 return LHS.I == RHS.I;
971 }
972 friend bool operator<(const iterator_adaptor_base& LHS,
973 const iterator_adaptor_base& RHS) {
974 static_assert(
975 BaseT::IsRandomAccess,
976 "Relational operators are only defined for random access iterators."
977 );
978 return LHS.I < RHS.I;
979 }
980
981 ReferenceT operator*() const {
982 return *I;
983 }
984};
985
995template<typename WrappedIteratorT,
996 typename T =
997 std::remove_reference_t<decltype(**std::declval<WrappedIteratorT>())>>
999 : iterator_adaptor_base<
1000 pointee_iterator<WrappedIteratorT, T>, WrappedIteratorT,
1001 typename std::iterator_traits<WrappedIteratorT>::iterator_category, T
1002 > {
1003 pointee_iterator() = default;
1004 template<typename U>
1005 pointee_iterator(U&& u) : // NOLINT(bugprone-forwarding-reference-overload)
1006 pointee_iterator::iterator_adaptor_base(std::forward<U>(u)) {}
1007
1008 T& operator*() const {
1009 return **this->I;
1010 }
1011};
1012
1013template<typename RangeT,
1014 typename WrappedIteratorT = decltype(std::begin(std::declval<RangeT>()))>
1015iterator_range<pointee_iterator<WrappedIteratorT>>
1016 make_pointee_range(RangeT&& Range) {
1017 using PointeeIteratorT = pointee_iterator<WrappedIteratorT>;
1018 return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
1019 PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
1020}
1021
1022template<typename WrappedIteratorT,
1023 typename T = decltype(&*std::declval<WrappedIteratorT>())>
1025 : public iterator_adaptor_base<
1026 pointer_iterator<WrappedIteratorT, T>, WrappedIteratorT,
1027 typename std::iterator_traits<WrappedIteratorT>::iterator_category, T
1028 > {
1029 mutable T Ptr;
1030
1031 public:
1032 pointer_iterator() = default;
1033
1034 explicit pointer_iterator(WrappedIteratorT u) :
1035 pointer_iterator::iterator_adaptor_base(std::move(u)) {}
1036
1037 T& operator*() const {
1038 return Ptr = &*this->I;
1039 }
1040};
1041
1042template<typename RangeT,
1043 typename WrappedIteratorT = decltype(std::begin(std::declval<RangeT>()))>
1044iterator_range<pointer_iterator<WrappedIteratorT>>
1045 make_pointer_range(RangeT&& Range) {
1046 using PointerIteratorT = pointer_iterator<WrappedIteratorT>;
1047 return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
1048 PointerIteratorT(std::end(std::forward<RangeT>(Range))));
1049}
1050
1051template<typename WrappedIteratorT,
1052 typename T1 =
1053 std::remove_reference_t<decltype(**std::declval<WrappedIteratorT>())>,
1054 typename T2 = std::add_pointer_t<T1>>
1057}
1058
1059#endif
Iterator which returns a ref on container's values given predicates.
Definition iterators.hpp:324
std::enable_if_t<!std::is_const_v< pointer_t >, pointer_t > operator->()
Definition iterators.hpp:507
bool operator==(const filter_iterator &other) const
Definition iterators.hpp:551
filter_iterator(const filter_iterator &copy)
Definition iterators.hpp:409
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:498
filter_iterator cend() const
Definition iterators.hpp:469
std::enable_if_t< std::is_pointer_v< V >, add_const_t< ref_t > > operator*() const
Definition iterators.hpp:480
filter_iterator(T container, filter_t filter)
Definition iterators.hpp:370
std::forward_iterator_tag iterator_category
Definition iterators.hpp:327
std::enable_if_t<!std::is_const_v< ref_t >, remove_const_t< ref_t > > operator*()
Definition iterators.hpp:473
filter_iterator(T container)
Definition iterators.hpp:404
void swap(filter_iterator &other) noexcept
Definition iterators.hpp:422
filter_iterator & operator++()
Definition iterators.hpp:440
filter_iterator(T container, const std::vector< filter_t > &filters)
Definition iterators.hpp:388
filter_iterator end() const
Definition iterators.hpp:459
typename filter_iterator::pointer pointer_t
Definition iterators.hpp:337
filter_iterator & operator=(filter_iterator other)
Definition iterators.hpp:417
decay_t< Symbol * > value_type
Definition iterators.hpp:328
std::remove_pointer_t< Symbol * > * pointer
Definition iterators.hpp:330
typename filter_iterator::reference ref_t
Definition iterators.hpp:336
filter_iterator begin() const
Definition iterators.hpp:451
bool empty() const
Definition iterators.hpp:538
std::enable_if_t<!std::is_const_v< ref_t >, remove_const_t< ref_t > > operator[](size_t n)
Definition iterators.hpp:492
Symbol * DT_VAL
Definition iterators.hpp:334
ptrdiff_t difference_type
Definition iterators.hpp:329
~filter_iterator()=default
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:513
size_t size() const
Definition iterators.hpp:517
bool operator!=(const filter_iterator &other) const
Definition iterators.hpp:556
std::function< bool(const typename DT::value_type &)> filter_t
Definition iterators.hpp:338
std::enable_if_t<!std::is_pointer_v< V >, add_const_t< ref_t > > operator*() const
Definition iterators.hpp:486
std::remove_pointer_t< Symbol * > & reference
Definition iterators.hpp:331
filter_iterator(filter_iterator &&other) noexcept
Definition iterators.hpp:340
symbols_t & container_type
Definition iterators.hpp:333
filter_iterator operator++(int)
Definition iterators.hpp:445
decay_t< symbols_t & > DT
Definition iterators.hpp:335
filter_iterator cbegin() const
Definition iterators.hpp:455
filter_iterator & def(filter_t func)
Definition iterators.hpp:433
filter_iterator & operator=(filter_iterator &&other) noexcept
Definition iterators.hpp:350
DerivedT & operator++()
Definition iterators.hpp:954
DerivedT & operator--()
Definition iterators.hpp:959
DerivedT & operator-=(difference_type n)
Definition iterators.hpp:936
ReferenceT operator*() const
Definition iterators.hpp:981
friend bool operator<(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:972
friend bool operator==(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:968
DifferenceTypeT difference_type
Definition iterators.hpp:926
DerivedT & operator+=(difference_type n)
Definition iterators.hpp:928
difference_type operator-(const DerivedT &RHS) const
Definition iterators.hpp:945
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterators.hpp:740
DifferenceTypeT difference_type
Definition iterators.hpp:747
PointerProxy operator->() const
Definition iterators.hpp:874
DerivedT & operator--()
Definition iterators.hpp:828
DerivedT operator++(int)
Definition iterators.hpp:823
T value_type
Definition iterators.hpp:746
friend DerivedT
Definition iterators.hpp:741
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
Definition iterators.hpp:805
bool operator>(const DerivedT &RHS) const
Definition iterators.hpp:851
ReferenceProxy operator[](DifferenceTypeT n) const
Definition iterators.hpp:877
ReferenceT reference
Definition iterators.hpp:749
bool operator>=(const DerivedT &RHS) const
Definition iterators.hpp:866
DerivedT operator-(DifferenceTypeT n) const
Definition iterators.hpp:810
DerivedT & operator++()
Definition iterators.hpp:818
PointerT pointer
Definition iterators.hpp:748
DerivedT operator--(int)
Definition iterators.hpp:835
IteratorCategoryT iterator_category
Definition iterators.hpp:745
DerivedT operator+(DifferenceTypeT n) const
Definition iterators.hpp:796
bool operator!=(const DerivedT &RHS) const
Definition iterators.hpp:846
bool operator<=(const DerivedT &RHS) const
Definition iterators.hpp:859
decltype(*std::declval< const IteratorDecayTy & >()) reference
Definition iterators.hpp:624
auto operator->() const -> decltype(&*std::declval< const It & >())
Definition iterators.hpp:631
friend iterator_range
Definition iterators.hpp:616
Definition iterators.hpp:595
IteratorT begin() const
Definition iterators.hpp:605
ReferenceProxy at(typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:636
std::decay_t< assembly::Instruction::Iterator > IteratorDecayTy
Definition iterators.hpp:598
iterator_range(T &&it_begin, T &&it_end)
Definition iterators.hpp:601
IteratorT end() const
Definition iterators.hpp:608
bool empty() const
Definition iterators.hpp:611
ReferenceProxy operator[](typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:643
assembly::Instruction::Iterator IteratorTy
Definition iterators.hpp:597
std::ptrdiff_t size() const
Definition iterators.hpp:647
Definition iterators.hpp:1028
T & operator*() const
Definition iterators.hpp:1037
pointer_iterator(WrappedIteratorT u)
Definition iterators.hpp:1034
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:152
size_t size() const
Definition iterators.hpp:271
ref_iterator & operator++()
Definition iterators.hpp:140
void swap(ref_iterator &other) noexcept
Definition iterators.hpp:130
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:146
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:160
ref_iterator cend() const
Definition iterators.hpp:259
std::enable_if_t<!std::is_pointer_v< V >, add_const_t< ref_t > > operator*() const
Definition iterators.hpp:292
ref_iterator & operator+=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:167
std::enable_if_t<!std::is_const_v< ref_t >, remove_const_t< ref_t > > operator[](size_t n)
Definition iterators.hpp:184
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:279
std::enable_if_t< std::is_pointer_v< V >, add_const_t< ref_t > > operator*() const
Definition iterators.hpp:286
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
ref_iterator cbegin() const
Definition iterators.hpp:248
bool empty() const
Definition iterators.hpp:275
ref_iterator & operator=(ref_iterator other)
Definition iterators.hpp:125
ref_iterator & operator=(ref_iterator &&other) noexcept
Definition iterators.hpp:71
bool operator!=(const ref_iterator &other) const
Definition iterators.hpp:267
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:118
ref_iterator(ref_iterator< T2, U2, IT2 > &&other) noexcept
Definition iterators.hpp:102
ref_iterator end() const
Definition iterators.hpp:252
ref_iterator & operator-=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:176
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
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:297
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:114
~ref_iterator()=default
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:303
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
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:587
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
Definition iterators.hpp:1016
iterator_range< T > make_range(T &&x, T &&y)
Definition iterators.hpp:665
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterators.hpp:1045
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:317
pointer_iterator< pointee_iterator< WrappedIteratorT, T1 >, T2 > raw_pointer_iterator
Definition iterators.hpp:1055
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:1002
T & operator*() const
Definition iterators.hpp:1008
pointee_iterator(U &&u)
Definition iterators.hpp:1005