Is there an STL container which size can be limited, where inserting elements keep it sorted and can provide a raw pointer to the data in C++ or can it be built by assembling some stuff from the STL and C++ ?
In fact, I'm receiving real time data (epoch + data), and I noticed that they aren't "always" sent in an increasing order of the epoch.
I only save 1024 data points to plot them with a plotting API, thus, I need a double raw pointer to the data (x => epoch, y => data).
I wrote a class that fills a 1024 double arrays of times and values. After receiving the 1023th data point, the buffer is shifted to receive the next data points.
Adding sorting to the code below, might overcomplicate it, so is there a better way to code it ?
struct TemporalData
{
TemporalData(const unsigned capacity) :
m_timestamps(new double[capacity]),
m_bsl(new double[capacity]),
m_capacity(capacity),
m_size(0),
m_lastPos(capacity - 1)
{
}
TemporalData(TemporalData&& moved) :
m_capacity(moved.m_capacity),
m_lastPos(moved.m_lastPos)
{
m_size = moved.m_size;
m_timestamps = moved.m_timestamps;
moved.m_timestamps = nullptr;
m_bsl = moved.m_bsl;
moved.m_bsl = nullptr;
}
TemporalData(const TemporalData& copied) :
m_capacity(copied.m_capacity),
m_lastPos(copied.m_lastPos)
{
m_size = copied.m_size;
m_timestamps = new double[m_capacity];
m_bsl = new double[m_capacity];
std::copy(copied.m_timestamps, copied.m_timestamps + m_size, m_timestamps);
std::copy(copied.m_bsl, copied.m_bsl + m_size, m_bsl);
}
TemporalData& operator=(const TemporalData& copied) = delete;
TemporalData& operator=(TemporalData&& moved) = delete;
inline void add(const double timestamp, const double bsl)
{
if (m_size >= m_capacity)
{
std::move(m_timestamps + 1, m_timestamps + 1 + m_lastPos, m_timestamps);
std::move(m_bsl + 1, m_bsl + 1 + m_lastPos, m_bsl);
m_timestamps[m_lastPos] = timestamp;
m_bsl[m_lastPos] = bsl;
}
else
{
m_timestamps[m_size] = timestamp;
m_bsl[m_size] = bsl;
++m_size;
}
}
inline void removeDataBefore(const double ptTime)
{
auto itRangeToEraseEnd = std::lower_bound(m_timestamps,
m_timestamps + m_size,
ptTime);
auto timesToEraseCount = itRangeToEraseEnd - m_timestamps;
if (timesToEraseCount > 0)
{
// shift
std::move(m_timestamps + timesToEraseCount, m_timestamps + m_size, m_timestamps);
std::move(m_bsl + timesToEraseCount, m_bsl + m_size, m_bsl);
m_size -= timesToEraseCount;
}
}
inline void clear() { m_size = 0; }
inline double* x() const { return m_timestamps; }
inline double* y() const { return m_bsl; }
inline unsigned size() const { return m_size; }
inline unsigned capacity() const { return m_capacity; }
~TemporalData()
{
delete [] m_timestamps;
delete [] m_bsl;
}
private:
double* m_timestamps; // x axis
double* m_bsl; // y axis
const unsigned m_capacity;
unsigned m_size;
const unsigned m_lastPos;
};