##// END OF EJS Templates
Moves cbegin() and cend() declarations in IDataSeries...
Alexandre Leroux -
r597:f66c81d8ced0
parent child
Show More
@@ -1,315 +1,328
1 1 #ifndef SCIQLOP_ARRAYDATA_H
2 2 #define SCIQLOP_ARRAYDATA_H
3 3
4 4 #include <Common/SortUtils.h>
5 5
6 6 #include <QReadLocker>
7 7 #include <QReadWriteLock>
8 8 #include <QVector>
9 9
10 10 #include <memory>
11 11
12 12 template <int Dim>
13 13 class ArrayData;
14 14
15 15 using DataContainer = QVector<QVector<double> >;
16 16
17 17 namespace arraydata_detail {
18 18
19 19 /// Struct used to sort ArrayData
20 20 template <int Dim>
21 21 struct Sort {
22 22 static std::shared_ptr<ArrayData<Dim> > sort(const DataContainer &data,
23 23 const std::vector<int> &sortPermutation)
24 24 {
25 25 auto nbComponents = data.size();
26 26 auto sortedData = DataContainer(nbComponents);
27 27
28 28 for (auto i = 0; i < nbComponents; ++i) {
29 29 sortedData[i] = SortUtils::sort(data.at(i), sortPermutation);
30 30 }
31 31
32 32 return std::make_shared<ArrayData<Dim> >(std::move(sortedData));
33 33 }
34 34 };
35 35
36 36 /// Specialization for uni-dimensional ArrayData
37 37 template <>
38 38 struct Sort<1> {
39 39 static std::shared_ptr<ArrayData<1> > sort(const DataContainer &data,
40 40 const std::vector<int> &sortPermutation)
41 41 {
42 42 return std::make_shared<ArrayData<1> >(SortUtils::sort(data.at(0), sortPermutation));
43 43 }
44 44 };
45 45
46 46 } // namespace arraydata_detail
47 47
48 48 /**
49 49 * @brief The ArrayData class represents a dataset for a data series.
50 50 *
51 51 * A dataset can be unidimensional or two-dimensional. This property is determined by the Dim
52 52 * template-parameter. In a case of a two-dimensional dataset, each dataset component has the same
53 53 * number of values
54 54 *
55 55 * @tparam Dim the dimension of the ArrayData (one or two)
56 56 * @sa IDataSeries
57 57 */
58 58 template <int Dim>
59 59 class ArrayData {
60 60 public:
61 61 class IteratorValue {
62 62 public:
63 63 explicit IteratorValue(const DataContainer &container, bool begin) : m_Its{}
64 64 {
65 65 for (auto i = 0; i < container.size(); ++i) {
66 66 m_Its.push_back(begin ? container.at(i).cbegin() : container.at(i).cend());
67 67 }
68 68 }
69 69
70 70 double at(int index) const { return *m_Its.at(index); }
71 71 double first() const { return *m_Its.front(); }
72 72
73 73 void next()
74 74 {
75 75 for (auto &it : m_Its) {
76 76 ++it;
77 77 }
78 78 }
79 79
80 void prev()
81 {
82 for (auto &it : m_Its) {
83 --it;
84 }
85 }
86
80 87 bool operator==(const IteratorValue &other) const { return m_Its == other.m_Its; }
81 88
82 89 private:
83 90 std::vector<DataContainer::value_type::const_iterator> m_Its;
84 91 };
85 92
86 93 class Iterator {
87 94 public:
88 95 using iterator_category = std::forward_iterator_tag;
89 96 using value_type = const IteratorValue;
90 97 using difference_type = std::ptrdiff_t;
91 98 using pointer = value_type *;
92 99 using reference = value_type &;
93 100
94 101 Iterator(const DataContainer &container, bool begin) : m_CurrentValue{container, begin} {}
95 102
96 103 virtual ~Iterator() noexcept = default;
97 104 Iterator(const Iterator &) = default;
98 105 Iterator(Iterator &&) = default;
99 106 Iterator &operator=(const Iterator &) = default;
100 107 Iterator &operator=(Iterator &&) = default;
101 108
102 109 Iterator &operator++()
103 110 {
104 111 m_CurrentValue.next();
105 112 return *this;
106 113 }
107 114
115 Iterator &operator--()
116 {
117 m_CurrentValue.prev();
118 return *this;
119 }
120
108 121 pointer operator->() const { return &m_CurrentValue; }
109 122 reference operator*() const { return m_CurrentValue; }
110 123
111 124 bool operator==(const Iterator &other) const
112 125 {
113 126 return m_CurrentValue == other.m_CurrentValue;
114 127 }
115 128
116 129 bool operator!=(const Iterator &other) const { return !(*this == other); }
117 130
118 131 private:
119 132 IteratorValue m_CurrentValue;
120 133 };
121 134
122 135 // ///// //
123 136 // Ctors //
124 137 // ///// //
125 138
126 139 /**
127 140 * Ctor for a unidimensional ArrayData
128 141 * @param data the data the ArrayData will hold
129 142 */
130 143 template <int D = Dim, typename = std::enable_if_t<D == 1> >
131 144 explicit ArrayData(QVector<double> data) : m_Data{1, QVector<double>{}}
132 145 {
133 146 m_Data[0] = std::move(data);
134 147 }
135 148
136 149 /**
137 150 * Ctor for a two-dimensional ArrayData. The number of components (number of vectors) must be
138 151 * greater than 2 and each component must have the same number of values
139 152 * @param data the data the ArrayData will hold
140 153 * @throws std::invalid_argument if the number of components is less than 2
141 154 * @remarks if the number of values is not the same for each component, no value is set
142 155 */
143 156 template <int D = Dim, typename = std::enable_if_t<D == 2> >
144 157 explicit ArrayData(DataContainer data)
145 158 {
146 159 auto nbComponents = data.size();
147 160 if (nbComponents < 2) {
148 161 throw std::invalid_argument{
149 162 QString{"A multidimensional ArrayData must have at least 2 components (found: %1"}
150 163 .arg(data.size())
151 164 .toStdString()};
152 165 }
153 166
154 167 auto nbValues = data.front().size();
155 168 if (std::all_of(data.cbegin(), data.cend(), [nbValues](const auto &component) {
156 169 return component.size() == nbValues;
157 170 })) {
158 171 m_Data = std::move(data);
159 172 }
160 173 else {
161 174 m_Data = DataContainer{nbComponents, QVector<double>{}};
162 175 }
163 176 }
164 177
165 178 /// Copy ctor
166 179 explicit ArrayData(const ArrayData &other)
167 180 {
168 181 QReadLocker otherLocker{&other.m_Lock};
169 182 m_Data = other.m_Data;
170 183 }
171 184
172 185 // /////////////// //
173 186 // General methods //
174 187 // /////////////// //
175 188
176 189 /**
177 190 * Merges into the array data an other array data. The two array datas must have the same number
178 191 * of components so the merge can be done
179 192 * @param other the array data to merge with
180 193 * @param prepend if true, the other array data is inserted at the beginning, otherwise it is
181 194 * inserted at the end
182 195 */
183 196 void add(const ArrayData<Dim> &other, bool prepend = false)
184 197 {
185 198 QWriteLocker locker{&m_Lock};
186 199 QReadLocker otherLocker{&other.m_Lock};
187 200
188 201 auto nbComponents = m_Data.size();
189 202 if (nbComponents != other.m_Data.size()) {
190 203 return;
191 204 }
192 205
193 206 for (auto componentIndex = 0; componentIndex < nbComponents; ++componentIndex) {
194 207 if (prepend) {
195 208 const auto &otherData = other.data(componentIndex);
196 209 const auto otherDataSize = otherData.size();
197 210
198 211 auto &data = m_Data[componentIndex];
199 212 data.insert(data.begin(), otherDataSize, 0.);
200 213
201 214 for (auto i = 0; i < otherDataSize; ++i) {
202 215 data.replace(i, otherData.at(i));
203 216 }
204 217 }
205 218 else {
206 219 m_Data[componentIndex] += other.data(componentIndex);
207 220 }
208 221 }
209 222 }
210 223
211 224 void clear()
212 225 {
213 226 QWriteLocker locker{&m_Lock};
214 227
215 228 auto nbComponents = m_Data.size();
216 229 for (auto i = 0; i < nbComponents; ++i) {
217 230 m_Data[i].clear();
218 231 }
219 232 }
220 233
221 234 int componentCount() const noexcept { return m_Data.size(); }
222 235
223 236 /**
224 237 * @return the data of a component
225 238 * @param componentIndex the index of the component to retrieve the data
226 239 * @return the component's data, empty vector if the index is invalid
227 240 */
228 241 QVector<double> data(int componentIndex) const noexcept
229 242 {
230 243 QReadLocker locker{&m_Lock};
231 244
232 245 return (componentIndex >= 0 && componentIndex < m_Data.size()) ? m_Data.at(componentIndex)
233 246 : QVector<double>{};
234 247 }
235 248
236 249 /// @return the size (i.e. number of values) of a single component
237 250 /// @remarks in a case of a two-dimensional ArrayData, each component has the same size
238 251 int size() const
239 252 {
240 253 QReadLocker locker{&m_Lock};
241 254 return m_Data[0].size();
242 255 }
243 256
244 257 std::shared_ptr<ArrayData<Dim> > sort(const std::vector<int> &sortPermutation)
245 258 {
246 259 QReadLocker locker{&m_Lock};
247 260 return arraydata_detail::Sort<Dim>::sort(m_Data, sortPermutation);
248 261 }
249 262
250 263 // ///////// //
251 264 // Iterators //
252 265 // ///////// //
253 266
254 267 Iterator cbegin() const { return Iterator{m_Data, true}; }
255 268 Iterator cend() const { return Iterator{m_Data, false}; }
256 269
257 270 // ///////////// //
258 271 // 1-dim methods //
259 272 // ///////////// //
260 273
261 274 /**
262 275 * @return the data at a specified index
263 276 * @remarks index must be a valid position
264 277 * @remarks this method is only available for a unidimensional ArrayData
265 278 */
266 279 template <int D = Dim, typename = std::enable_if_t<D == 1> >
267 280 double at(int index) const noexcept
268 281 {
269 282 QReadLocker locker{&m_Lock};
270 283 return m_Data[0].at(index);
271 284 }
272 285
273 286 /**
274 287 * @return the data as a vector, as a const reference
275 288 * @remarks this method is only available for a unidimensional ArrayData
276 289 */
277 290 template <int D = Dim, typename = std::enable_if_t<D == 1> >
278 291 const QVector<double> &cdata() const noexcept
279 292 {
280 293 QReadLocker locker{&m_Lock};
281 294 return m_Data.at(0);
282 295 }
283 296
284 297 /**
285 298 * @return the data as a vector
286 299 * @remarks this method is only available for a unidimensional ArrayData
287 300 */
288 301 template <int D = Dim, typename = std::enable_if_t<D == 1> >
289 302 QVector<double> data() const noexcept
290 303 {
291 304 QReadLocker locker{&m_Lock};
292 305 return m_Data[0];
293 306 }
294 307
295 308 // ///////////// //
296 309 // 2-dim methods //
297 310 // ///////////// //
298 311
299 312 /**
300 313 * @return the data
301 314 * @remarks this method is only available for a two-dimensional ArrayData
302 315 */
303 316 template <int D = Dim, typename = std::enable_if_t<D == 2> >
304 317 DataContainer data() const noexcept
305 318 {
306 319 QReadLocker locker{&m_Lock};
307 320 return m_Data;
308 321 }
309 322
310 323 private:
311 324 DataContainer m_Data;
312 325 mutable QReadWriteLock m_Lock;
313 326 };
314 327
315 328 #endif // SCIQLOP_ARRAYDATA_H
@@ -1,287 +1,287
1 1 #ifndef SCIQLOP_DATASERIES_H
2 2 #define SCIQLOP_DATASERIES_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Common/SortUtils.h>
7 7
8 8 #include <Data/ArrayData.h>
9 9 #include <Data/IDataSeries.h>
10 10
11 11 #include <QLoggingCategory>
12 12 #include <QReadLocker>
13 13 #include <QReadWriteLock>
14 14 #include <memory>
15 15
16 16 // We don't use the Qt macro since the log is used in the header file, which causes multiple log
17 17 // definitions with inheritance. Inline method is used instead
18 18 inline const QLoggingCategory &LOG_DataSeries()
19 19 {
20 20 static const QLoggingCategory category{"DataSeries"};
21 21 return category;
22 22 }
23 23
24 24 template <int Dim>
25 25 class DataSeries;
26 26
27 27 namespace dataseries_detail {
28 28
29 29 template <int Dim>
30 30 class IteratorValue : public DataSeriesIteratorValue::Impl {
31 31 public:
32 32 explicit IteratorValue(const DataSeries<Dim> &dataSeries, bool begin)
33 33 : m_XIt(begin ? dataSeries.xAxisData()->cbegin() : dataSeries.xAxisData()->cend()),
34 34 m_ValuesIt(begin ? dataSeries.valuesData()->cbegin()
35 35 : dataSeries.valuesData()->cend())
36 36 {
37 37 }
38 38 IteratorValue(const IteratorValue &other) = default;
39 39
40 40 std::unique_ptr<DataSeriesIteratorValue::Impl> clone() const override
41 41 {
42 42 return std::make_unique<IteratorValue<Dim> >(*this);
43 43 }
44 44
45 45 bool equals(const DataSeriesIteratorValue::Impl &other) const override try {
46 46 const auto &otherImpl = dynamic_cast<const IteratorValue &>(other);
47 47 return std::tie(m_XIt, m_ValuesIt) == std::tie(otherImpl.m_XIt, otherImpl.m_ValuesIt);
48 48 }
49 49 catch (const std::bad_cast &) {
50 50 return false;
51 51 }
52 52
53 53 void next() override
54 54 {
55 55 ++m_XIt;
56 56 ++m_ValuesIt;
57 57 }
58 58
59 59 void prev() override
60 60 {
61 61 --m_XIt;
62 62 --m_ValuesIt;
63 63 }
64 64
65 65 double x() const override { return m_XIt->at(0); }
66 66 double value() const override { return m_ValuesIt->at(0); }
67 67 double value(int componentIndex) const override { return m_ValuesIt->at(componentIndex); }
68 68
69 69 private:
70 70 ArrayData<1>::Iterator m_XIt;
71 71 typename ArrayData<Dim>::Iterator m_ValuesIt;
72 72 };
73 73 } // namespace dataseries_detail
74 74
75 75 /**
76 76 * @brief The DataSeries class is the base (abstract) implementation of IDataSeries.
77 77 *
78 78 * It proposes to set a dimension for the values ​​data.
79 79 *
80 80 * A DataSeries is always sorted on its x-axis data.
81 81 *
82 82 * @tparam Dim The dimension of the values data
83 83 *
84 84 */
85 85 template <int Dim>
86 86 class SCIQLOP_CORE_EXPORT DataSeries : public IDataSeries {
87 87 public:
88 88 /// @sa IDataSeries::xAxisData()
89 89 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
90 90 const std::shared_ptr<ArrayData<1> > xAxisData() const { return m_XAxisData; }
91 91
92 92 /// @sa IDataSeries::xAxisUnit()
93 93 Unit xAxisUnit() const override { return m_XAxisUnit; }
94 94
95 95 /// @return the values dataset
96 96 std::shared_ptr<ArrayData<Dim> > valuesData() { return m_ValuesData; }
97 97 const std::shared_ptr<ArrayData<Dim> > valuesData() const { return m_ValuesData; }
98 98
99 99 /// @sa IDataSeries::valuesUnit()
100 100 Unit valuesUnit() const override { return m_ValuesUnit; }
101 101
102 102
103 103 SqpRange range() const override
104 104 {
105 105 if (!m_XAxisData->cdata().isEmpty()) {
106 106 return SqpRange{m_XAxisData->cdata().first(), m_XAxisData->cdata().last()};
107 107 }
108 108
109 109 return SqpRange{};
110 110 }
111 111
112 112 void clear()
113 113 {
114 114 m_XAxisData->clear();
115 115 m_ValuesData->clear();
116 116 }
117 117
118 118 /// Merges into the data series an other data series
119 119 /// @remarks the data series to merge with is cleared after the operation
120 120 void merge(IDataSeries *dataSeries) override
121 121 {
122 122 dataSeries->lockWrite();
123 123 lockWrite();
124 124
125 125 if (auto other = dynamic_cast<DataSeries<Dim> *>(dataSeries)) {
126 126 const auto &otherXAxisData = other->xAxisData()->cdata();
127 127 const auto &xAxisData = m_XAxisData->cdata();
128 128
129 129 // As data series are sorted, we can improve performances of merge, by call the sort
130 130 // method only if the two data series overlap.
131 131 if (!otherXAxisData.empty()) {
132 132 auto firstValue = otherXAxisData.front();
133 133 auto lastValue = otherXAxisData.back();
134 134
135 135 auto xAxisDataBegin = xAxisData.cbegin();
136 136 auto xAxisDataEnd = xAxisData.cend();
137 137
138 138 bool prepend;
139 139 bool sortNeeded;
140 140
141 141 if (std::lower_bound(xAxisDataBegin, xAxisDataEnd, firstValue) == xAxisDataEnd) {
142 142 // Other data series if after data series
143 143 prepend = false;
144 144 sortNeeded = false;
145 145 }
146 146 else if (std::upper_bound(xAxisDataBegin, xAxisDataEnd, lastValue)
147 147 == xAxisDataBegin) {
148 148 // Other data series if before data series
149 149 prepend = true;
150 150 sortNeeded = false;
151 151 }
152 152 else {
153 153 // The two data series overlap
154 154 prepend = false;
155 155 sortNeeded = true;
156 156 }
157 157
158 158 // Makes the merge
159 159 m_XAxisData->add(*other->xAxisData(), prepend);
160 160 m_ValuesData->add(*other->valuesData(), prepend);
161 161
162 162 if (sortNeeded) {
163 163 sort();
164 164 }
165 165 }
166 166
167 167 // Clears the other data series
168 168 other->clear();
169 169 }
170 170 else {
171 171 qCWarning(LOG_DataSeries())
172 172 << QObject::tr("Detection of a type of IDataSeries we cannot merge with !");
173 173 }
174 174 unlock();
175 175 dataSeries->unlock();
176 176 }
177 177
178 178 // ///////// //
179 179 // Iterators //
180 180 // ///////// //
181 181
182 182 DataSeriesIterator cbegin() const override
183 183 {
184 184 return DataSeriesIterator{DataSeriesIteratorValue{
185 185 std::make_unique<dataseries_detail::IteratorValue<Dim> >(*this, true)}};
186 186 }
187 187
188 188 DataSeriesIterator cend() const override
189 189 {
190 190 return DataSeriesIterator{DataSeriesIteratorValue{
191 191 std::make_unique<dataseries_detail::IteratorValue<Dim> >(*this, false)}};
192 192 }
193 193
194 std::pair<Iterator, Iterator> subData(double min, double max) const
194 std::pair<DataSeriesIterator, DataSeriesIterator> subData(double min, double max) const override
195 195 {
196 196 if (min > max) {
197 197 std::swap(min, max);
198 198 }
199 199
200 200 auto begin = cbegin();
201 201 auto end = cend();
202 202
203 203 auto lowerIt
204 204 = std::lower_bound(begin, end, min, [](const auto &itValue, const auto &value) {
205 205 return itValue.x() < value;
206 206 });
207 207 auto upperIt
208 208 = std::upper_bound(begin, end, max, [](const auto &value, const auto &itValue) {
209 209 return value < itValue.x();
210 210 });
211 211
212 212 return std::make_pair(lowerIt, upperIt);
213 213 }
214 214
215 215 // /////// //
216 216 // Mutexes //
217 217 // /////// //
218 218
219 219 virtual void lockRead() { m_Lock.lockForRead(); }
220 220 virtual void lockWrite() { m_Lock.lockForWrite(); }
221 221 virtual void unlock() { m_Lock.unlock(); }
222 222
223 223 protected:
224 224 /// Protected ctor (DataSeries is abstract). The vectors must have the same size, otherwise a
225 225 /// DataSeries with no values will be created.
226 226 /// @remarks data series is automatically sorted on its x-axis data
227 227 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const Unit &xAxisUnit,
228 228 std::shared_ptr<ArrayData<Dim> > valuesData, const Unit &valuesUnit)
229 229 : m_XAxisData{xAxisData},
230 230 m_XAxisUnit{xAxisUnit},
231 231 m_ValuesData{valuesData},
232 232 m_ValuesUnit{valuesUnit}
233 233 {
234 234 if (m_XAxisData->size() != m_ValuesData->size()) {
235 235 clear();
236 236 }
237 237
238 238 // Sorts data if it's not the case
239 239 const auto &xAxisCData = m_XAxisData->cdata();
240 240 if (!std::is_sorted(xAxisCData.cbegin(), xAxisCData.cend())) {
241 241 sort();
242 242 }
243 243 }
244 244
245 245 /// Copy ctor
246 246 explicit DataSeries(const DataSeries<Dim> &other)
247 247 : m_XAxisData{std::make_shared<ArrayData<1> >(*other.m_XAxisData)},
248 248 m_XAxisUnit{other.m_XAxisUnit},
249 249 m_ValuesData{std::make_shared<ArrayData<Dim> >(*other.m_ValuesData)},
250 250 m_ValuesUnit{other.m_ValuesUnit}
251 251 {
252 252 // Since a series is ordered from its construction and is always ordered, it is not
253 253 // necessary to call the sort method here ('other' is sorted)
254 254 }
255 255
256 256 /// Assignment operator
257 257 template <int D>
258 258 DataSeries &operator=(DataSeries<D> other)
259 259 {
260 260 std::swap(m_XAxisData, other.m_XAxisData);
261 261 std::swap(m_XAxisUnit, other.m_XAxisUnit);
262 262 std::swap(m_ValuesData, other.m_ValuesData);
263 263 std::swap(m_ValuesUnit, other.m_ValuesUnit);
264 264
265 265 return *this;
266 266 }
267 267
268 268 private:
269 269 /**
270 270 * Sorts data series on its x-axis data
271 271 */
272 272 void sort() noexcept
273 273 {
274 274 auto permutation = SortUtils::sortPermutation(*m_XAxisData, std::less<double>());
275 275 m_XAxisData = m_XAxisData->sort(permutation);
276 276 m_ValuesData = m_ValuesData->sort(permutation);
277 277 }
278 278
279 279 std::shared_ptr<ArrayData<1> > m_XAxisData;
280 280 Unit m_XAxisUnit;
281 281 std::shared_ptr<ArrayData<Dim> > m_ValuesData;
282 282 Unit m_ValuesUnit;
283 283
284 284 QReadWriteLock m_Lock;
285 285 };
286 286
287 287 #endif // SCIQLOP_DATASERIES_H
@@ -1,73 +1,88
1 1 #ifndef SCIQLOP_IDATASERIES_H
2 2 #define SCIQLOP_IDATASERIES_H
3 3
4 4 #include <Common/MetaTypes.h>
5 #include <Data/DataSeriesIterator.h>
5 6 #include <Data/SqpRange.h>
6 7
7 8 #include <memory>
8 9
9 10 #include <QString>
10 11
11 12 template <int Dim>
12 13 class ArrayData;
13 14
14 15 struct Unit {
15 16 explicit Unit(const QString &name = {}, bool timeUnit = false)
16 17 : m_Name{name}, m_TimeUnit{timeUnit}
17 18 {
18 19 }
19 20
20 21 inline bool operator==(const Unit &other) const
21 22 {
22 23 return std::tie(m_Name, m_TimeUnit) == std::tie(other.m_Name, other.m_TimeUnit);
23 24 }
24 25 inline bool operator!=(const Unit &other) const { return !(*this == other); }
25 26
26 27 QString m_Name; ///< Unit name
27 28 bool m_TimeUnit; ///< The unit is a unit of time (UTC)
28 29 };
29 30
30 31 /**
31 32 * @brief The IDataSeries aims to declare a data series.
32 33 *
33 34 * A data series is an entity that contains at least :
34 35 * - one dataset representing the x-axis
35 36 * - one dataset representing the values
36 37 *
37 38 * Each dataset is represented by an ArrayData, and is associated with a unit.
38 39 *
39 40 * An ArrayData can be unidimensional or two-dimensional, depending on the implementation of the
40 41 * IDataSeries. The x-axis dataset is always unidimensional.
41 42 *
42 43 * @sa ArrayData
43 44 */
44 45 class IDataSeries {
45 46 public:
46 47 virtual ~IDataSeries() noexcept = default;
47 48
48 49 /// Returns the x-axis dataset
49 50 virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0;
50 51
51 52 /// Returns the x-axis dataset (as const)
52 53 virtual const std::shared_ptr<ArrayData<1> > xAxisData() const = 0;
53 54
54 55 virtual Unit xAxisUnit() const = 0;
55 56
56 57 virtual Unit valuesUnit() const = 0;
57 58
58 59 virtual void merge(IDataSeries *dataSeries) = 0;
59 60 /// @todo Review the name and signature of this method
60 61 virtual std::shared_ptr<IDataSeries> subDataSeries(const SqpRange &range) = 0;
61 62
62 63 virtual std::unique_ptr<IDataSeries> clone() const = 0;
63 64 virtual SqpRange range() const = 0;
64 65
66 // ///////// //
67 // Iterators //
68 // ///////// //
69
70 virtual DataSeriesIterator cbegin() const = 0;
71 virtual DataSeriesIterator cend() const = 0;
72
73 virtual std::pair<DataSeriesIterator, DataSeriesIterator> subData(double min,
74 double max) const = 0;
75
76 // /////// //
77 // Mutexes //
78 // /////// //
79
65 80 virtual void lockRead() = 0;
66 81 virtual void lockWrite() = 0;
67 82 virtual void unlock() = 0;
68 83 };
69 84
70 85 // Required for using shared_ptr in signals/slots
71 86 SCIQLOP_REGISTER_META_TYPE(IDATASERIES_PTR_REGISTRY, std::shared_ptr<IDataSeries>)
72 87
73 88 #endif // SCIQLOP_IDATASERIES_H
General Comments 0
You need to be logged in to leave comments. Login now