Skip to content

Commit bb08faf

Browse files
author
Michal Tichák
committed
filtering iterators working
1 parent a604541 commit bb08faf

File tree

4 files changed

+223
-85
lines changed

4 files changed

+223
-85
lines changed

Framework/include/QualityControl/Data.h

Lines changed: 99 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,12 @@
2020
#include <any>
2121
#include <concepts>
2222
#include <functional>
23-
#include <iostream>
2423
#include <iterator>
2524
#include <map>
2625
#include <memory>
2726
#include <optional>
2827
#include <string>
2928
#include <vector>
30-
#include <typeinfo>
3129

3230
namespace o2::quality_control::core
3331
{
@@ -40,8 +38,38 @@ class Data
4038
using InternalContainer = std::map<std::string, std::any, std::less<>>;
4139
using InternalContainerConstIterator = InternalContainer::const_iterator;
4240

43-
public:
4441
template <typename T>
42+
using value_type = std::pair<std::reference_wrapper<const std::string>, std::reference_wrapper<const T>>;
43+
44+
template <typename T>
45+
struct NoPredicateIncrementPolicy {
46+
bool increment(const InternalContainerConstIterator& it, std::optional<value_type<T>>& val)
47+
{
48+
if (auto* casted = std::any_cast<T>(&it->second); casted != nullptr) {
49+
val.emplace(it->first, *casted);
50+
return true;
51+
}
52+
return false;
53+
}
54+
};
55+
56+
template <typename T, std::predicate<const T&> Pred>
57+
struct PredicateIncrementPolicy {
58+
Pred filter;
59+
bool increment(const InternalContainerConstIterator& it, std::optional<value_type<T>>& val)
60+
{
61+
if (auto* casted = std::any_cast<T>(&it->second); casted != nullptr) {
62+
if (filter(*casted)) {
63+
val.emplace(it->first, *casted);
64+
return true;
65+
}
66+
}
67+
return false;
68+
}
69+
};
70+
71+
public:
72+
template <typename T, typename IncrementalPolicy = NoPredicateIncrementPolicy<T>>
4573
class Iterator
4674
{
4775
public:
@@ -51,26 +79,28 @@ class Data
5179
using reference = const value_type&;
5280
using pointer = const value_type*;
5381

82+
private:
83+
public:
5484
Iterator() = default;
55-
Iterator(InternalContainerConstIterator it, InternalContainerConstIterator end)
56-
: mIt{ it }, mEnd{ end }, val{ std::nullopt }
85+
Iterator(const InternalContainerConstIterator& it, const InternalContainerConstIterator& end, const IncrementalPolicy& policy = {})
86+
: mIt{ it }, mEnd{ end }, mVal{ std::nullopt }
5787
{
5888
seek_next_valid(mIt);
5989
}
6090

6191
reference operator*() const
6292
{
63-
return val.value();
93+
return mVal.value();
6494
}
6595

6696
pointer operator->() const
6797
{
68-
return &val.value();
98+
return &mVal.value();
6999
}
70100

71101
Iterator& operator++()
72102
{
73-
// can this be optimised out?
103+
// TODO: can this check be optimised out?
74104
if (mIt != mEnd) {
75105
seek_next_valid(++mIt);
76106
}
@@ -92,19 +122,22 @@ class Data
92122
private:
93123
InternalContainerConstIterator mIt;
94124
InternalContainerConstIterator mEnd;
95-
std::optional<value_type> val;
125+
IncrementalPolicy mPolicy;
126+
std::optional<value_type> mVal;
96127

97-
void seek_next_valid(InternalContainerConstIterator startingIt)
128+
void seek_next_valid(InternalContainerConstIterator& startingIt)
98129
{
99-
for (auto it = startingIt; it != mEnd; ++it) {
100-
if (auto* casted = std::any_cast<T>(&it->second); casted != nullptr) {
101-
val.emplace(it->first, *casted);
130+
for (; startingIt != mEnd; ++startingIt) {
131+
if (mPolicy.increment(startingIt, mVal)) {
102132
break;
103133
}
104134
}
105135
}
106136
};
107137

138+
template <typename T, std::predicate<const T&> P>
139+
using FilteringIterator = Iterator<T, PredicateIncrementPolicy<T, P>>;
140+
108141
static_assert(std::forward_iterator<Iterator<int>>);
109142

110143
Data() = default;
@@ -127,44 +160,75 @@ class Data
127160
mObjects.insert({ std::string{ key }, value });
128161
}
129162

130-
template <typename Type>
131-
std::vector<Type> getAllOfType() const
163+
template <typename T>
164+
struct Range {
165+
Iterator<T> begin_it;
166+
Iterator<T> end_it;
167+
Iterator<T> begin() { return begin_it; }
168+
Iterator<T> end() { return end_it; }
169+
};
170+
171+
template <typename T>
172+
Range<T> iterate() const noexcept
132173
{
133-
std::vector<Type> result;
134-
for (const auto& [_, object] : mObjects) {
135-
if (auto* casted = std::any_cast<Type>(&object); casted != nullptr) {
136-
result.push_back(*casted);
137-
}
138-
}
139-
return result;
174+
return {
175+
.begin_it = begin<T>(),
176+
.end_it = end<T>()
177+
};
140178
}
141179

142-
template <typename Type, std::predicate<Type> Pred>
143-
std::vector<Type> getAllOfTypeIf(Pred filter) const
180+
template <typename T, std::predicate<const T&> P>
181+
struct FilteredRange {
182+
FilteringIterator<T, P> begin_it;
183+
FilteringIterator<T, P> end_it;
184+
FilteringIterator<T, P> begin() { return begin_it; }
185+
FilteringIterator<T, P> end() { return end_it; }
186+
};
187+
188+
template <typename Type, std::predicate<const Type&> Pred>
189+
FilteredRange<Type, Pred> iterateAndFilter(Pred&& filter) const noexcept
144190
{
145-
std::vector<Type> result;
146-
for (const auto& [_, object] : mObjects) {
147-
if (auto* casted = std::any_cast<Type>(&object); casted != nullptr) {
148-
if (filter(*casted)) {
149-
result.push_back(*casted);
150-
}
151-
}
152-
}
153-
return result;
191+
return FilteredRange<Type, Pred>{
192+
.begin_it = begin<Type, Pred>(std::forward<Pred>(filter)),
193+
.end_it = end<Type, Pred>(std::forward<Pred>(filter))
194+
};
154195
}
155196

197+
size_t size();
198+
156199
template <typename T>
157-
Iterator<T> begin()
200+
Iterator<T> begin() const noexcept
158201
{
159202
return { mObjects.begin(), mObjects.end() };
160203
}
161204

205+
template <typename T, std::predicate<const T&> P>
206+
FilteringIterator<T, P> begin(P&& filter) const noexcept
207+
{
208+
return { mObjects.begin(), mObjects.end(), PredicateIncrementPolicy<T, P>(filter) };
209+
}
210+
162211
template <typename T>
163-
Iterator<T> end()
212+
Iterator<T> end() const noexcept
164213
{
165214
return { mObjects.end(), mObjects.end() };
166215
}
167216

217+
template <typename T, std::predicate<const T&> P>
218+
FilteringIterator<T, P> end(P&& filter) const noexcept
219+
{
220+
return { mObjects.end(), mObjects.end(), PredicateIncrementPolicy<T, P>(filter) };
221+
}
222+
223+
template <typename Base, typename Derived>
224+
static std::optional<Derived*> downcast(const Base* base)
225+
{
226+
if (const auto* casted = dynamic_cast<Derived*>(base); casted != nullptr) {
227+
return { casted };
228+
}
229+
return std::nullopt;
230+
}
231+
168232
private:
169233
InternalContainer mObjects;
170234
};

Framework/src/Data.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,10 @@ Data::Data(const std::map<std::string, std::shared_ptr<MonitorObject>>& moMap)
2424
insert(key, mo);
2525
}
2626
}
27+
28+
size_t Data::size()
29+
{
30+
return mObjects.size();
31+
}
32+
2733
} // namespace o2::quality_control::core

0 commit comments

Comments
 (0)