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