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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#pragma once
#include "concepts/container.h"
#include <util/system/yassert.h>
#include <iterator>
namespace NFlatHash {
template <class Container, class T>
class TIterator {
private:
static_assert(NConcepts::ContainerV<std::decay_t<Container>>);
public:
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = typename std::add_pointer<T>::type;
using reference = typename std::add_lvalue_reference<T>::type;
private:
using size_type = typename Container::size_type;
public:
TIterator(Container* cont)
: Cont_(cont)
, Idx_(0)
{
if (!cont->IsTaken(Idx_)) {
Next();
}
}
TIterator(Container* cont, size_type idx)
: Cont_(cont)
, Idx_(idx) {}
template <class C, class U, class = std::enable_if_t<std::is_convertible<C*, Container*>::value &&
std::is_convertible<U, T>::value>>
TIterator(const TIterator<C, U>& rhs)
: Cont_(rhs.Cont_)
, Idx_(rhs.Idx_) {}
TIterator(const TIterator&) = default;
TIterator& operator=(const TIterator&) = default;
TIterator& operator++() {
Next();
return *this;
}
TIterator operator++(int) {
auto idx = Idx_;
Next();
return { Cont_, idx };
}
reference operator*() {
return Cont_->Node(Idx_);
}
pointer operator->() {
return &Cont_->Node(Idx_);
}
const pointer operator->() const {
return &Cont_->Node(Idx_);
}
bool operator==(const TIterator& rhs) const noexcept {
Y_ASSERT(Cont_ == rhs.Cont_);
return Idx_ == rhs.Idx_;
}
bool operator!=(const TIterator& rhs) const noexcept {
return !operator==(rhs);
}
private:
void Next() {
// Container provider ensures that it's not empty.
do {
++Idx_;
} while (Idx_ != Cont_->Size() && !Cont_->IsTaken(Idx_));
}
private:
template <class C, class U>
friend class TIterator;
Container* Cont_ = nullptr;
protected:
size_type Idx_ = 0;
};
} // namespace NFlatHash
|