Ref T241, Ref T243, ITimestampWithOffsetObjectList

* there was already ITimestampWithOffsetBased for objects
* this creates the container version
* functions to add objects (parts/situations) and guarantee the sort order
* moved push_frontMaxElements to CSequence (not specific for timestamp lists)
* added in-place reverse
This commit is contained in:
Klaus Basan
2018-02-02 20:41:41 +01:00
parent e9e0ae1ff4
commit 51ba6398bb
9 changed files with 170 additions and 17 deletions

View File

@@ -25,6 +25,5 @@ namespace BlackMisc
CAircraftPartsList::CAircraftPartsList(std::initializer_list<CAircraftParts> il) :
CSequence<CAircraftParts>(il)
{ }
} // namespace
} // namespace

View File

@@ -28,7 +28,7 @@ namespace BlackMisc
//! Value object encapsulating a list of aircraft parts.
class BLACKMISC_EXPORT CAircraftPartsList :
public CSequence<CAircraftParts>,
public ITimestampObjectList<CAircraftParts, CAircraftPartsList>,
public ITimestampWithOffsetObjectList<CAircraftParts, CAircraftPartsList>,
public BlackMisc::Mixin::MetaType<CAircraftPartsList>
{
public:

View File

@@ -10,7 +10,6 @@
#include "blackmisc/aviation/aircraftsituationlist.h"
#include "blackmisc/aviation/aircraftsituation.h"
#include "blackmisc/geo/elevationplane.h"
#include <tuple>
using namespace BlackMisc::PhysicalQuantities;

View File

@@ -33,7 +33,7 @@ namespace BlackMisc
//! Value object encapsulating a list of aircraft situations
class BLACKMISC_EXPORT CAircraftSituationList :
public CSequence<CAircraftSituation>,
public ITimestampObjectList<CAircraftSituation, CAircraftSituationList>,
public ITimestampWithOffsetObjectList<CAircraftSituation, CAircraftSituationList>,
public ICallsignObjectList<CAircraftSituation, CAircraftSituationList>,
public Mixin::MetaType<CAircraftSituationList>
{

View File

@@ -178,6 +178,14 @@ namespace BlackMisc
//! Insert as first element.
void push_front(const T &value) { insert(begin(), value); }
//! Insert as first element by keep maxElements
void push_frontMaxElements(const T &value, int maxElements)
{
Q_ASSERT(maxElements > 1);
if (this->size() >= (maxElements - 1)) { this->truncate(maxElements - 1); }
this->push_front(value);
}
//! Move-appends an element at the end of the sequence.
void push_back(T &&value) { m_impl.push_back(std::move(value)); }
@@ -376,6 +384,12 @@ namespace BlackMisc
else { push_back(replacement); }
}
//! In-place reverse
void reverse()
{
std::reverse(begin(), end());
}
//! In-place sort by a given comparator predicate.
template <class Predicate> void sort(Predicate p)
{

View File

@@ -290,6 +290,11 @@ namespace BlackMisc
return (i >= static_cast<int>(IndexOffsetMs)) && (i <= static_cast<int>(IndexOffsetWithUnit));
}
bool ITimestampWithOffsetBased::hasOffsetTime() const
{
return m_timeOffsetMs != 0;
}
QString ITimestampWithOffsetBased::getTimeOffsetWithUnit() const
{
static const QString os("%1ms");

View File

@@ -161,6 +161,9 @@ namespace BlackMisc
//! Milliseconds to add to timestamp for interpolation
qint64 getTimeOffsetMs() const { return m_timeOffsetMs; }
//! Having a valid offset time
bool hasOffsetTime() const;
//! Offset with unit
QString getTimeOffsetWithUnit() const;

View File

@@ -33,6 +33,7 @@
#include <QDateTime>
#include <algorithm>
#include <limits>
#include <iterator>
#include <type_traits>
@@ -216,7 +217,7 @@ namespace BlackMisc
void ITimestampObjectList<OBJ, CONTAINER>::sortLatestFirst()
{
this->container().sortOldestFirst();
std::reverse(this->container().begin(), this->container().end());
this->container().reverse();
}
template <class OBJ, class CONTAINER>
@@ -225,15 +226,111 @@ namespace BlackMisc
this->container().sort(BlackMisc::Predicates::MemberLess(&OBJ::getMSecsSinceEpoch));
}
template <class OBJ, class CONTAINER>
void ITimestampObjectList<OBJ, CONTAINER>::push_frontMaxElements(const OBJ &object, int maxElements)
template<class OBJ, class CONTAINER>
void ITimestampObjectList<OBJ, CONTAINER>::push_frontKeepLatestFirst(const OBJ &value, int maxElements)
{
Q_ASSERT(maxElements > 1);
if (this->container().size() >= (maxElements - 1))
Q_ASSERT_X(maxElements < 0 || maxElements > 1, Q_FUNC_INFO, "Max.value wrong range");
CONTAINER &c = this->container();
if (!c.isEmpty() && value.isOlderThan(c.front()))
{
this->container().truncate(maxElements - 1);
ITimestampObjectList::sortLatestFirst();
}
this->container().push_front(object);
c.push_front(value);
if (maxElements < 0 || maxElements <= c.size()) { return; }
c.truncate(maxElements);
}
template<class OBJ, class CONTAINER>
bool ITimestampObjectList<OBJ, CONTAINER>::isSortedLatestLast() const
{
if (this->container().isEmpty()) { return true; }
qint64 max = -1;
for (const ITimestampBased &obj : this->container())
{
if (!obj.hasValidTimestamp()) { return false; }
if (obj.getMSecsSinceEpoch() < max) { return false; }
max = obj.getMSecsSinceEpoch();
continue;
}
return true;
}
template<class OBJ, class CONTAINER>
bool ITimestampObjectList<OBJ, CONTAINER>::isSortedLatestFirst() const
{
if (this->container().isEmpty()) { return true; }
qint64 min = std::numeric_limits <qint64>::max();
for (const ITimestampBased &obj : this->container())
{
if (!obj.hasValidTimestamp()) { return false; }
if (obj.getMSecsSinceEpoch() > min) { return false; }
min = obj.getMSecsSinceEpoch();
continue;
}
return true;
}
template <class OBJ, class CONTAINER>
void ITimestampWithOffsetObjectList<OBJ, CONTAINER>::sortAdjustedLatestFirst()
{
this->container().sortAdjustedOldestFirst();
this->container().reverse();
}
template<class OBJ, class CONTAINER>
void ITimestampWithOffsetObjectList<OBJ, CONTAINER>::sortAdjustedOldestFirst()
{
this->container().sort(Predicates::MemberLess(&OBJ::getAdjustedMSecsSinceEpoch));
}
template<class OBJ, class CONTAINER>
ITimestampWithOffsetObjectList<OBJ, CONTAINER>::ITimestampWithOffsetObjectList() : ITimestampObjectList<OBJ, CONTAINER>()
{
static_assert(std::is_base_of<ITimestampWithOffsetBased, OBJ>::value, "OBJ needs to implement ITimestampBased");
}
template<class OBJ, class CONTAINER>
void ITimestampWithOffsetObjectList<OBJ, CONTAINER>::push_frontKeepLatestAdjustedFirst(const OBJ &value, int maxElements)
{
Q_ASSERT_X(maxElements < 0 || maxElements > 1, Q_FUNC_INFO, "Max.value wrong range");
CONTAINER &c = this->container();
if (!c.isEmpty() && value.isOlderThan(c.front()))
{
ITimestampWithOffsetObjectList::sortAdjustedLatestFirst();
}
c.push_front(value);
if (maxElements < 0 || maxElements <= c.size()) { return; }
c.truncate(maxElements);
}
template<class OBJ, class CONTAINER>
bool ITimestampWithOffsetObjectList<OBJ, CONTAINER>::isSortedAdjustedLatestLast() const
{
if (this->container().isEmpty()) { return true; }
qint64 max = -1;
for (const ITimestampWithOffsetBased &obj : this->container())
{
if (!obj.hasValidTimestamp()) { return false; }
if (obj.getAdjustedMSecsSinceEpoch() < max) { return false; }
max = obj.getAdjustedMSecsSinceEpoch();
continue;
}
return true;
}
template<class OBJ, class CONTAINER>
bool ITimestampWithOffsetObjectList<OBJ, CONTAINER>::isSortedAdjustedLatestFirst() const
{
if (this->container().isEmpty()) { return true; }
qint64 min = std::numeric_limits <qint64>::max();
for (const ITimestampWithOffsetBased &obj : this->container())
{
if (!obj.hasValidTimestamp()) { return false; }
if (obj.getAdjustedMSecsSinceEpoch() > min) { return false; }
min = obj.getAdjustedMSecsSinceEpoch();
continue;
}
return true;
}
// see here for the reason of thess forward instantiations
@@ -243,8 +340,6 @@ namespace BlackMisc
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::CIdentifier, BlackMisc::CIdentifierList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::CStatusMessage, BlackMisc::CStatusMessageList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Aviation::CAircraftIcaoCode, BlackMisc::Aviation::CAircraftIcaoCodeList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Aviation::CAircraftParts, BlackMisc::Aviation::CAircraftPartsList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Aviation::CAircraftSituation, BlackMisc::Aviation::CAircraftSituationList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Aviation::CAirlineIcaoCode, BlackMisc::Aviation::CAirlineIcaoCodeList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Aviation::CAirport, BlackMisc::Aviation::CAirportList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Aviation::CLivery, BlackMisc::Aviation::CLiveryList>;
@@ -256,6 +351,9 @@ namespace BlackMisc
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList<BlackMisc::Simulation::CMatchingStatisticsEntry, BlackMisc::Simulation::CMatchingStatistics>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampWithOffsetObjectList<BlackMisc::Aviation::CAircraftParts, BlackMisc::Aviation::CAircraftPartsList>;
template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampWithOffsetObjectList<BlackMisc::Aviation::CAircraftSituation, BlackMisc::Aviation::CAircraftSituationList>;
//! \endcond
} // namespace

