Skip to content

Commit ef80b20

Browse files
committed
let iterator facade use only public functions; declare compound and difference operators in derived iterator implementation
Signed-off-by: Martijn Govers <[email protected]>
1 parent d0690b5 commit ef80b20

File tree

5 files changed

+73
-69
lines changed

5 files changed

+73
-69
lines changed

power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ class ColumnarAttributeRange : public std::ranges::view_interface<ColumnarAttrib
118118
};
119119

120120
class iterator : public IteratorFacade {
121-
friend class IteratorFacade;
122-
123121
public:
124122
using value_type = std::conditional_t<is_data_mutable_v<dataset_type>, Proxy, Proxy const>;
125123
using difference_type = Idx;
@@ -139,15 +137,19 @@ class ColumnarAttributeRange : public std::ranges::view_interface<ColumnarAttrib
139137
return first.current_idx() <=> second.current_idx();
140138
}
141139

140+
constexpr auto operator+=(difference_type n) -> std::add_lvalue_reference_t<iterator> {
141+
current_idx() += n;
142+
return *this;
143+
}
144+
145+
friend constexpr auto operator-(iterator const& first, iterator const& second) -> difference_type {
146+
return first.current_idx() - second.current_idx();
147+
}
148+
142149
private:
143150
constexpr auto current_idx() const { return current_.idx_; }
144151
constexpr auto& current_idx() { return current_.idx_; }
145152

146-
constexpr auto distance_to(iterator const& other) const -> difference_type {
147-
return other.current_idx() - current_idx();
148-
}
149-
constexpr void advance(difference_type n) { current_idx() += n; }
150-
151153
Proxy current_;
152154
};
153155

