1414// / \author Michal Tichak
1515// /
1616
17+ #ifndef QC_CORE_DATA_H
18+ #define QC_CORE_DATA_H
19+
1720#include < any>
1821#include < concepts>
22+ #include < functional>
1923#include < iostream>
24+ #include < iterator>
2025#include < map>
2126#include < memory>
2227#include < optional>
@@ -31,7 +36,77 @@ class MonitorObject;
3136
3237class Data
3338{
39+ // change this for boost::flat_map? or do a magic and split by different keys?
40+ using InternalContainer = std::map<std::string, std::any, std::less<>>;
41+ using InternalContainerConstIterator = InternalContainer::const_iterator;
42+
3443 public:
44+ template <typename T>
45+ class Iterator
46+ {
47+ public:
48+ using value_type = std::pair<std::reference_wrapper<const std::string>, std::reference_wrapper<const T>>;
49+ using difference_type = std::ptrdiff_t ;
50+ using iterator_category = std::forward_iterator_tag;
51+ using reference = const value_type&;
52+ using pointer = const value_type*;
53+
54+ Iterator () = default ;
55+ Iterator (InternalContainerConstIterator it, InternalContainerConstIterator end)
56+ : mIt { it }, mEnd { end }, val{ std::nullopt }
57+ {
58+ seek_next_valid (mIt );
59+ }
60+
61+ reference operator *() const
62+ {
63+ return val.value ();
64+ }
65+
66+ pointer operator ->() const
67+ {
68+ return &val.value ();
69+ }
70+
71+ Iterator& operator ++()
72+ {
73+ // can this be optimised out?
74+ if (mIt != mEnd ) {
75+ seek_next_valid (++mIt );
76+ }
77+ return *this ;
78+ }
79+
80+ Iterator operator ++(int )
81+ {
82+ auto tmp = *this ;
83+ ++*this ;
84+ return tmp;
85+ }
86+
87+ bool operator ==(const Iterator& other) const
88+ {
89+ return mIt == other.mIt ;
90+ }
91+
92+ private:
93+ InternalContainerConstIterator mIt ;
94+ InternalContainerConstIterator mEnd ;
95+ std::optional<value_type> val;
96+
97+ void seek_next_valid (InternalContainerConstIterator startingIt)
98+ {
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);
102+ break ;
103+ }
104+ }
105+ }
106+ };
107+
108+ static_assert (std::forward_iterator<Iterator<int >>);
109+
35110 Data () = default ;
36111 Data (const std::map<std::string, std::shared_ptr<MonitorObject>>& moMap);
37112
@@ -49,7 +124,6 @@ class Data
49124 template <typename StoreType>
50125 void insert (std::string_view key, const StoreType& value)
51126 {
52- // std::cout << "inserting value: " << value << ", of type: " << typeid(StoreType).name() << "\n";
53127 mObjects .insert ({ std::string{ key }, value });
54128 }
55129
@@ -79,8 +153,22 @@ class Data
79153 return result;
80154 }
81155
156+ template <typename T>
157+ Iterator<T> begin ()
158+ {
159+ return { mObjects .begin (), mObjects .end () };
160+ }
161+
162+ template <typename T>
163+ Iterator<T> end ()
164+ {
165+ return { mObjects .end (), mObjects .end () };
166+ }
167+
82168 private:
83- std::map<std::string, std::any, std::less<>> mObjects ;
169+ InternalContainer mObjects ;
84170};
85171
86172} // namespace o2::quality_control::core
173+
174+ #endif
0 commit comments