Ultra 0.9.4
Loading...
Searching...
No Matches
layered_population_iterator.tcc
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_LAYERED_POPULATION_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(ULTRA_LAYERED_POPULATION_ITERATOR_TCC)
18#define ULTRA_LAYERED_POPULATION_ITERATOR_TCC
19
23template<Individual I>
24template<bool is_const>
25class layered_population<I>::base_iterator
26{
27public:
28 using iterator_category = std::forward_iterator_tag;
29 using value_type = I;
30 using pointer = value_type *;
31 using const_pointer = const value_type *;
32 using reference = value_type &;
33 using const_reference = const value_type &;
34 using difference_type = std::ptrdiff_t;
35
36 using ptr = std::conditional_t<is_const, const_pointer, pointer>;
37 using ref = std::conditional_t<is_const, const_reference, reference>;
38 using pop = std::conditional_t<is_const,
39 const layered_population, layered_population>;
40 using itr = std::conditional_t<is_const,
41 typename pop::layer_const_iter,
42 typename pop::layer_iter>;
43
44 // A requirement for `std::input_iterator` is that it must be
45 // default-initializable.
46 base_iterator() noexcept = default;
47
50 base_iterator(pop &p, bool begin) noexcept
51 {
52 const auto layers(p.range_of_layers());
53
54 end_ = layers.end();
55 layer_ = begin ? layers.begin() : end_;
56 pos_.layer_index = begin ? 0 : p.layers();
57
58 if (begin)
59 skip_empty_layers();
60 }
61
66 base_iterator &operator++() noexcept
67 {
68 Expects(layer_ != end_);
69
70 if (++pos_.individual_coord >= layer_->size())
71 {
72 ++layer_;
73 ++pos_.layer_index;
74 pos_.individual_coord = 0;
75
76 skip_empty_layers();
77 }
78
79 assert((layer_ != end_ && pos_.individual_coord < layer_->size())
80 || (layer_ == end_ && pos_.individual_coord == 0));
81
82 return *this;
83 }
84
87 base_iterator operator++(int) noexcept
88 {
89 base_iterator tmp(*this);
90 operator++();
91 return tmp;
92 }
93
102 [[nodiscard]] bool operator==(const base_iterator &other) const noexcept
103 {
104 return layer_ == other.layer_
105 && pos_.individual_coord == other.pos_.individual_coord;
106 }
107
108 [[nodiscard]] std::size_t uid() const noexcept
109 {
110 Expects(layer_ != end_);
111 return layer_->uid();
112 }
113
114 [[nodiscard]] typename layered_population<I>::coord coord() const noexcept
115 {
116 Expects(layer_ != end_);
117 Expects(pos_.individual_coord < layer_->size());
118 return pos_;
119 }
120
122 [[nodiscard]] ref operator*() const noexcept
123 {
124 Expects(layer_ != end_);
125 Expects(pos_.individual_coord < layer_->size());
126 return (*layer_)[pos_.individual_coord];
127 }
128
130 [[nodiscard]] ptr operator->() const noexcept
131 {
132 return &operator*();
133 }
134
135 friend std::ostream &operator<<(std::ostream &out, const base_iterator &i)
136 {
137 out << '[' << i.pos_.layer_index << ',' << i.pos_.individual_coord << ']';
138 return out;
139 }
140
141private:
142 void skip_empty_layers() noexcept
143 {
144 while (layer_ != end_ && layer_->empty())
145 {
146 ++layer_;
147 ++pos_.layer_index;
148 }
149 }
150
151 itr end_ {};
152 itr layer_ {};
153 layered_population<I>::coord pos_ {0, 0};
154};
155
156#endif // include guard
Definition layered_population_iterator.tcc:26
ref operator*() const noexcept
Definition layered_population_iterator.tcc:122
base_iterator operator++(int) noexcept
Definition layered_population_iterator.tcc:87
base_iterator & operator++() noexcept
Definition layered_population_iterator.tcc:66
base_iterator(pop &p, bool begin) noexcept
Definition layered_population_iterator.tcc:50
ptr operator->() const noexcept
Definition layered_population_iterator.tcc:130
bool operator==(const base_iterator &other) const noexcept
Definition layered_population_iterator.tcc:102
Definition layered_population_coord.tcc:25