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 operator+=(const typename ref_iterator::difference_type& movement) {
168 std::advance(it_, movement);
169 distance_ += movement;
170 return *this;
171 }
172
173
175 operator-=(const typename ref_iterator::difference_type& movement) {
176 return (*this) += -movement;
177 }
178
179
180 typename std::enable_if<!std::is_const<ref_t>::value,
182 operator[](size_t n) {
183 return const_cast<remove_const_t<ref_t>>(
184 static_cast<const ref_iterator*>(this)->operator[](n)
185 );
186 }
187
188
190 assert(n < size() && "integrity error: out of bound");
191
192 auto* no_const_this = const_cast<ref_iterator*>(this);
193
194 typename ref_iterator::difference_type saved_dist =
195 std::distance(std::begin(no_const_this->container_), no_const_this->it_);
196 no_const_this->it_ = std::begin(no_const_this->container_);
197 std::advance(no_const_this->it_, n);
198
199 auto&& v = const_cast<add_const_t<ref_t>>(no_const_this->operator*());
200
201 no_const_this->it_ = std::begin(no_const_this->container_);
202 std::advance(no_const_this->it_, saved_dist);
203
204 return v;
205 }
206
208 ref_iterator tmp = *this;
209 return tmp += n;
210 }
211
212
214 ref_iterator tmp = *this;
215 return tmp -= n;
216 }
217
218
220 return distance_ - rhs.distance_;
221 }
222
223 bool operator<(const ref_iterator& rhs) const {
224 return (rhs - *this) > 0;
225 }
226
227
228 bool operator>(const ref_iterator& rhs) const {
229 return rhs < *this;
230 }
231
232
233 bool operator>=(const ref_iterator& rhs) const {
234 return !(*this < rhs);
235 }
236
237
238 bool operator<=(const ref_iterator& rhs) const {
239 return !(*this > rhs);
240 }
241
243 return container_;
244 }
245
247 return begin();
248 }
249
251 ref_iterator it = ref_iterator{container_};
252 it.it_ = std::end(it.container_);
253 it.distance_ = it.size();
254 return it;
255 }
256
258 return end();
259 }
260
261 bool operator==(const ref_iterator& other) const {
262 return (size() == other.size() && distance_ == other.distance_);
263 }
264
265 bool operator!=(const ref_iterator& other) const {
266 return !(*this == other);
267 }
268
269 size_t size() const {
270 return container_.size();
271 }
272
273 bool empty() const {
274 return container_.empty();
275 }
276
277 typename std::enable_if<!std::is_const<ref_t>::value,
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 typename std::enable_if<std::is_pointer<V>::value, add_const_t<ref_t>>::type
287 operator*() const {
288 assert(*it_ && "integrity error: nullptr");
289 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
290 }
291
292 template<typename V = DT_VAL>
293 typename std::enable_if<!std::is_pointer<V>::value, add_const_t<ref_t>>::type
294 operator*() const {
295 return const_cast<add_const_t<ref_t>>(*(it_));
296 }
297
298
299 typename std::enable_if<!std::is_const<pointer_t>::value, pointer_t>::type
301 return const_cast<remove_const_t<pointer_t>>(
302 static_cast<const ref_iterator*>(this)->operator->()
303 );
304 }
305
307 return const_cast<add_const_t<pointer_t>>(&(operator*()));
308 }
309
310 protected:
311 T container_;
312 ITERATOR_T it_;
313 typename ref_iterator::difference_type distance_{};
314};
315
316
318template<class T, typename U = typename decay_t<T>::value_type,
319 class CT = typename std::add_const<T>::type>
322
323
325template<class T, typename U = typename decay_t<T>::value_type,
326 class ITERATOR_T = typename decay_t<T>::iterator>
328
329 public:
330 using iterator_category = std::forward_iterator_tag;
332 using difference_type = ptrdiff_t;
333 using pointer = typename std::remove_pointer<U>::type*;
334 using reference = typename std::remove_pointer<U>::type&;
335
336 using container_type = T;
337 using DT_VAL = U;
338 using DT = decay_t<T>;
341 using filter_t = std::function<bool(const typename DT::value_type&)>;
342
344 size_c_(other.size_c_),
345 size_cached_(other.size_cached_),
346 container_(std::forward<T>(other.container_)),
347 it_(std::begin(container_)),
348 filters_{std::move(other.filters_)},
349 distance_(other.distance_) {
350 std::advance(it_, distance_);
351 }
352
354 if (this == &other) {
355 return *this;
356 }
357
358 size_c_ = other.size_c_;
359 size_cached_ = other.size_cached_;
360 container_ = std::forward<T>(other.container_);
361 it_ = std::begin(container_);
362 filters_ = std::move(other.filters_);
363 distance_ = other.distance_;
364
365 std::advance(it_, distance_);
366
367 return *this;
368 }
369
370 ~filter_iterator() = default;
371
372 filter_iterator(T container, filter_t filter) :
373 container_{std::forward<T>(container)},
374 it_(std::begin(container_)),
375 filters_{} {
376
377
378 filters_.push_back(filter);
379
380 if (it_ != std::end(container_)) {
381 if (!std::all_of(std::begin(filters_), std::end(filters_),
382 [this](const filter_t& f) { return f(*it_); }))
383 {
384 next();
385 }
386 }
387 }
388
389 filter_iterator(T container, const std::vector<filter_t>& filters) :
390 container_{std::forward<T>(container)},
391 it_(std::begin(container_)),
392 filters_{filters} {
393
394
395 if (it_ != std::end(container_)) {
396 if (!std::all_of(std::begin(filters_), std::end(filters_),
397 [this](const filter_t& f) { return f(*it_); }))
398 {
399 next();
400 }
401 }
402 }
403
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 typename std::enable_if<!std::is_const<ref_t>::value,
476 return const_cast<remove_const_t<ref_t>>(
477 static_cast<const filter_iterator*>(this)->operator*()
478 );
479 }
480
481 template<typename V = DT_VAL>
482 typename std::enable_if<std::is_pointer<V>::value, add_const_t<ref_t>>::type
483 operator*() const {
484 assert(*it_ && "integrity error: nullptr");
485 return const_cast<add_const_t<ref_t>>(static_cast<ref_t>(**it_));
486 }
487
488 template<typename V = DT_VAL>
489 typename std::enable_if<!std::is_pointer<V>::value, add_const_t<ref_t>>::type
490 operator*() const {
491 return const_cast<add_const_t<ref_t>>(*(it_));
492 }
493
494
495 typename std::enable_if<!std::is_const<ref_t>::value,
497 operator[](size_t n) {
498 return const_cast<remove_const_t<ref_t>>(
499 static_cast<const filter_iterator*>(this)->operator[](n)
500 );
501 }
502
504 assert(n < size() && "integrity error: out of bound");
505
506 auto it = begin();
507 std::advance(it, n);
508 return const_cast<add_const_t<ref_t>>(*it);
509 }
510
511
512 typename std::enable_if<!std::is_const<pointer_t>::value, pointer_t>::type
514 return const_cast<remove_const_t<pointer_t>>(
515 static_cast<const filter_iterator*>(this)->operator->()
516 );
517 }
518
520 return const_cast<add_const_t<pointer_t>>(&(operator*()));
521 }
522
523 size_t size() const {
524 if (filters_.empty()) {
525 return container_.size();
526 }
527
528 if (size_cached_) {
529 return size_c_;
530 }
531 filter_iterator it = begin();
532 size_t size = 0;
533
534 auto end_iter = it.end();
535 for (; it != end_iter; ++it) {
536 ++size;
537 }
538 size_c_ = size;
539 size_cached_ = true;
540 return size_c_;
541 }
542
543
544 bool empty() const {
545 if (filters_.empty()) {
546 return container_.empty();
547 }
548
549 if (size_cached_) {
550 return size_c_ == 0;
551 }
552
553 return begin() == end();
554 }
555
556
557 bool operator==(const filter_iterator& other) const {
558 return (container_.size() == other.container_.size() &&
559 distance_ == other.distance_);
560 }
561
562 bool operator!=(const filter_iterator& other) const {
563 return !(*this == other);
564 }
565
566 protected:
567 void next() {
568 if (it_ == std::end(container_)) {
569 distance_ = container_.size();
570 return;
571 }
572
573 do {
574 it_ = std::next(it_);
575 distance_++;
576 } while (it_ != std::end(container_) &&
577 !std::all_of(std::begin(filters_), std::end(filters_),
578 [this](const filter_t& f) { return f(*it_); }));
579 }
580
581
582 mutable size_t size_c_ = 0;
583 mutable bool size_cached_ = false;
584 T container_;
585 ITERATOR_T it_;
586 std::vector<filter_t> filters_;
587 typename filter_iterator::difference_type distance_ = 0;
588};
589
591template<class T, typename U = typename decay_t<T>::value_type,
592 class CT = typename std::add_const<T>::type>
595
596// ----------------------------------------------------------------------------
597// This part is taken from LLVM
598// ----------------------------------------------------------------------------
599
600template<typename IteratorT>
602 public:
603 using IteratorTy = IteratorT;
604 using IteratorDecayTy = typename std::decay<IteratorT>::type;
605
606 template<class T>
607 iterator_range(T&& it_begin, T&& it_end) :
608 begin_(std::forward<T>(it_begin)),
609 end_(std::forward<T>(it_end)) {}
610
611 IteratorT begin() const {
612 return begin_;
613 }
614 IteratorT end() const {
615 return end_;
616 }
617 bool empty() const {
618 return begin_ == end_;
619 }
620
621 typename IteratorDecayTy::value_type
622 at(typename IteratorDecayTy::difference_type pos) const {
623 static_assert(IsRandomAccess, "at() needs random access iterator");
624 auto it = begin_;
625 std::advance(it, pos);
626 return *it;
627 }
628
629 typename IteratorDecayTy::value_type
630 operator[](typename IteratorDecayTy::difference_type pos) const {
631 return at(pos);
632 }
633
634 std::ptrdiff_t size() const {
635 return std::distance(begin_, end_);
636 }
637
638 protected:
639 enum {
640 IsRandomAccess =
641 std::is_base_of<std::random_access_iterator_tag,
642 typename IteratorDecayTy::iterator_category>::value,
643 IsBidirectional =
644 std::is_base_of<std::bidirectional_iterator_tag,
645 typename IteratorDecayTy::iterator_category>::value,
646 };
647
648 private:
649 IteratorT begin_;
650 IteratorT end_;
651};
652
653template<class T>
655 return iterator_range<T>(std::forward<T>(x), std::forward<T>(y));
656}
657
658} // namespace LIEF
659
660#if LIEF_HAS_STD_RANGES
661template<typename IteratorT>
662inline constexpr bool
663 std::ranges::enable_borrowed_range<LIEF::iterator_range<IteratorT>> = true;
664#endif
665
666namespace LIEF {
667
668
726template<typename DerivedT, typename IteratorCategoryT, typename T,
727 typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T*,
728 typename ReferenceT = T&>
730 public:
731 using iterator_category = IteratorCategoryT;
732 using value_type = T;
733 using difference_type = DifferenceTypeT;
734 using pointer = PointerT;
735 using reference = ReferenceT;
736
737 protected:
738 enum {
739 IsRandomAccess =
740 std::is_base_of<std::random_access_iterator_tag, IteratorCategoryT>::value,
741 IsBidirectional =
742 std::is_base_of<std::bidirectional_iterator_tag, IteratorCategoryT>::value,
743 };
744
750 class ReferenceProxy {
752
753 DerivedT I;
754
755 ReferenceProxy(DerivedT I) :
756 I(std::move(I)) {}
757
758 public:
759 operator ReferenceT() const {
760 return *I;
761 }
762 };
763
768 class PointerProxy {
769 friend iterator_facade_base;
770
771 ReferenceT R;
772
773 template<typename RefT>
774 PointerProxy(RefT&& R) : // NOLINT(bugprone-forwarding-reference-overload)
775 R(std::forward<RefT>(R)) {}
776
777 public:
778 PointerT operator->() const {
779 return &R;
780 }
781 };
782
783 public:
784 DerivedT operator+(DifferenceTypeT n) const {
785 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
786 "Must pass the derived type to this template!");
787 static_assert(IsRandomAccess,
788 "The '+' operator is only defined for random access iterators.");
789 DerivedT tmp = *static_cast<const DerivedT*>(this);
790 tmp += n;
791 return tmp;
792 }
793 friend DerivedT operator+(DifferenceTypeT n, const DerivedT& i) {
794 static_assert(IsRandomAccess,
795 "The '+' operator is only defined for random access iterators.");
796 return i + n;
797 }
798 DerivedT operator-(DifferenceTypeT n) const {
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
806 DerivedT& operator++() {
807 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
808 "Must pass the derived type to this template!");
809 return static_cast<DerivedT*>(this)->operator+=(1);
810 }
811 DerivedT operator++(int) {
812 DerivedT tmp = *static_cast<DerivedT*>(this);
813 ++*static_cast<DerivedT*>(this);
814 return tmp;
815 }
816 DerivedT& operator--() {
817 static_assert(
818 IsBidirectional,
819 "The decrement operator is only defined for bidirectional iterators."
820 );
821 return static_cast<DerivedT*>(this)->operator-=(1);
822 }
823 DerivedT operator--(int) {
824 static_assert(
825 IsBidirectional,
826 "The decrement operator is only defined for bidirectional iterators."
827 );
828 DerivedT tmp = *static_cast<DerivedT*>(this);
829 --*static_cast<DerivedT*>(this);
830 return tmp;
831 }
832
833#ifndef __cpp_impl_three_way_comparison
834 bool operator!=(const DerivedT& RHS) const {
835 return !(static_cast<const DerivedT&>(*this) == RHS);
836 }
837#endif
838
839 bool operator>(const DerivedT& RHS) const {
840 static_assert(
841 IsRandomAccess,
842 "Relational operators are only defined for random access iterators."
843 );
844 return !(static_cast<const DerivedT&>(*this) < RHS) &&
845 !(static_cast<const DerivedT&>(*this) == RHS);
846 }
847 bool operator<=(const DerivedT& RHS) const {
848 static_assert(
849 IsRandomAccess,
850 "Relational operators are only defined for random access iterators."
851 );
852 return !(static_cast<const DerivedT&>(*this) > RHS);
853 }
854 bool operator>=(const DerivedT& RHS) const {
855 static_assert(
856 IsRandomAccess,
857 "Relational operators are only defined for random access iterators."
858 );
859 return !(static_cast<const DerivedT&>(*this) < RHS);
860 }
861
862 PointerProxy operator->() const {
863 return static_cast<const DerivedT*>(this)->operator*();
864 }
865 ReferenceProxy operator[](DifferenceTypeT n) const {
866 static_assert(IsRandomAccess,
867 "Subscripting is only defined for random access iterators.");
868 return static_cast<const DerivedT*>(this)->operator+(n);
869 }
870};
871
877template<typename DerivedT, typename WrappedIteratorT,
878 typename IteratorCategoryT =
879 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
880 typename T = typename std::iterator_traits<WrappedIteratorT>::value_type,
881 typename DifferenceTypeT =
882 typename std::iterator_traits<WrappedIteratorT>::difference_type,
883 typename PointerT = typename std::conditional<
884 std::is_same<T, typename std::iterator_traits<WrappedIteratorT>::
885 value_type>::value,
886 typename std::iterator_traits<WrappedIteratorT>::pointer, T*
887 >::type,
888 typename ReferenceT = typename std::conditional<
889 std::is_same<T, typename std::iterator_traits<WrappedIteratorT>::
890 value_type>::value,
891 typename std::iterator_traits<WrappedIteratorT>::reference, T&
892 >::type>
893class iterator_adaptor_base
894 : public iterator_facade_base<DerivedT, IteratorCategoryT, T, DifferenceTypeT,
895 PointerT, ReferenceT> {
896 using BaseT = typename iterator_adaptor_base::iterator_facade_base;
897
898 protected:
899 WrappedIteratorT I;
900
901 iterator_adaptor_base() = default;
902
903 explicit iterator_adaptor_base(WrappedIteratorT u) :
904 I(std::move(u)) {
905 static_assert(std::is_base_of<iterator_adaptor_base, DerivedT>::value,
906 "Must pass the derived type to this template!");
907 }
908
909 const WrappedIteratorT& wrapped() const {
910 return I;
911 }
912
913 public:
914 using difference_type = DifferenceTypeT;
915
917 static_assert(
918 BaseT::IsRandomAccess,
919 "The '+=' operator is only defined for random access iterators."
920 );
921 I += n;
922 return *static_cast<DerivedT*>(this);
923 }
925 static_assert(
926 BaseT::IsRandomAccess,
927 "The '-=' operator is only defined for random access iterators."
928 );
929 I -= n;
930 return *static_cast<DerivedT*>(this);
931 }
932 using BaseT::operator-;
933 difference_type operator-(const DerivedT& RHS) const {
934 static_assert(BaseT::IsRandomAccess,
935 "The '-' operator is only defined for random access iterators.");
936 return I - RHS.I;
937 }
938
939 // We have to explicitly provide ++ and -- rather than letting the facade
940 // forward to += because WrappedIteratorT might not support +=.
941 using BaseT::operator++;
942 DerivedT& operator++() {
943 ++I;
944 return *static_cast<DerivedT*>(this);
945 }
946 using BaseT::operator--;
947 DerivedT& operator--() {
948 static_assert(
949 BaseT::IsBidirectional,
950 "The decrement operator is only defined for bidirectional iterators."
951 );
952 --I;
953 return *static_cast<DerivedT*>(this);
954 }
955
956 friend bool operator==(const iterator_adaptor_base& LHS,
957 const iterator_adaptor_base& RHS) {
958 return LHS.I == RHS.I;
959 }
960 friend bool operator<(const iterator_adaptor_base& LHS,
961 const iterator_adaptor_base& RHS) {
962 static_assert(
963 BaseT::IsRandomAccess,
964 "Relational operators are only defined for random access iterators."
965 );
966 return LHS.I < RHS.I;
967 }
968
969 ReferenceT operator*() const {
970 return *I;
971 }
972};
973
983template<typename WrappedIteratorT,
984 typename T = typename std::
985 remove_reference<decltype(**std::declval<WrappedIteratorT>())>::type>
987 : iterator_adaptor_base<
988 pointee_iterator<WrappedIteratorT, T>, WrappedIteratorT,
989 typename std::iterator_traits<WrappedIteratorT>::iterator_category, T
990 > {
991 pointee_iterator() = default;
992 template<typename U>
993 pointee_iterator(U&& u) : // NOLINT(bugprone-forwarding-reference-overload)
994 pointee_iterator::iterator_adaptor_base(std::forward<U>(u)) {}
995
996 T& operator*() const {
997 return **this->I;
998 }
999};
1000
1001template<typename RangeT,
1002 typename WrappedIteratorT = decltype(std::begin(std::declval<RangeT>()))>
1003iterator_range<pointee_iterator<WrappedIteratorT>>
1004 make_pointee_range(RangeT&& Range) {
1005 using PointeeIteratorT = pointee_iterator<WrappedIteratorT>;
1006 return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
1007 PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
1008}
1009
1010template<typename WrappedIteratorT,
1011 typename T = decltype(&*std::declval<WrappedIteratorT>())>
1013 : public iterator_adaptor_base<
1014 pointer_iterator<WrappedIteratorT, T>, WrappedIteratorT,
1015 typename std::iterator_traits<WrappedIteratorT>::iterator_category, T
1016 > {
1017 mutable T Ptr;
1018
1019 public:
1020 pointer_iterator() = default;
1021
1022 explicit pointer_iterator(WrappedIteratorT u) :
1023 pointer_iterator::iterator_adaptor_base(std::move(u)) {}
1024
1025 T& operator*() const {
1026 return Ptr = &*this->I;
1027 }
1028};
1029
1030template<typename RangeT,
1031 typename WrappedIteratorT = decltype(std::begin(std::declval<RangeT>()))>
1032iterator_range<pointer_iterator<WrappedIteratorT>>
1033 make_pointer_range(RangeT&& Range) {
1034 using PointerIteratorT = pointer_iterator<WrappedIteratorT>;
1035 return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
1036 PointerIteratorT(std::end(std::forward<RangeT>(Range))));
1037}
1038
1039template<typename WrappedIteratorT,
1040 typename T1 = typename std::
1041 remove_reference<decltype(**std::declval<WrappedIteratorT>())>::type,
1042 typename T2 = typename std::add_pointer<T1>::type>
1045
1046}
1047
1048#endif
Iterator which returns a ref on container's values given predicates.
Definition iterators.hpp:327
std::enable_if<!std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:490
bool operator==(const filter_iterator &other) const
Definition iterators.hpp:557
filter_iterator(const filter_iterator &copy)
Definition iterators.hpp:409
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:503
filter_iterator cend() const
Definition iterators.hpp:469
typename std::remove_pointer< Symbol * >::type * pointer
Definition iterators.hpp:333
filter_iterator(T container, filter_t filter)
Definition iterators.hpp:372
std::forward_iterator_tag iterator_category
Definition iterators.hpp:330
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
std::enable_if<!std::is_const< pointer_t >::value, pointer_t >::type operator->()
Definition iterators.hpp:513
filter_iterator(T container, const std::vector< filter_t > &filters)
Definition iterators.hpp:389
filter_iterator end() const
Definition iterators.hpp:459
typename filter_iterator::pointer pointer_t
Definition iterators.hpp:340
filter_iterator & operator=(filter_iterator other)
Definition iterators.hpp:417
decay_t< Symbol * > value_type
Definition iterators.hpp:331
typename filter_iterator::reference ref_t
Definition iterators.hpp:339
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator*()
Definition iterators.hpp:475
filter_iterator begin() const
Definition iterators.hpp:451
bool empty() const
Definition iterators.hpp:544
Symbol * DT_VAL
Definition iterators.hpp:337
ptrdiff_t difference_type
Definition iterators.hpp:332
~filter_iterator()=default
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:519
size_t size() const
Definition iterators.hpp:523
std::enable_if< std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:483
bool operator!=(const filter_iterator &other) const
Definition iterators.hpp:562
std::function< bool(const typename DT::value_type &)> filter_t
Definition iterators.hpp:341
filter_iterator(filter_iterator &&other) noexcept
Definition iterators.hpp:343
symbols_t & container_type
Definition iterators.hpp:336
filter_iterator operator++(int)
Definition iterators.hpp:445
decay_t< symbols_t & > DT
Definition iterators.hpp:338
filter_iterator cbegin() const
Definition iterators.hpp:455
filter_iterator & def(filter_t func)
Definition iterators.hpp:433
typename std::remove_pointer< Symbol * >::type & reference
Definition iterators.hpp:334
filter_iterator & operator=(filter_iterator &&other) noexcept
Definition iterators.hpp:353
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator[](size_t n)
Definition iterators.hpp:497
DerivedT & operator++()
Definition iterators.hpp:942
DerivedT & operator--()
Definition iterators.hpp:947
DerivedT & operator-=(difference_type n)
Definition iterators.hpp:924
ReferenceT operator*() const
Definition iterators.hpp:969
friend bool operator<(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:960
friend bool operator==(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:956
DifferenceTypeT difference_type
Definition iterators.hpp:914
DerivedT & operator+=(difference_type n)
Definition iterators.hpp:916
difference_type operator-(const DerivedT &RHS) const
Definition iterators.hpp:933
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterators.hpp:729
DifferenceTypeT difference_type
Definition iterators.hpp:733
PointerProxy operator->() const
Definition iterators.hpp:862
DerivedT & operator--()
Definition iterators.hpp:816
DerivedT operator++(int)
Definition iterators.hpp:811
T value_type
Definition iterators.hpp:732
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
Definition iterators.hpp:793
bool operator>(const DerivedT &RHS) const
Definition iterators.hpp:839
ReferenceProxy operator[](DifferenceTypeT n) const
Definition iterators.hpp:865
ReferenceT reference
Definition iterators.hpp:735
bool operator>=(const DerivedT &RHS) const
Definition iterators.hpp:854
DerivedT operator-(DifferenceTypeT n) const
Definition iterators.hpp:798
DerivedT & operator++()
Definition iterators.hpp:806
PointerT pointer
Definition iterators.hpp:734
DerivedT operator--(int)
Definition iterators.hpp:823
IteratorCategoryT iterator_category
Definition iterators.hpp:731
DerivedT operator+(DifferenceTypeT n) const
Definition iterators.hpp:784
bool operator!=(const DerivedT &RHS) const
Definition iterators.hpp:834
bool operator<=(const DerivedT &RHS) const
Definition iterators.hpp:847
Definition iterators.hpp:601
IteratorT begin() const
Definition iterators.hpp:611
iterator_range(T &&it_begin, T &&it_end)
Definition iterators.hpp:607
IteratorT end() const
Definition iterators.hpp:614
bool empty() const
Definition iterators.hpp:617
IteratorDecayTy::value_type at(typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:622
assembly::Instruction::Iterator IteratorTy
Definition iterators.hpp:603
IteratorDecayTy::value_type operator[](typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:630
std::ptrdiff_t size() const
Definition iterators.hpp:634
typename std::decay< assembly::Instruction::Iterator >::type IteratorDecayTy
Definition iterators.hpp:604
Definition iterators.hpp:1016
T & operator*() const
Definition iterators.hpp:1025
pointer_iterator(WrappedIteratorT u)
Definition iterators.hpp:1022
Iterator which returns reference on container's values.
Definition iterators.hpp:47
bool operator<=(const ref_iterator &rhs) const
Definition iterators.hpp:238
ref_iterator & operator--()
Definition iterators.hpp:151
size_t size() const
Definition iterators.hpp:269
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:223
ref_iterator operator-(typename ref_iterator::difference_type n) const
Definition iterators.hpp:213
ref_iterator operator++(int)
Definition iterators.hpp:145
ref_iterator begin() const
Definition iterators.hpp:242
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:257
ref_iterator & operator+=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:167
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:207
typename std::remove_pointer< typename decay_t< sections_t >::value_type >::type & reference
Definition iterators.hpp:56
ref_iterator cbegin() const
Definition iterators.hpp:246
bool empty() const
Definition iterators.hpp:273
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:265
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator[](size_t n)
Definition iterators.hpp:182
bool operator>(const ref_iterator &rhs) const
Definition iterators.hpp:228
bool operator>=(const ref_iterator &rhs) const
Definition iterators.hpp:233
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:250
std::enable_if< std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:287
std::enable_if<!std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:294
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:189
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:279
ref_iterator::difference_type operator-(const ref_iterator &rhs) const
Definition iterators.hpp:219
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:300
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:306
bool operator==(const ref_iterator &other) const
Definition iterators.hpp:261
decay_t< sections_t > DT
Definition iterators.hpp:60
@ T
Definition AcceleratorCodes.hpp:97
LIEF namespace.
Definition Abstract/Binary.hpp:40
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:593
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:1004
iterator_range< T > make_range(T &&x, T &&y)
Definition iterators.hpp:654
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterators.hpp:1033
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:320
pointer_iterator< pointee_iterator< WrappedIteratorT, T1 >, T2 > raw_pointer_iterator
Definition iterators.hpp:1043
An iterator type that allows iterating over the pointees via some other iterator.
Definition iterators.hpp:990
T & operator*() const
Definition iterators.hpp:996
pointee_iterator(U &&u)
Definition iterators.hpp:993