View File

@@ -12,6 +12,7 @@
#ifndef BLACKMISC_TIMESTAMPOBJECTLIST_H
#define BLACKMISC_TIMESTAMPOBJECTLIST_H
#include "blackmisc/timestampbased.h"
#include "blackmisc/blackmiscexport.h"
#include <QList>
#include <QtGlobal>
@@ -22,8 +23,7 @@ namespace BlackMisc
{
//! List of objects with timestamp.
//! Such objects should implement \sa ITimestampBased
template<class OBJ, class CONTAINER>
class ITimestampObjectList
template<class OBJ, class CONTAINER> class ITimestampObjectList
{
public:
//! List of objects before dateTime
@@ -92,8 +92,16 @@ namespace BlackMisc
//! Sort by timestamp
void sortOldestFirst();
//! Inserts as first object by keeping max. elements
void push_frontMaxElements(const OBJ &object, int maxElements);
//! Insert as first element by keeping maxElements and the latest first
void push_frontKeepLatestFirst(const OBJ &value, int maxElements = -1);
//! Is completelty sorted: latest last
//! \remark all object must have a valid timestamp
bool isSortedLatestLast() const;
//! Is completelty sorted: latest last
//! \remark all object must have a valid timestamp
bool isSortedLatestFirst() const;
protected:
//! Constructor
@@ -106,6 +114,33 @@ namespace BlackMisc
CONTAINER &container();
};
//! List of objects with timestamp and offset.
//! Such objects should implement \sa ITimestampWithOffsetBased
template<class OBJ, class CONTAINER> class ITimestampWithOffsetObjectList : public ITimestampObjectList<OBJ, CONTAINER>
{
public:
//! Sort by adjusted timestamp
void sortAdjustedLatestFirst();
//! Sort by adjusted timestamp
void sortAdjustedOldestFirst();
//! Insert as first element by keeping maxElements and the latest first
void push_frontKeepLatestAdjustedFirst(const OBJ &value, int maxElements = -1);
//! Is completelty sorted: latest last
//! \remark all object must have a valid timestamp
bool isSortedAdjustedLatestLast() const;
//! Is completelty sorted: latest last
//! \remark all object must have a valid timestamp
bool isSortedAdjustedLatestFirst() const;
protected:
//! Constructor
ITimestampWithOffsetObjectList();
};
//! \cond PRIVATE
namespace Aviation
{