Skip to content

Commit 24495dd

Browse files
author
Michal Tichák
committed
version 2
1 parent bb08faf commit 24495dd

File tree

7 files changed

+180
-285
lines changed

7 files changed

+180
-285
lines changed

Framework/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ add_library(O2QualityControl
137137
src/KafkaPoller.cxx
138138
src/FlagHelpers.cxx
139139
src/ObjectMetadataHelpers.cxx
140-
src/Data.cxx
140+
src/DataAdapters.cxx
141141
)
142142

143143
target_include_directories(

Framework/include/QualityControl/Data.h

Lines changed: 43 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -20,128 +20,23 @@
2020
#include <any>
2121
#include <concepts>
2222
#include <functional>
23-
#include <iterator>
2423
#include <map>
2524
#include <memory>
2625
#include <optional>
2726
#include <string>
28-
#include <vector>
27+
#include <ranges>
28+
#include <type_traits>
2929

3030
namespace o2::quality_control::core
3131
{
3232

33-
class MonitorObject;
33+
template <typename Function, typename Result, typename... Args>
34+
concept invocable_r = std::invocable<Function, Args...> && std::same_as<std::invoke_result_t<Function, Args...>, Result>;
3435

3536
class Data
3637
{
37-
// change this for boost::flat_map? or do a magic and split by different keys?
38-
using InternalContainer = std::map<std::string, std::any, std::less<>>;
39-
using InternalContainerConstIterator = InternalContainer::const_iterator;
40-
41-
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-
7138
public:
72-
template <typename T, typename IncrementalPolicy = NoPredicateIncrementPolicy<T>>
73-
class Iterator
74-
{
75-
public:
76-
using value_type = std::pair<std::reference_wrapper<const std::string>, std::reference_wrapper<const T>>;
77-
using difference_type = std::ptrdiff_t;
78-
using iterator_category = std::forward_iterator_tag;
79-
using reference = const value_type&;
80-
using pointer = const value_type*;
81-
82-
private:
83-
public:
84-
Iterator() = default;
85-
Iterator(const InternalContainerConstIterator& it, const InternalContainerConstIterator& end, const IncrementalPolicy& policy = {})
86-
: mIt{ it }, mEnd{ end }, mVal{ std::nullopt }
87-
{
88-
seek_next_valid(mIt);
89-
}
90-
91-
reference operator*() const
92-
{
93-
return mVal.value();
94-
}
95-
96-
pointer operator->() const
97-
{
98-
return &mVal.value();
99-
}
100-
101-
Iterator& operator++()
102-
{
103-
// TODO: can this check be optimised out?
104-
if (mIt != mEnd) {
105-
seek_next_valid(++mIt);
106-
}
107-
return *this;
108-
}
109-
110-
Iterator operator++(int)
111-
{
112-
auto tmp = *this;
113-
++*this;
114-
return tmp;
115-
}
116-
117-
bool operator==(const Iterator& other) const
118-
{
119-
return mIt == other.mIt;
120-
}
121-
122-
private:
123-
InternalContainerConstIterator mIt;
124-
InternalContainerConstIterator mEnd;
125-
IncrementalPolicy mPolicy;
126-
std::optional<value_type> mVal;
127-
128-
void seek_next_valid(InternalContainerConstIterator& startingIt)
129-
{
130-
for (; startingIt != mEnd; ++startingIt) {
131-
if (mPolicy.increment(startingIt, mVal)) {
132-
break;
133-
}
134-
}
135-
}
136-
};
137-
138-
template <typename T, std::predicate<const T&> P>
139-
using FilteringIterator = Iterator<T, PredicateIncrementPolicy<T, P>>;
140-
141-
static_assert(std::forward_iterator<Iterator<int>>);
142-
14339
Data() = default;
144-
Data(const std::map<std::string, std::shared_ptr<MonitorObject>>& moMap);
14540

14641
template <typename Result>
14742
std::optional<Result> get(std::string_view key)
@@ -154,83 +49,71 @@ class Data
15449
return std::nullopt;
15550
}
15651

157-
template <typename StoreType>
158-
void insert(std::string_view key, const StoreType& value)
52+
template <typename T, typename... Args>
53+
void emplace(std::string_view key, Args&&... args)
15954
{
160-
mObjects.insert({ std::string{ key }, value });
55+
mObjects.emplace(key, std::any{ std::in_place_type<T>, std::forward<Args>(args)... });
16156
}
16257

16358
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-
};
59+
void insert(std::string_view key, const T& value)
60+
{
61+
mObjects.insert({ std::string{ key }, value });
62+
}
17063

17164
template <typename T>
172-
Range<T> iterate() const noexcept
65+
static const T* any_cast_try_shared_ptr(const std::any& value)
17366
{
174-
return {
175-
.begin_it = begin<T>(),
176-
.end_it = end<T>()
177-
};
67+
if (auto* casted = std::any_cast<std::shared_ptr<T>>(&value); casted != nullptr) {
68+
return casted->get();
69+
} else {
70+
return std::any_cast<T>(&value);
71+
}
17872
}
17973

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-
};
74+
template <typename T>
75+
static constexpr auto any_to_specific = std::views::transform([](const auto& pair) -> std::pair<std::string_view, const T*> { return { pair.first, any_cast_try_shared_ptr<T>(pair.second) }; });
18776

188-
template <typename Type, std::predicate<const Type&> Pred>
189-
FilteredRange<Type, Pred> iterateAndFilter(Pred&& filter) const noexcept
190-
{
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-
};
195-
}
77+
static constexpr auto filter_nullptr_in_pair = std::views::filter([](const auto& pair) { return pair.second != nullptr; });
19678

