@@ -13,7 +13,7 | |||||
13 | template <int Dim> |
|
13 | template <int Dim> | |
14 | class ArrayData; |
|
14 | class ArrayData; | |
15 |
|
15 | |||
16 |
using DataContainer = QVector< |
|
16 | using DataContainer = QVector<double>; | |
17 |
|
17 | |||
18 | namespace arraydata_detail { |
|
18 | namespace arraydata_detail { | |
19 |
|
19 | |||
@@ -130,37 +130,34 public: | |||||
130 | * @param data the data the ArrayData will hold |
|
130 | * @param data the data the ArrayData will hold | |
131 | */ |
|
131 | */ | |
132 | template <int D = Dim, typename = std::enable_if_t<D == 1> > |
|
132 | template <int D = Dim, typename = std::enable_if_t<D == 1> > | |
133 | explicit ArrayData(QVector<double> data) : m_Data{1, QVector<double>{}} |
|
133 | explicit ArrayData(DataContainer data) : m_Data{std::move(data)}, m_NbComponents{1} | |
134 | { |
|
134 | { | |
135 | m_Data[0] = std::move(data); |
|
|||
136 | } |
|
135 | } | |
137 |
|
136 | |||
138 | /** |
|
137 | /** | |
139 |
* Ctor for a two-dimensional ArrayData. The number of components (number of |
|
138 | * Ctor for a two-dimensional ArrayData. The number of components (number of lines) must be | |
140 |
* greater than 2 and |
|
139 | * greater than 2 and must be a divisor of the total number of data in the vector | |
141 | * @param data the data the ArrayData will hold |
|
140 | * @param data the data the ArrayData will hold | |
142 |
* @ |
|
141 | * @param nbComponents the number of components | |
143 | * @remarks if the number of values is not the same for each component, no value is set |
|
142 | * @throws std::invalid_argument if the number of components is less than 2 or is not a divisor | |
|
143 | * of the size of the data | |||
144 | */ |
|
144 | */ | |
145 | template <int D = Dim, typename = std::enable_if_t<D == 2> > |
|
145 | template <int D = Dim, typename = std::enable_if_t<D == 2> > | |
146 | explicit ArrayData(DataContainer data) |
|
146 | explicit ArrayData(DataContainer data, int nbComponents) | |
|
147 | : m_Data{std::move(data)}, m_NbComponents{nbComponents} | |||
147 | { |
|
148 | { | |
148 | auto nbComponents = data.size(); |
|
|||
149 | if (nbComponents < 2) { |
|
149 | if (nbComponents < 2) { | |
150 | throw std::invalid_argument{ |
|
150 | throw std::invalid_argument{ | |
151 | QString{"A multidimensional ArrayData must have at least 2 components (found: %1"} |
|
151 | QString{"A multidimensional ArrayData must have at least 2 components (found: %1)"} | |
152 |
.arg( |
|
152 | .arg(nbComponents) | |
153 | .toStdString()}; |
|
153 | .toStdString()}; | |
154 | } |
|
154 | } | |
155 |
|
155 | |||
156 | auto nbValues = data.front().size(); |
|
156 | if (m_Data.size() % m_NbComponents != 0) { | |
157 | if (std::all_of(data.cbegin(), data.cend(), [nbValues](const auto &component) { |
|
157 | throw std::invalid_argument{QString{ | |
158 | return component.size() == nbValues; |
|
158 | "The number of components (%1) is inconsistent with the total number of data (%2)"} | |
159 | })) { |
|
159 | .arg(m_Data.size(), nbComponents) | |
160 | m_Data = std::move(data); |
|
160 | .toStdString()}; | |
161 | } |
|
|||
162 | else { |
|
|||
163 | m_Data = DataContainer{nbComponents, QVector<double>{}}; |
|
|||
164 | } |
|
161 | } | |
165 | } |
|
162 | } | |
166 |
|
163 | |||
@@ -169,6 +166,7 public: | |||||
169 | { |
|
166 | { | |
170 | QReadLocker otherLocker{&other.m_Lock}; |
|
167 | QReadLocker otherLocker{&other.m_Lock}; | |
171 | m_Data = other.m_Data; |
|
168 | m_Data = other.m_Data; | |
|
169 | m_NbComponents = other.m_NbComponents; | |||
172 | } |
|
170 | } | |
173 |
|
171 | |||
174 | // /////////////// // |
|
172 | // /////////////// // | |
@@ -187,66 +185,42 public: | |||||
187 | QWriteLocker locker{&m_Lock}; |
|
185 | QWriteLocker locker{&m_Lock}; | |
188 | QReadLocker otherLocker{&other.m_Lock}; |
|
186 | QReadLocker otherLocker{&other.m_Lock}; | |
189 |
|
187 | |||
190 | auto nbComponents = m_Data.size(); |
|
188 | if (m_NbComponents != other.componentCount()) { | |
191 | if (nbComponents != other.m_Data.size()) { |
|
|||
192 | return; |
|
189 | return; | |
193 | } |
|
190 | } | |
194 |
|
191 | |||
195 | for (auto componentIndex = 0; componentIndex < nbComponents; ++componentIndex) { |
|
|||
196 |
|
|
192 | if (prepend) { | |
197 |
|
|
193 | auto otherDataSize = other.m_Data.size(); | |
198 | const auto otherDataSize = otherData.size(); |
|
194 | m_Data.insert(m_Data.begin(), otherDataSize, 0.); | |
199 |
|
||||
200 | auto &data = m_Data[componentIndex]; |
|
|||
201 | data.insert(data.begin(), otherDataSize, 0.); |
|
|||
202 |
|
||||
203 |
|
|
195 | for (auto i = 0; i < otherDataSize; ++i) { | |
204 |
|
|
196 | m_Data.replace(i, other.m_Data.at(i)); | |
205 |
|
|
197 | } | |
206 |
|
|
198 | } | |
207 |
|
|
199 | else { | |
208 |
|
|
200 | m_Data.append(other.m_Data); | |
209 | } |
|
|||
210 | } |
|
201 | } | |
211 | } |
|
202 | } | |
212 |
|
203 | |||
213 | void clear() |
|
204 | void clear() | |
214 | { |
|
205 | { | |
215 | QWriteLocker locker{&m_Lock}; |
|
206 | QWriteLocker locker{&m_Lock}; | |
216 |
|
207 | m_Data.clear(); | ||
217 | auto nbComponents = m_Data.size(); |
|
|||
218 | for (auto i = 0; i < nbComponents; ++i) { |
|
|||
219 | m_Data[i].clear(); |
|
|||
220 |
|
|
208 | } | |
221 | } |
|
|||
222 |
|
||||
223 | int componentCount() const noexcept { return m_Data.size(); } |
|
|||
224 |
|
||||
225 | /** |
|
|||
226 | * @return the data of a component |
|
|||
227 | * @param componentIndex the index of the component to retrieve the data |
|
|||
228 | * @return the component's data, empty vector if the index is invalid |
|
|||
229 | */ |
|
|||
230 | QVector<double> data(int componentIndex) const noexcept |
|
|||
231 | { |
|
|||
232 | QReadLocker locker{&m_Lock}; |
|
|||
233 |
|
209 | |||
234 | return (componentIndex >= 0 && componentIndex < m_Data.size()) ? m_Data.at(componentIndex) |
|
210 | int componentCount() const noexcept { return m_NbComponents; } | |
235 | : QVector<double>{}; |
|
|||
236 | } |
|
|||
237 |
|
211 | |||
238 | /// @return the size (i.e. number of values) of a single component |
|
212 | /// @return the size (i.e. number of values) of a single component | |
239 | /// @remarks in a case of a two-dimensional ArrayData, each component has the same size |
|
213 | /// @remarks in a case of a two-dimensional ArrayData, each component has the same size | |
240 | int size() const |
|
214 | int size() const | |
241 | { |
|
215 | { | |
242 | QReadLocker locker{&m_Lock}; |
|
216 | QReadLocker locker{&m_Lock}; | |
243 |
return m_Data |
|
217 | return m_Data.size() / m_NbComponents; | |
244 | } |
|
218 | } | |
245 |
|
219 | |||
246 | std::shared_ptr<ArrayData<Dim> > sort(const std::vector<int> &sortPermutation) |
|
220 | std::shared_ptr<ArrayData<Dim> > sort(const std::vector<int> &sortPermutation) | |
247 | { |
|
221 | { | |
248 | QReadLocker locker{&m_Lock}; |
|
222 | QReadLocker locker{&m_Lock}; | |
249 | return arraydata_detail::Sort<Dim>::sort(m_Data, sortPermutation); |
|
223 | return arraydata_detail::Sort<Dim>::sort(m_Data, m_NbComponents, sortPermutation); | |
250 | } |
|
224 | } | |
251 |
|
225 | |||
252 | // ///////// // |
|
226 | // ///////// // | |
@@ -277,7 +251,7 public: | |||||
277 | double at(int index) const noexcept |
|
251 | double at(int index) const noexcept | |
278 | { |
|
252 | { | |
279 | QReadLocker locker{&m_Lock}; |
|
253 | QReadLocker locker{&m_Lock}; | |
280 |
return m_Data |
|
254 | return m_Data.at(index); | |
281 | } |
|
255 | } | |
282 |
|
256 | |||
283 | /** |
|
257 | /** | |
@@ -319,6 +293,8 public: | |||||
319 |
|
293 | |||
320 | private: |
|
294 | private: | |
321 | DataContainer m_Data; |
|
295 | DataContainer m_Data; | |
|
296 | /// Number of components (lines). Is always 1 in a 1-dim ArrayData | |||
|
297 | int m_NbComponents; | |||
322 | mutable QReadWriteLock m_Lock; |
|
298 | mutable QReadWriteLock m_Lock; | |
323 | }; |
|
299 | }; | |
324 |
|
300 |
General Comments 0
You need to be logged in to leave comments.
Login now