17#ifndef LIEF_ITERATORS_H
18#define LIEF_ITERATORS_H
30using decay_t =
typename std::decay<T>::type;
43template<class T, typename U = typename decay_t<T>::value_type,
50 using pointer =
typename std::remove_pointer<U>::type*;
51 using reference =
typename std::remove_pointer<U>::type&;
60 container_{std::forward<T>(other.container_)},
61 it_{std::begin(container_)},
62 distance_{other.distance_} {
63 std::advance(it_, distance_);
70 container_ = std::forward<T>(other.container_);
71 it_ = std::begin(other.container_);
72 distance_ = other.distance_;
73 std::advance(it_, distance_);
80 container_{std::forward<T>(container)},
81 it_(std::
begin(container_)) {}
84 container_{copy.container_},
85 it_{std::
begin(container_)},
86 distance_{copy.distance_} {
87 std::advance(it_, distance_);
100 std::swap(it_, other.it_);
101 std::swap(distance_, other.distance_);
106 it_ = std::next(it_);
118 if (it_ != std::begin(container_)) {
119 it_ = std::prev(it_);
134 std::advance(it_, movement);
135 distance_ += movement;
142 return (*
this) += -movement;
146 typename std::enable_if<!std::is_const<ref_t>::value,
156 assert(n <
size() &&
"integrity error: out of bound");
161 std::distance(std::begin(no_const_this->container_), no_const_this->it_);
162 no_const_this->it_ = std::begin(no_const_this->container_);
163 std::advance(no_const_this->it_, n);
167 no_const_this->it_ = std::begin(no_const_this->container_);
168 std::advance(no_const_this->it_, saved_dist);
186 return distance_ - rhs.distance_;
190 return (rhs - *
this) > 0;
200 return !(*
this < rhs);
205 return !(*
this > rhs);
218 it.it_ = std::end(it.container_);
219 it.distance_ = it.
size();
228 return (
size() == other.
size() && distance_ == other.distance_);
232 return !(*
this == other);
236 return container_.size();
240 return container_.empty();
243 typename std::enable_if<!std::is_const<ref_t>::value,
251 template<
typename V = DT_VAL>
254 assert(*it_ &&
"integrity error: nullptr");
258 template<
typename V = DT_VAL>
265 typename std::enable_if<!std::is_const<pointer_t>::value,
pointer_t>::type
284template<class T, typename U = typename decay_t<T>::value_type,
285 class CT =
typename std::add_const<T>::type>
291template<class T, typename U = typename decay_t<T>::value_type,
299 using pointer =
typename std::remove_pointer<U>::type*;
300 using reference =
typename std::remove_pointer<U>::type&;
307 using filter_t = std::function<bool(
const typename DT::value_type&)>;
310 size_c_(other.size_c_),
311 size_cached_(other.size_cached_),
312 container_(std::forward<T>(other.container_)),
313 it_(std::begin(container_)),
314 filters_{std::move(other.filters_)},
315 distance_(other.distance_) {
316 std::advance(it_, distance_);
320 if (
this == &other) {
324 size_c_ = other.size_c_;
325 size_cached_ = other.size_cached_;
326 container_ = std::forward<T>(other.container_);
327 it_ = std::begin(container_);
328 filters_ = std::move(other.filters_);
329 distance_ = other.distance_;
331 std::advance(it_, distance_);
339 container_{std::forward<T>(container)},
340 it_(std::
begin(container_)),
344 filters_.push_back(filter);
346 if (it_ != std::end(container_)) {
347 if (!std::all_of(std::begin(filters_), std::end(filters_),
348 [
this](
const filter_t& f) {
return f(*it_); }))
356 container_{std::forward<T>(container)},
357 it_(std::
begin(container_)),
361 if (it_ != std::end(container_)) {
362 if (!std::all_of(std::begin(filters_), std::end(filters_),
363 [
this](
const filter_t& f) {
return f(*it_); }))
371 container_{std::forward<T>(container)},
372 it_(std::
begin(container_)),
376 container_{copy.container_},
377 it_{std::
begin(container_)},
378 filters_{copy.filters_},
379 distance_{copy.distance_} {
380 std::advance(it_, distance_);
391 std::swap(it_, other.it_);
392 std::swap(filters_, other.filters_);
393 std::swap(size_c_, other.size_c_);
394 std::swap(size_cached_, other.size_cached_);
395 std::swap(distance_, other.distance_);
400 filters_.push_back(func);
402 size_cached_ =
false;
418 return {container_, filters_};
429 it_end.it_ = it_end.container_.end();
430 it_end.distance_ = it_end.container_.size();
439 typename std::enable_if<!std::is_const<ref_t>::value,
447 template<
typename V = DT_VAL>
450 assert(*it_ &&
"integrity error: nullptr");
454 template<
typename V = DT_VAL>
461 typename std::enable_if<!std::is_const<ref_t>::value,
470 assert(n <
size() &&
"integrity error: out of bound");
478 typename std::enable_if<!std::is_const<pointer_t>::value,
pointer_t>::type
490 if (filters_.empty()) {
491 return container_.size();
500 auto end_iter = it.
end();
501 for (; it != end_iter; ++it) {
511 if (filters_.empty()) {
512 return container_.empty();
524 return (container_.size() == other.container_.size() &&
525 distance_ == other.distance_);
529 return !(*
this == other);
534 if (it_ == std::end(container_)) {
535 distance_ = container_.size();
540 it_ = std::next(it_);
542 }
while (it_ != std::end(container_) &&
543 !std::all_of(std::begin(filters_), std::end(filters_),
544 [
this](
const filter_t& f) {
return f(*it_); }));
548 mutable size_t size_c_ = 0;
549 mutable bool size_cached_ =
false;
552 std::vector<filter_t> filters_;
557template<class T, typename U = typename decay_t<T>::value_type,
558 class CT =
typename std::add_const<T>::type>
566template<
typename IteratorT>
574 begin_(std::forward<T>(it_begin)),
575 end_(std::forward<T>(it_end)) {}
584 return begin_ == end_;
587 typename IteratorDecayTy::value_type
588 at(
typename IteratorDecayTy::difference_type pos)
const {
589 static_assert(IsRandomAccess,
"at() needs random access iterator");
591 std::advance(it, pos);
595 typename IteratorDecayTy::value_type
596 operator[](
typename IteratorDecayTy::difference_type pos)
const {
601 return std::distance(begin_, end_);
607 std::is_base_of<std::random_access_iterator_tag,
608 typename IteratorDecayTy::iterator_category>::value,
610 std::is_base_of<std::bidirectional_iterator_tag,
611 typename IteratorDecayTy::iterator_category>::value,
682template<
typename DerivedT,
typename IteratorCategoryT,
typename T,
683 typename DifferenceTypeT = std::ptrdiff_t,
typename PointerT = T*,
684 typename ReferenceT = T&>
696 std::is_base_of<std::random_access_iterator_tag, IteratorCategoryT>::value,
698 std::is_base_of<std::bidirectional_iterator_tag, IteratorCategoryT>::value,
706 class ReferenceProxy {
711 ReferenceProxy(DerivedT I) :
715 operator ReferenceT()
const {
725 friend iterator_facade_base;
729 template<
typename RefT>
730 PointerProxy(RefT&& R) :
731 R(std::forward<RefT>(R)) {}
741 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
742 "Must pass the derived type to this template!");
743 static_assert(IsRandomAccess,
744 "The '+' operator is only defined for random access iterators.");
745 DerivedT tmp = *
static_cast<const DerivedT*
>(
this);
749 friend DerivedT
operator+(DifferenceTypeT n,
const DerivedT& i) {
750 static_assert(IsRandomAccess,
751 "The '+' operator is only defined for random access iterators.");
755 static_assert(IsRandomAccess,
756 "The '-' operator is only defined for random access iterators.");
757 DerivedT tmp = *
static_cast<const DerivedT*
>(
this);
763 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
764 "Must pass the derived type to this template!");
765 return static_cast<DerivedT*
>(
this)->
operator+=(1);
768 DerivedT tmp = *
static_cast<DerivedT*
>(
this);
769 ++*
static_cast<DerivedT*
>(
this);
775 "The decrement operator is only defined for bidirectional iterators."
777 return static_cast<DerivedT*
>(
this)->
operator-=(1);
782 "The decrement operator is only defined for bidirectional iterators."
784 DerivedT tmp = *
static_cast<DerivedT*
>(
this);
785 --*
static_cast<DerivedT*
>(
this);
789#ifndef __cpp_impl_three_way_comparison
791 return !(
static_cast<const DerivedT&
>(*this) == RHS);
798 "Relational operators are only defined for random access iterators."
800 return !(
static_cast<const DerivedT&
>(*this) < RHS) &&
801 !(
static_cast<const DerivedT&
>(*
this) == RHS);
806 "Relational operators are only defined for random access iterators."
808 return !(
static_cast<const DerivedT&
>(*this) > RHS);
813 "Relational operators are only defined for random access iterators."
815 return !(
static_cast<const DerivedT&
>(*this) < RHS);
819 return static_cast<const DerivedT*
>(
this)->
operator*();
822 static_assert(IsRandomAccess,
823 "Subscripting is only defined for random access iterators.");
824 return static_cast<const DerivedT*
>(
this)->
operator+(n);
833template<
typename DerivedT,
typename WrappedIteratorT,
834 typename IteratorCategoryT =
835 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
836 typename T =
typename std::iterator_traits<WrappedIteratorT>::value_type,
837 typename DifferenceTypeT =
838 typename std::iterator_traits<WrappedIteratorT>::difference_type,
839 typename PointerT =
typename std::conditional<
840 std::is_same<T, typename std::iterator_traits<WrappedIteratorT>::
842 typename std::iterator_traits<WrappedIteratorT>::pointer, T*
844 typename ReferenceT =
typename std::conditional<
845 std::is_same<T, typename std::iterator_traits<WrappedIteratorT>::
847 typename std::iterator_traits<WrappedIteratorT>::reference, T&
849class iterator_adaptor_base
851 PointerT, ReferenceT> {
852 using BaseT =
typename iterator_adaptor_base::iterator_facade_base;
857 iterator_adaptor_base() =
default;
859 explicit iterator_adaptor_base(WrappedIteratorT u) :
861 static_assert(std::is_base_of<iterator_adaptor_base, DerivedT>::value,
862 "Must pass the derived type to this template!");
865 const WrappedIteratorT& wrapped()
const {
874 BaseT::IsRandomAccess,
875 "The '+=' operator is only defined for random access iterators."
878 return *
static_cast<DerivedT*
>(
this);
882 BaseT::IsRandomAccess,
883 "The '-=' operator is only defined for random access iterators."
886 return *
static_cast<DerivedT*
>(
this);
888 using BaseT::operator-;
890 static_assert(BaseT::IsRandomAccess,
891 "The '-' operator is only defined for random access iterators.");
897 using BaseT::operator++;
900 return *
static_cast<DerivedT*
>(
this);
902 using BaseT::operator--;
905 BaseT::IsBidirectional,
906 "The decrement operator is only defined for bidirectional iterators."
909 return *
static_cast<DerivedT*
>(
this);
913 const iterator_adaptor_base& RHS) {
914 return LHS.I == RHS.I;
917 const iterator_adaptor_base& RHS) {
919 BaseT::IsRandomAccess,
920 "Relational operators are only defined for random access iterators."
922 return LHS.I < RHS.I;
939template<
typename WrappedIteratorT,
940 typename T =
typename std::
941 remove_reference<decltype(**std::declval<WrappedIteratorT>())>::type>
943 : iterator_adaptor_base<
957template<
typename RangeT,
958 typename WrappedIteratorT =
decltype(std::begin(std::declval<RangeT>()))>
959iterator_range<pointee_iterator<WrappedIteratorT>>
962 return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
963 PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
966template<
typename WrappedIteratorT,
967 typename T =
decltype(&*std::declval<WrappedIteratorT>())>
969 : public iterator_adaptor_base<
982 return Ptr = &*this->I;
986template<
typename RangeT,
987 typename WrappedIteratorT =
decltype(std::begin(std::declval<RangeT>()))>
988iterator_range<pointer_iterator<WrappedIteratorT>>
991 return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
992 PointerIteratorT(std::end(std::forward<RangeT>(Range))));
995template<
typename WrappedIteratorT,
996 typename T1 =
typename std::
997 remove_reference<decltype(**std::declval<WrappedIteratorT>())>::type,
998 typename T2 =
typename std::add_pointer<T1>::type>
Iterator which returns a ref on container's values given predicates.
Definition iterators.hpp:293
std::enable_if<!std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:456
bool operator==(const filter_iterator &other) const
Definition iterators.hpp:523
filter_iterator(const filter_iterator ©)
Definition iterators.hpp:375
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:469
filter_iterator cend() const
Definition iterators.hpp:435
typename std::remove_pointer< Symbol * >::type * pointer
Definition iterators.hpp:299
filter_iterator(T container, filter_t filter)
Definition iterators.hpp:338
std::forward_iterator_tag iterator_category
Definition iterators.hpp:296
filter_iterator(T container)
Definition iterators.hpp:370
void swap(filter_iterator &other) noexcept
Definition iterators.hpp:388
filter_iterator & operator++()
Definition iterators.hpp:406
std::enable_if<!std::is_const< pointer_t >::value, pointer_t >::type operator->()
Definition iterators.hpp:479
filter_iterator(T container, const std::vector< filter_t > &filters)
Definition iterators.hpp:355
filter_iterator end() const
Definition iterators.hpp:425
typename filter_iterator::pointer pointer_t
Definition iterators.hpp:306
filter_iterator & operator=(filter_iterator other)
Definition iterators.hpp:383
decay_t< Symbol * > value_type
Definition iterators.hpp:297
typename filter_iterator::reference ref_t
Definition iterators.hpp:305
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator*()
Definition iterators.hpp:441
filter_iterator begin() const
Definition iterators.hpp:417
bool empty() const
Definition iterators.hpp:510
Symbol * DT_VAL
Definition iterators.hpp:303
ptrdiff_t difference_type
Definition iterators.hpp:298
~filter_iterator()=default
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:485
size_t size() const
Definition iterators.hpp:489
std::enable_if< std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:449
bool operator!=(const filter_iterator &other) const
Definition iterators.hpp:528
std::function< bool(const typename DT::value_type &)> filter_t
Definition iterators.hpp:307
filter_iterator(filter_iterator &&other) noexcept
Definition iterators.hpp:309
symbols_t & container_type
Definition iterators.hpp:302
filter_iterator operator++(int)
Definition iterators.hpp:411
decay_t< symbols_t & > DT
Definition iterators.hpp:304
filter_iterator cbegin() const
Definition iterators.hpp:421
filter_iterator & def(filter_t func)
Definition iterators.hpp:399
typename std::remove_pointer< Symbol * >::type & reference
Definition iterators.hpp:300
filter_iterator & operator=(filter_iterator &&other) noexcept
Definition iterators.hpp:319
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator[](size_t n)
Definition iterators.hpp:463
DerivedT & operator++()
Definition iterators.hpp:898
DerivedT & operator--()
Definition iterators.hpp:903
DerivedT & operator-=(difference_type n)
Definition iterators.hpp:880
ReferenceT operator*() const
Definition iterators.hpp:925
friend bool operator<(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:916
friend bool operator==(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
Definition iterators.hpp:912
DifferenceTypeT difference_type
Definition iterators.hpp:870
DerivedT & operator+=(difference_type n)
Definition iterators.hpp:872
difference_type operator-(const DerivedT &RHS) const
Definition iterators.hpp:889
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterators.hpp:685
DifferenceTypeT difference_type
Definition iterators.hpp:689
PointerProxy operator->() const
Definition iterators.hpp:818
DerivedT & operator--()
Definition iterators.hpp:772
DerivedT operator++(int)
Definition iterators.hpp:767
T value_type
Definition iterators.hpp:688
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
Definition iterators.hpp:749
bool operator>(const DerivedT &RHS) const
Definition iterators.hpp:795
ReferenceProxy operator[](DifferenceTypeT n) const
Definition iterators.hpp:821
ReferenceT reference
Definition iterators.hpp:691
bool operator>=(const DerivedT &RHS) const
Definition iterators.hpp:810
DerivedT operator-(DifferenceTypeT n) const
Definition iterators.hpp:754
DerivedT & operator++()
Definition iterators.hpp:762
PointerT pointer
Definition iterators.hpp:690
DerivedT operator--(int)
Definition iterators.hpp:779
IteratorCategoryT iterator_category
Definition iterators.hpp:687
DerivedT operator+(DifferenceTypeT n) const
Definition iterators.hpp:740
bool operator!=(const DerivedT &RHS) const
Definition iterators.hpp:790
bool operator<=(const DerivedT &RHS) const
Definition iterators.hpp:803
Definition iterators.hpp:567
IteratorT begin() const
Definition iterators.hpp:577
iterator_range(T &&it_begin, T &&it_end)
Definition iterators.hpp:573
IteratorT end() const
Definition iterators.hpp:580
bool empty() const
Definition iterators.hpp:583
IteratorDecayTy::value_type at(typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:588
assembly::Instruction::Iterator IteratorTy
Definition iterators.hpp:569
IteratorDecayTy::value_type operator[](typename IteratorDecayTy::difference_type pos) const
Definition iterators.hpp:596
std::ptrdiff_t size() const
Definition iterators.hpp:600
typename std::decay< assembly::Instruction::Iterator >::type IteratorDecayTy
Definition iterators.hpp:570
Definition iterators.hpp:972
pointer_iterator()=default
T & operator*() const
Definition iterators.hpp:981
pointer_iterator(WrappedIteratorT u)
Definition iterators.hpp:978
Iterator which returns reference on container's values.
Definition iterators.hpp:45
bool operator<=(const ref_iterator &rhs) const
Definition iterators.hpp:204
ref_iterator & operator--()
Definition iterators.hpp:117
size_t size() const
Definition iterators.hpp:235
ref_iterator & operator++()
Definition iterators.hpp:105
void swap(ref_iterator &other) noexcept
Definition iterators.hpp:95
bool operator<(const ref_iterator &rhs) const
Definition iterators.hpp:189
ref_iterator operator-(typename ref_iterator::difference_type n) const
Definition iterators.hpp:179
ref_iterator operator++(int)
Definition iterators.hpp:111
ref_iterator begin() const
Definition iterators.hpp:208
sections_t container_type
Definition iterators.hpp:53
typename ref_iterator::reference ref_t
Definition iterators.hpp:56
ref_iterator operator--(int)
Definition iterators.hpp:125
ref_iterator cend() const
Definition iterators.hpp:223
ref_iterator & operator+=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:133
std::bidirectional_iterator_tag iterator_category
Definition iterators.hpp:47
ref_iterator(ref_iterator &&other) noexcept
Definition iterators.hpp:59
ptrdiff_t difference_type
Definition iterators.hpp:49
ref_iterator operator+(typename ref_iterator::difference_type n) const
Definition iterators.hpp:173
typename std::remove_pointer< typename decay_t< sections_t >::value_type >::type & reference
Definition iterators.hpp:51
ref_iterator cbegin() const
Definition iterators.hpp:212
bool empty() const
Definition iterators.hpp:239
ref_iterator & operator=(ref_iterator other)
Definition iterators.hpp:90
typename std::remove_pointer< typename decay_t< sections_t >::value_type >::type * pointer
Definition iterators.hpp:50
ref_iterator & operator=(ref_iterator &&other) noexcept
Definition iterators.hpp:66
bool operator!=(const ref_iterator &other) const
Definition iterators.hpp:231
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator[](size_t n)
Definition iterators.hpp:148
bool operator>(const ref_iterator &rhs) const
Definition iterators.hpp:194
bool operator>=(const ref_iterator &rhs) const
Definition iterators.hpp:199
ref_iterator(const ref_iterator ©)
Definition iterators.hpp:83
ref_iterator end() const
Definition iterators.hpp:216
std::enable_if< std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:253
std::enable_if<!std::is_pointer< V >::value, add_const_t< ref_t > >::type operator*() const
Definition iterators.hpp:260
ref_iterator & operator-=(const typename ref_iterator::difference_type &movement)
Definition iterators.hpp:141
add_const_t< ref_t > operator[](size_t n) const
Definition iterators.hpp:155
decay_t< typename decay_t< sections_t >::value_type > value_type
Definition iterators.hpp:48
std::enable_if<!std::is_const< ref_t >::value, remove_const_t< ref_t > >::type operator*()
Definition iterators.hpp:245
ref_iterator::difference_type operator-(const ref_iterator &rhs) const
Definition iterators.hpp:185
typename decay_t< sections_t >::value_type DT_VAL
Definition iterators.hpp:54
typename ref_iterator::pointer pointer_t
Definition iterators.hpp:57
ref_iterator(T container)
Definition iterators.hpp:79
std::enable_if<!std::is_const< pointer_t >::value, pointer_t >::type operator->()
Definition iterators.hpp:266
add_const_t< pointer_t > operator->() const
Definition iterators.hpp:272
bool operator==(const ref_iterator &other) const
Definition iterators.hpp:227
decay_t< sections_t > DT
Definition iterators.hpp:55
@ 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:559
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:960
iterator_range< T > make_range(T &&x, T &&y)
Definition iterators.hpp:620
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterators.hpp:989
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:286
pointer_iterator< pointee_iterator< WrappedIteratorT, T1 >, T2 > raw_pointer_iterator
Definition iterators.hpp:999
An iterator type that allows iterating over the pointees via some other iterator.
Definition iterators.hpp:946
pointee_iterator()=default
T & operator*() const
Definition iterators.hpp:952
pointee_iterator(U &&u)
Definition iterators.hpp:949