power_grid_model_c/power_grid_model/include/power_grid_model/common/grouped_index_vector.hpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ constexpr auto from_dense = from_dense_t{};
9595
class SparseGroupedIdxVector {
9696
private:
9797
class GroupIterator : public IteratorFacade {
98-
friend class IteratorFacade;
99-
10098
public:
10199
using iterator = GroupIterator;
102100
using const_iterator = std::add_const_t<GroupIterator>;
@@ -125,19 +123,23 @@ class SparseGroupedIdxVector {
125123
return first.group_ <=> second.group_;
126124
}
127125

126+
constexpr auto operator+=(difference_type n) -> std::add_lvalue_reference_t<GroupIterator> {
127+
group_ += n;
128+
return *this;
129+
}
130+
131+
friend auto operator-(GroupIterator const& first, GroupIterator const& second) -> difference_type {
132+
assert(first.indptr_ == second.indptr_);
133+
return first.group_ - second.group_;
134+
}
135+
128136
private:
129137
IdxVector const* indptr_{};
130138
Idx group_{};
131139
mutable std::remove_const_t<value_type>
132140
latest_value_{}; // making this mutable allows us to delay out-of-bounds checks until
133141
// dereferencing instead of update methods. Note that the value will be
134142
// invalidated at first update
135-
136-
constexpr auto distance_to(GroupIterator const& other) const -> difference_type {
137-
assert(indptr_ == other.indptr_);
138-
return other.group_ - group_;
139-
}
140-
constexpr void advance(Idx n) { group_ += n; }
141143
};
142144

143145
constexpr auto group_iterator(Idx group) const { return GroupIterator{indptr_, group}; }
@@ -175,8 +177,6 @@ class SparseGroupedIdxVector {
175177
class DenseGroupedIdxVector {
176178
private:
177179
class GroupIterator : public IteratorFacade {
178-
friend class IteratorFacade;
179-
180180
public:
181181
using iterator = GroupIterator;
182182
using const_iterator = std::add_const_t<GroupIterator>;
@@ -208,6 +208,15 @@ class DenseGroupedIdxVector {
208208
return first.group_ <=> second.group_;
209209
}
210210

211+
constexpr auto operator+=(difference_type n) -> std::add_lvalue_reference_t<GroupIterator> {
212+
advance(n);
213+
return *this;
214+
}
215+
friend auto operator-(GroupIterator const& first, GroupIterator const& second) -> difference_type {
216+
assert(first.dense_vector_ == second.dense_vector_);
217+
return first.group_ - second.group_;
218+
}
219+
211220
private:
212221
using group_iterator = IdxVector::const_iterator;
213222

@@ -219,10 +228,6 @@ class DenseGroupedIdxVector {
219228
// dereferencing instead of update methods. Note that the value will be
220229
// invalidated at first update
221230

222-
constexpr auto distance_to(GroupIterator const& other) const -> difference_type {
223-
return other.group_ - group_;
224-
}
225-
226231
constexpr void increment() {
227232
++group_;
228233
group_range_ = {group_range_.end(), std::find_if(group_range_.end(), std::cend(*dense_vector_),
@@ -235,7 +240,7 @@ class DenseGroupedIdxVector {
235240
.base(),
236241
group_range_.begin()};
237242
}
238-
constexpr void advance(Idx n) {
243+
constexpr void advance(difference_type n) {
239244
auto const start = n > 0 ? group_range_.end() : std::cbegin(*dense_vector_);
240245
auto const stop = n < 0 ? group_range_.begin() : std::cend(*dense_vector_);
241246

power_grid_model_c/power_grid_model/include/power_grid_model/common/iterator_facade.hpp

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,22 @@
1313
namespace power_grid_model {
1414
namespace detail {
1515
template <typename T>
16-
concept iterator_facadeable_c =
17-
std::integral<typename T::difference_type> && std::is_pointer_v<typename T::pointer> &&
18-
std::is_lvalue_reference_v<typename T::reference> &&
19-
requires(T t, std::add_const_t<T> ct, std::add_const_t<T> ct2, typename T::difference_type d) {
20-
typename T::value_type;
21-
{ *t } -> std::same_as<typename T::reference>;
22-
{ &*t } -> std::same_as<typename T::pointer>;
23-
{ ct <=> ct2 } -> std::same_as<std::strong_ordering>;
24-
{ t.advance(d) };
25-
{ ct.distance_to(ct) } -> std::same_as<typename T::difference_type>;
26-
};
16+
concept iterator_facadeable_c = std::integral<typename T::difference_type> && std::is_pointer_v<typename T::pointer> &&
17+
std::is_lvalue_reference_v<typename T::reference> &&
18+
requires(T t, std::remove_cvref_t<T> mt, std::add_const_t<T> ct,
19+
std::add_const_t<T> ct2, typename std::remove_cvref_t<T>::difference_type d) {
20+
typename T::value_type;
21+
{ *t } -> std::same_as<typename T::reference>;
22+
{ &*t } -> std::same_as<typename T::pointer>;
23+
{ ct <=> ct2 } -> std::same_as<std::strong_ordering>;
24+
{ mt += d } -> std::same_as<std::add_lvalue_reference_t<T>>;
25+
{ ct - ct2 } -> std::same_as<typename T::difference_type>;
26+
};
27+
28+
template <typename T, typename Int>
29+
concept compound_assignable_c = requires(T t, Int n) {
30+
{ t += n } -> std::same_as<std::add_lvalue_reference_t<T>>;
31+
};
2732
} // namespace detail
2833

2934
class IteratorFacade {
@@ -71,43 +76,29 @@ class IteratorFacade {
7176
return result;
7277
}
7378
template <typename Self>
74-
constexpr std::add_lvalue_reference_t<Self> operator+=(this Self& self, std::integral auto offset) {
75-
self.advance(offset);
76-
return self;
77-
}
78-
template <typename Self>
7979
constexpr std::add_lvalue_reference_t<Self> operator-=(this Self& self, std::integral auto idx) {
8080
return (self += (-idx));
8181
}
8282

83-
template <typename Self>
84-
requires std::derived_from<std::remove_cvref_t<Self>, IteratorFacade> &&
85-
detail::iterator_facadeable_c<std::remove_cvref_t<Self>>
86-
friend constexpr std::remove_cvref_t<Self> operator+(Self&& self, std::integral auto offset) {
83+
template <typename Self, std::integral Int>
84+
friend constexpr std::remove_cvref_t<Self> operator+(Self&& self, Int offset)
85+
requires std::derived_from<std::remove_cvref_t<Self>, IteratorFacade> //&& detail::iterator_facadeable_c<Self>
86+
{
8787
using Result = std::remove_cvref_t<Self>;
8888
Result result{std::forward<Self>(self)};
8989
result += offset;
9090
return result;
9191
}
92-
template <typename Self>
93-
requires std::derived_from<std::remove_cvref_t<Self>, IteratorFacade> &&
94-
detail::iterator_facadeable_c<std::remove_cvref_t<Self>>
95-
friend constexpr std::remove_cvref_t<Self> operator+(std::integral auto offset, Self&& self) {
92+
template <typename Self, std::integral Int>
93+
requires std::derived_from<std::remove_cvref_t<Self>, IteratorFacade> //&& detail::iterator_facadeable_c<Self>
94+
friend constexpr std::remove_cvref_t<Self> operator+(Int offset, Self&& self) {
9695
return std::forward<Self>(self) + offset;
9796
}
98-
template <typename Self>
99-
requires std::derived_from<std::remove_cvref_t<Self>, IteratorFacade> &&
100-
detail::iterator_facadeable_c<std::remove_cvref_t<Self>>
101-
friend constexpr std::remove_cvref_t<Self> operator-(Self&& self, std::integral auto idx) {
97+
template <typename Self, std::integral Int>
98+
requires std::derived_from<std::remove_cvref_t<Self>, IteratorFacade> //&& detail::iterator_facadeable_c<Self>
99+
friend constexpr std::remove_cvref_t<Self> operator-(Self&& self, Int idx) {
102100
return (std::forward<Self>(self)) + (-idx);
103101
}
104-
template <typename Self, typename Other>
105-
requires std::derived_from<std::remove_cvref_t<Self>, IteratorFacade> &&
106-
detail::iterator_facadeable_c<std::remove_cvref_t<Self>> &&
107-
std::same_as<std::remove_cvref_t<Self>, std::remove_cvref_t<Other>>
108-
friend constexpr auto operator-(Self&& self, Other&& other) {
109-
return std::forward<Other>(other).distance_to(std::forward<Self>(self));
110-
}
111102

112103
template <typename Self>
113104
constexpr decltype(auto) operator[](this Self const& self, typename Self::difference_type idx) {
@@ -122,7 +113,7 @@ class IteratorFacade {
122113
// instantiated when used.
123114
static_assert(std::derived_from<std::remove_cvref_t<Self>, IteratorFacade>);
124115
static_assert(detail::iterator_facadeable_c<std::remove_cvref_t<Self>>);
125-
};
116+
}
126117
};
127118

128119
} // namespace power_grid_model

power_grid_model_c/power_grid_model/include/power_grid_model/container.hpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,6 @@ class Container<RetrievableTypes<GettableTypes...>, StorageableTypes...> {
286286

287287
// define iterator
288288
template <supported_type_c<GettableTypes...> Gettable> class Iterator : public IteratorFacade {
289-
friend class IteratorFacade;
290-
291289
public:
292290
using value_type = Gettable;
293291
using difference_type = Idx;
@@ -312,17 +310,22 @@ class Container<RetrievableTypes<GettableTypes...>, StorageableTypes...> {
312310
}
313311
constexpr Gettable& operator*() { return container_ptr_->template get_item_by_seq<base_type>(idx_); }
314312

315-
friend constexpr auto operator<=>(Iterator const& first, Iterator const& second) {
313+
constexpr auto operator+=(Idx n) -> std::add_lvalue_reference_t<Iterator> {
314+
idx_ += n;
315+
return *this;
316+
}
317+
318+
friend constexpr auto operator<=>(Iterator const& first, Iterator const& second) -> std::strong_ordering {
316319
assert(first.container_ptr_ == second.container_ptr_);
317320
return first.idx_ <=> second.idx_;
318321
}
322+
friend constexpr auto operator-(Iterator const& first, Iterator const& second) -> difference_type {
323+
assert(first.container_ptr_ == second.container_ptr_);
324+
return first.idx_ - second.idx_;
325+
}
319326

320327
private:
321328
constexpr void advance(Idx n) { idx_ += n; }
322-
constexpr Idx distance_to(Iterator const& other) const {
323-
assert(container_ptr_ == other.container_ptr_);
324-
return other.idx_ - idx_;
325-
}
326329

327330
// store container pointer
328331
// and idx

tests/cpp_unit_tests/test_iterator_facade.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ using power_grid_model::IteratorFacade;
1515
using power_grid_model::detail::iterator_facadeable_c;
1616

1717
template <typename UnderlyingType> class BaseTestIterator : public IteratorFacade {
18-
friend class IteratorFacade;
19-
2018
public:
2119
using underlying = UnderlyingType;
2220

@@ -35,8 +33,13 @@ template <typename UnderlyingType> class BaseTestIterator : public IteratorFacad
3533
return *first.it_ <=> *second.it_;
3634
}
3735

38-
constexpr auto distance_to(BaseTestIterator const& other) const -> difference_type { return other.it_ - it_; }
39-
constexpr void advance(difference_type n) { it_ += n; }
36+
constexpr auto operator+=(difference_type n) -> std::add_lvalue_reference_t<BaseTestIterator> {
37+
it_ += n;
38+
return *this;
39+
}
40+
friend constexpr auto operator-(BaseTestIterator const& first, BaseTestIterator const& second) -> difference_type {
41+
return second.it_ - first.it_;
42+
}
4043

4144
private:
4245
underlying it_;

0 commit comments

Comments
 (0)