Qx v0.5.7
Qt Extensions Library
Loading...
Searching...
No Matches
qx-cumulation.h
1#ifndef QX_CUMULATION_H
2#define QX_CUMULATION_H
3
4// Qt Includes
5#include <QHash>
6
7// Extra-component Includes
9
10/* TODO: An iterator can't be added to this class unless it dereferences to a special class like the QJsonValueRef
11 * approach since when the value is modified the running total would need to be changed as well. That or the running
12 * total needs to be done away with and the total() method needs to calculate the total each time its called (ehhhh)
13 */
14
15namespace Qx
16{
17
18template <typename K, typename V>
19 requires arithmetic<V>
21{
22//-Instance Variables----------------------------------------------------------------------------------------------
23private:
24 QHash<K, V> mComponents;
25 QHash<K, V> mScalars;
26 V mTotal;
27
28//-Constructor----------------------------------------------------------------------------------------------
29public:
31 mTotal(0)
32 {}
33
34//-Instance Functions----------------------------------------------------------------------------------------------
35private:
36 template<typename N>
37 requires std::integral<N>
38 N sMean() const
39 {
40 return !mComponents.isEmpty() ? std::round(static_cast<double>(mTotal)/mComponents.count()) : 0;
41 }
42
43 template<typename N>
44 requires std::floating_point<N>
45 N sMean() const
46 {
47 return !mComponents.isEmpty() ? mTotal/mComponents.count() : 0;
48 }
49
50 void basicInsert(K component, V value, V scalar)
51 {
52 mTotal += value * scalar;
53 mComponents[component] = value;
54 mScalars[component] = scalar;
55 }
56
57public:
58 void insert(K component, V value, V scalar = 1)
59 {
60 // If replacing an existing value, remove its portion from the running total if its not the same
61 if(mComponents.contains(component))
62 {
63 const V& curVal = mComponents[component];
64 const V& curScal = mScalars[component];
65
66 // Remove old component portion from running total if different
67 if(curVal != value || curScal != scalar)
68 mTotal -= curVal * curScal;
69 else
70 return;
71 }
72
73 // Insert/replace
74 basicInsert(component, value, scalar);
75 }
76
77 void setValue(K component, V value)
78 {
79 if(mComponents.contains(component))
80 {
81 V& curVal = mComponents[component];
82 if(value != curVal)
83 {
84 const V& scalar = mScalars[component];
85 mTotal += (value * scalar) - (curVal * scalar);
86 curVal = value;
87 }
88 }
89 else
90 basicInsert(component, value, 1);
91 }
92
93 void setScalar(K component, V scalar)
94 {
95 if(mComponents.contains(component))
96 {
97 V& curScalar = mScalars[component];
98 if(scalar != curScalar)
99 {
100 const V& value = mComponents[component];
101 mTotal += (value * scalar) - (value * curScalar);
102 curScalar = scalar;
103 }
104 }
105 else
106 basicInsert(component, 0, scalar);
107 }
108
109 void increase(K component, V amount)
110 {
111 if(mComponents.contains(component))
112 {
113 mTotal += amount * mScalars[component];
114 mComponents[component] += amount;
115 }
116 else
117 basicInsert(component, amount, 1);
118 }
119
120 void reduce(K component, V amount)
121 {
122 if(mComponents.contains(component))
123 {
124 mTotal -= amount * mScalars[component];
125 mComponents[component] -= amount;
126 }
127 else
128 basicInsert(component, -amount, 1);
129 }
130
131 V increment(K component)
132 {
133 if(mComponents.contains(component))
134 {
135 mTotal += mScalars[component];
136 mComponents[component]++;
137 }
138 else
139 basicInsert(component, 1, 1);
140
141 return mTotal;
142 }
143
144 V decrement(K component)
145 {
146 if(mComponents.contains(component))
147 {
148 mTotal -= mScalars[component];
149 mComponents[component]--;
150 }
151 else
152 basicInsert(component, -1, 1);
153
154 return mTotal;
155 }
156
157 void remove(K component)
158 {
159 if(mComponents.contains(component))
160 {
161 mTotal -= (mComponents[component] * mScalars[component]);
162 mComponents.remove(component);
163 mScalars.remove(component);
164 }
165 }
166
167 void clear()
168 {
169 mComponents.clear();
170 mScalars.clear();
171 mTotal = 0;
172 }
173
174 bool contains(K component) const { return mComponents.contains(component); }
175 V value(K component) const { return mComponents.value(component); }
176 V total() const { return mTotal; }
177 QList<K> components() const { return mComponents.keys(); }
178
179 qsizetype count() const { return mComponents.count(); }
180 bool isEmpty() const { return mComponents.isEmpty(); }
181 V mean() const { return sMean<V>(); }
182
183 bool operator==(const Cumulation& other) const
184 {
185 return mComponents == other.mComponents && mScalars == other.mScalars && mTotal == other.mTotal;
186 }
187
188 bool operator!=(const Cumulation& other) const { return !(*this == other); }
189};
190
191}
192
193#endif // QX_CUMULATION_H
The Cumulation template class tracks the sum of multiple key-value components that can be changed ind...
Definition qx-cumulation.h:21
bool isEmpty() const
Definition qx-cumulation.h:180
bool operator!=(const Cumulation &other) const
Definition qx-cumulation.h:188
V decrement(K component)
Definition qx-cumulation.h:144
V increment(K component)
Definition qx-cumulation.h:131
bool contains(K component) const
Definition qx-cumulation.h:174
void reduce(K component, V amount)
Definition qx-cumulation.h:120
void clear()
Definition qx-cumulation.h:167
V mean() const
Definition qx-cumulation.h:181
void setValue(K component, V value)
Definition qx-cumulation.h:77
V total() const
Definition qx-cumulation.h:176
void increase(K component, V amount)
Definition qx-cumulation.h:109
void setScalar(K component, V scalar)
Definition qx-cumulation.h:93
QList< K > components() const
Definition qx-cumulation.h:177
void remove(K component)
Definition qx-cumulation.h:157
qsizetype count() const
Definition qx-cumulation.h:179
bool operator==(const Cumulation &other) const
Definition qx-cumulation.h:183
V value(K component) const
Definition qx-cumulation.h:175
void insert(K component, V value, V scalar=1)
Definition qx-cumulation.h:58
Cumulation()
Definition qx-cumulation.h:30
The Qx namespace is the main namespace through which all non-global functionality of the Qx library i...
Definition qx-processwaiter.cpp:5
void clear()
bool contains(const Key &key) const const
qsizetype count() const const
bool isEmpty() const const
QList< Key > keys() const const
bool remove(const Key &key)
T value(const Key &key) const const
The qx-concepts header file provides a library of general purpose concepts as an extension of the sta...