197-
size_t size();
79+
static constexpr auto filter_nullptr = std::views::filter([](const auto* ptr) -> bool { return ptr != nullptr; });
19880

199-
template <typename T>
200-
Iterator<T> begin() const noexcept
201-
{
202-
return { mObjects.begin(), mObjects.end() };
203-
}
81+
static constexpr auto pair_to_reference = std::views::transform([](const auto& pair) -> const auto& { return *pair.second; });
20482

205-
template <typename T, std::predicate<const T&> P>
206-
FilteringIterator<T, P> begin(P&& filter) const noexcept
83+
static constexpr auto pointer_to_reference = std::views::transform([](const auto* ptr) -> auto& { return *ptr; });
84+
85+
template <typename T>
86+
auto iterateByType() const
20787
{
208-
return { mObjects.begin(), mObjects.end(), PredicateIncrementPolicy<T, P>(filter) };
88+
return mObjects | any_to_specific<T> | filter_nullptr_in_pair | pair_to_reference;
20989
}
21090

211-
template <typename T>
212-
Iterator<T> end() const noexcept
91+
template <typename T, std::predicate<const std::pair<std::string_view, const T*>&> Pred>
92+
auto iterateByTypeAndFilter(Pred&& filter) const
21393
{
214-
return { mObjects.end(), mObjects.end() };
94+
return mObjects | any_to_specific<T> | filter_nullptr_in_pair | std::views::filter(filter) | pair_to_reference;
21595
}
21696

217-
template <typename T, std::predicate<const T&> P>
218-
FilteringIterator<T, P> end(P&& filter) const noexcept
97+
template <typename StoredType, typename ResultingType, std::predicate<const std::pair<std::string_view, const StoredType*>&> Pred, invocable_r<const ResultingType*, const StoredType*> Transform>
98+
auto iterateByTypeFilterAndTransform(Pred&& filter, Transform&& transform) const
21999
{
220-
return { mObjects.end(), mObjects.end(), PredicateIncrementPolicy<T, P>(filter) };
100+
return mObjects |
101+
any_to_specific<StoredType> |
102+
filter_nullptr_in_pair |
103+
std::views::filter(filter) |
104+
std::views::transform([](const auto& pair) { return pair.second; }) |
105+
std::views::transform(transform) |
106+
filter_nullptr |
107+
pointer_to_reference;
221108
}
222109

223-
template <typename Base, typename Derived>
224-
static std::optional<Derived*> downcast(const Base* base)
110+
size_t size() const noexcept
225111
{
226-
if (const auto* casted = dynamic_cast<Derived*>(base); casted != nullptr) {
227-
return { casted };
228-
}
229-
return std::nullopt;
112+
return mObjects.size();
230113
}
231114

232115
private:
233-
InternalContainer mObjects;
116+
std::map<std::string, std::any, std::less<>> mObjects;
234117
};
235118

236119
} // namespace o2::quality_control::core
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2025 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
///
13+
/// \file DataAdapters.h
14+
/// \author Michal Tichak
15+
///
16+
17+
#ifndef QC_CORE_DATA_ADAPTERS_H
18+
#define QC_CORE_DATA_ADAPTERS_H
19+
20+
#include "Data.h"
21+
#include "QualityControl/MonitorObject.h"
22+
23+
namespace o2::quality_control::core
24+
{
25+
26+
Data createData(const std::map<std::string, std::shared_ptr<MonitorObject>>& moMap);
27+
28+
template <typename Result>
29+
auto iterateMOsFilterByNameAndTransform(const Data& data, std::string_view moName)
30+
{
31+
return data.iterateByTypeFilterAndTransform<MonitorObject, Result>(
32+
[name = std::string{ moName }](const std::pair<std::string_view, const MonitorObject*>& pair) -> bool { return std::string_view{ pair.second->GetName() } == name; },
33+
[](const MonitorObject* ptr) -> const Result* { return dynamic_cast<const Result*>(ptr->getObject()); });
34+
}
35+
36+
} // namespace o2::quality_control::core
37+
38+
#endif

Framework/src/CheckInterface.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "QualityControl/ReferenceUtils.h"
1919
#include "QualityControl/MonitorObject.h"
2020
#include "QualityControl/Data.h"
21+
#include "QualityControl/DataAdapters.h"
2122

2223
#include <TClass.h>
2324

@@ -29,7 +30,7 @@ namespace o2::quality_control::checker
2930

3031
core::Quality CheckInterface::check(std::map<std::string, std::shared_ptr<core::MonitorObject>>* moMap)
3132
{
32-
Data data(*moMap);
33+
auto data = createData(*moMap);
3334
return check(data);
3435
};
3536

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,22 @@
1010
// or submit itself to any jurisdiction.
1111

1212
///
13-
/// \file Data.h
13+
/// \file DataAdapters.cxx
1414
/// \author Michal Tichak
1515
///
1616

17-
#include "QualityControl/Data.h"
17+
#include "QualityControl/DataAdapters.h"
1818

1919
namespace o2::quality_control::core
2020
{
21-
Data::Data(const std::map<std::string, std::shared_ptr<MonitorObject>>& moMap)
21+
22+
Data createData(const std::map<std::string, std::shared_ptr<MonitorObject>>& moMap)
2223
{
24+
Data data;
2325
for (const auto& [key, mo] : moMap) {
24-
insert(key, mo);
26+
data.insert(key, mo);
2527
}
26-
}
27-
28-
size_t Data::size()
29-
{
30-
return mObjects.size();
28+
return data;
3129
}
3230

3331
} // namespace o2::quality_control::core

0 commit comments

Comments
 (0)