50 using iterator_category = std::bidirectional_iterator_tag;
51 using value_type = decay_t<U>;
52 using difference_type = ptrdiff_t;
53 using pointer =
typename std::remove_pointer<U>::type*;
54 using reference =
typename std::remove_pointer<U>::type&;
56 using container_type = T;
58 using DT = decay_t<T>;
59 using ref_t =
typename ref_iterator::reference;
60 using pointer_t =
typename ref_iterator::pointer;
63 container_{std::forward<T>(container)}
65 it_ = std::begin(container_);
69 container_{copy.container_},
70 it_{std::begin(container_)},
71 distance_{copy.distance_}
73 std::advance(it_, distance_);
83 std::swap(
const_cast<add_lvalue_reference_t<remove_const_t<DT>
>>(container_),
84 const_cast<add_lvalue_reference_t<remove_const_t<DT>
>>(other.container_));
85 std::swap(it_, other.it_);
86 std::swap(distance_, other.distance_);
103 if (it_ != std::begin(container_)) {
104 it_ = std::prev(it_);
117 ref_iterator& operator+=(
const typename ref_iterator::difference_type& movement) {
118 std::advance(it_, movement);
119 distance_ += movement;
124 ref_iterator& operator-=(
const typename ref_iterator::difference_type& movement) {
125 return (*
this) += -movement;
129 typename std::enable_if<!std::is_const<ref_t>::value, remove_const_t<ref_t>>::type
130 operator[](
size_t n) {
131 return const_cast<remove_const_t<ref_t>
>(
static_cast<const ref_iterator*
>(
this)->
operator[](n));
135 add_const_t<ref_t> operator[](
size_t n)
const {
136 assert(n < size() &&
"integrity error: out of bound");
140 typename ref_iterator::difference_type saved_dist = std::distance(std::begin(no_const_this->container_), no_const_this->it_);
141 no_const_this->it_ = std::begin(no_const_this->container_);
142 std::advance(no_const_this->it_, n);
144 auto&& v =
const_cast<add_const_t<ref_t>
>(no_const_this->operator*());
146 no_const_this->it_ = std::begin(no_const_this->container_);
147 std::advance(no_const_this->it_, saved_dist);
152 ref_iterator operator+(
typename ref_iterator::difference_type n)
const {
158 ref_iterator operator-(
typename ref_iterator::difference_type n)
const {
164 typename ref_iterator::difference_type operator-(
const ref_iterator& rhs)
const {
165 return distance_ - rhs.distance_;
169 return (rhs - *
this) > 0;
179 return !(*
this < rhs);
184 return !(*
this > rhs);
197 it.it_ = std::end(it.container_);
198 it.distance_ = it.size();
207 return (size() == other.size() && distance_ == other.distance_);
211 return !(*
this == other);
214 size_t size()
const {
215 return container_.size();
219 return container_.empty();
222 typename std::enable_if<!std::is_const<ref_t>::value, remove_const_t<ref_t>>::type
224 return const_cast<remove_const_t<ref_t>
>(
static_cast<const ref_iterator*
>(
this)->
operator*());
227 template<
typename V = DT_VAL>
228 typename std::enable_if<std::is_pointer<V>::value, add_const_t<ref_t>>::type
230 assert(*it_ &&
"integrity error: nullptr");
231 return const_cast<add_const_t<ref_t>
>(
static_cast<ref_t
>(**it_));
234 template<
typename V = DT_VAL>
235 typename std::enable_if<!std::is_pointer<V>::value, add_const_t<ref_t>>::type
237 return const_cast<add_const_t<ref_t>
>(*(it_));
241 typename std::enable_if<!std::is_const<pointer_t>::value, pointer_t>::type
243 return const_cast<remove_const_t<pointer_t>
>(
static_cast<const ref_iterator*
>(
this)->operator->());
246 add_const_t<pointer_t> operator->()
const {
247 return const_cast<add_const_t<pointer_t>
>(&(operator*()));
253 typename ref_iterator::difference_type distance_{};
268 using iterator_category = std::forward_iterator_tag;
269 using value_type = decay_t<U>;
270 using difference_type = ptrdiff_t;
271 using pointer =
typename std::remove_pointer<U>::type*;
272 using reference =
typename std::remove_pointer<U>::type&;
274 using container_type = T;
276 using DT = decay_t<T>;
277 using ref_t =
typename filter_iterator::reference;
278 using pointer_t =
typename filter_iterator::pointer;
279 using filter_t = std::function<bool (
const typename DT::value_type&)>;
282 container_{std::forward<T>(container)},
286 it_ = std::begin(container_);
288 filters_.push_back(filter),
289 it_ = std::begin(container_);
291 if (it_ != std::end(container_)) {
292 if (!std::all_of(std::begin(filters_), std::end(filters_), [
this] (
const filter_t& f) {
return f(*it_);})) {
299 container_{std::forward<T>(container)},
303 it_ = std::begin(container_);
305 if (it_ != std::end(container_)) {
306 if (!std::all_of(std::begin(filters_), std::end(filters_), [
this] (
const filter_t& f) {
return f(*it_);})) {
313 container_{std::forward<T>(container)},
316 it_ = std::begin(container_);
320 container_{copy.container_},
321 it_{std::begin(container_)},
322 filters_{copy.filters_},
323 distance_{copy.distance_}
325 std::advance(it_, distance_);
334 std::swap(
const_cast<remove_const_t<DT>&
>(container_),
const_cast<remove_const_t<DT>&
>(other.container_));
335 std::swap(it_, other.it_);
336 std::swap(filters_, other.filters_);
337 std::swap(size_c_, other.size_c_);
338 std::swap(distance_, other.distance_);
343 filters_.push_back(func);
360 return {container_, filters_};
371 it_end.it_ = it_end.container_.end();
372 it_end.distance_ = it_end.container_.size();
381 typename std::enable_if<!std::is_const<ref_t>::value, remove_const_t<ref_t>>::type
383 return const_cast<remove_const_t<ref_t>
>(
static_cast<const filter_iterator*
>(
this)->
operator*());
386 template<
typename V = DT_VAL>
387 typename std::enable_if<std::is_pointer<V>::value, add_const_t<ref_t>>::type
389 assert(*it_ &&
"integrity error: nullptr");
390 return const_cast<add_const_t<ref_t>
>(
static_cast<ref_t
>(**it_));
393 template<
typename V = DT_VAL>
394 typename std::enable_if<!std::is_pointer<V>::value, add_const_t<ref_t>>::type
396 return const_cast<add_const_t<ref_t>
>(*(it_));
400 typename std::enable_if<!std::is_const<ref_t>::value, remove_const_t<ref_t>>::type
401 operator[](
size_t n) {
402 return const_cast<remove_const_t<ref_t>
>(
static_cast<const filter_iterator*
>(
this)->
operator[](n));
405 add_const_t<ref_t> operator[](
size_t n)
const {
406 assert(n < size() &&
"integrity error: out of bound");
410 return const_cast<add_const_t<ref_t>
>(*it);
414 typename std::enable_if<!std::is_const<pointer_t>::value, pointer_t>::type
416 return const_cast<remove_const_t<pointer_t>
>(
static_cast<const filter_iterator*
>(
this)->operator->());
419 add_const_t<pointer_t> operator->()
const {
420 return const_cast<add_const_t<pointer_t>
>(&(operator*()));
423 size_t size()
const {
424 if (filters_.empty()) {
425 return container_.size();
434 auto end_iter = std::end(it);
435 for (; it != end_iter; ++it) ++size;
447 return (container_.size() == other.container_.size() && distance_ == other.distance_);
451 return !(*
this == other);
456 if (it_ == std::end(container_)) {
457 distance_ = container_.size();
462 it_ = std::next(it_);
464 }
while(it_ != std::end(container_) &&
465 !std::all_of(std::begin(filters_), std::end(filters_),
466 [
this] (
const filter_t& f) {
return f(*it_); }));
471 mutable size_t size_c_ = 0;
474 std::vector<filter_t> filters_;
475 typename filter_iterator::difference_type distance_ = 0;