-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfilter_iterator.h
More file actions
67 lines (59 loc) · 1.77 KB
/
Copy pathfilter_iterator.h
File metadata and controls
67 lines (59 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#pragma once
#include <iterator>
namespace lambda {
template <typename Iter, typename Iter2, typename Pred>
class filter_iterator : std::iterator<std::input_iterator_tag, std::remove_reference_t<decltype(*std::declval<Iter>())>>
{
using ValueType = std::remove_const_t<std::remove_reference_t<decltype(*std::declval<Iter>())>>;
public:
template <typename _Iter, typename _Iter2, typename _Func>
filter_iterator(_Iter&& iter, _Iter2&& end, _Func&& func,
std::enable_if_t<std::is_convertible<Iter, _Iter>::value && std::is_convertible<Pred, _Func>::value && std::is_convertible<Iter2, _Iter2>::value>* = 0) :
m_iterator(std::forward<_Iter>(iter)),
m_end(end),
m_pred(std::forward<_Func>(func))
{
if (m_iterator != end) {
while (!m_pred(m_current_value = *m_iterator))
{
if (++m_iterator == m_end)
break;
}
}
}
ValueType & operator*()
{
return m_current_value;
}
const ValueType & operator*() const
{
return m_current_value;
}
filter_iterator & operator++()
{
do {
if (++m_iterator == m_end)
break;
} while (!m_pred(m_current_value = *m_iterator));
return *this;
}
bool operator==(const filter_iterator & other) const
{
return m_iterator == other.m_iterator;
}
bool operator!=(const filter_iterator & other) const
{
return m_iterator != other.m_iterator;
}
private:
Iter m_iterator;
Iter2 m_end;
mutable Pred m_pred; // the predicate can change everytime we use it
ValueType m_current_value;
};
template <typename Iter, typename Iter2, typename Pred>
filter_iterator<Iter, Iter2, Pred> make_filter_iterator(Iter&& iter, Iter2&& end, Pred&& func)
{
return filter_iterator<Iter, Iter2, Pred>(std::forward<Iter>(iter), std::forward<Iter2>(end), std::forward<Pred>(func));
}
}