From 51ba6398bb6014a17e5d6252fb31abdda2f7abf9 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 2 Feb 2018 20:41:41 +0100 Subject: [PATCH] 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 --- src/blackmisc/aviation/aircraftpartslist.cpp | 1 - src/blackmisc/aviation/aircraftpartslist.h | 2 +- .../aviation/aircraftsituationlist.cpp | 1 - .../aviation/aircraftsituationlist.h | 2 +- src/blackmisc/sequence.h | 14 +++ src/blackmisc/timestampbased.cpp | 5 + src/blackmisc/timestampbased.h | 3 + src/blackmisc/timestampobjectlist.cpp | 116 ++++++++++++++++-- src/blackmisc/timestampobjectlist.h | 43 ++++++- 9 files changed, 170 insertions(+), 17 deletions(-) diff --git a/src/blackmisc/aviation/aircraftpartslist.cpp b/src/blackmisc/aviation/aircraftpartslist.cpp index fbd761d46..44c11423f 100644 --- a/src/blackmisc/aviation/aircraftpartslist.cpp +++ b/src/blackmisc/aviation/aircraftpartslist.cpp @@ -25,6 +25,5 @@ namespace BlackMisc CAircraftPartsList::CAircraftPartsList(std::initializer_list il) : CSequence(il) { } - } // namespace } // namespace diff --git a/src/blackmisc/aviation/aircraftpartslist.h b/src/blackmisc/aviation/aircraftpartslist.h index f8011d589..80f31582c 100644 --- a/src/blackmisc/aviation/aircraftpartslist.h +++ b/src/blackmisc/aviation/aircraftpartslist.h @@ -28,7 +28,7 @@ namespace BlackMisc //! Value object encapsulating a list of aircraft parts. class BLACKMISC_EXPORT CAircraftPartsList : public CSequence, - public ITimestampObjectList, + public ITimestampWithOffsetObjectList, public BlackMisc::Mixin::MetaType { public: diff --git a/src/blackmisc/aviation/aircraftsituationlist.cpp b/src/blackmisc/aviation/aircraftsituationlist.cpp index 20bc90b0c..c161d1000 100644 --- a/src/blackmisc/aviation/aircraftsituationlist.cpp +++ b/src/blackmisc/aviation/aircraftsituationlist.cpp @@ -10,7 +10,6 @@ #include "blackmisc/aviation/aircraftsituationlist.h" #include "blackmisc/aviation/aircraftsituation.h" #include "blackmisc/geo/elevationplane.h" - #include using namespace BlackMisc::PhysicalQuantities; diff --git a/src/blackmisc/aviation/aircraftsituationlist.h b/src/blackmisc/aviation/aircraftsituationlist.h index 4ef7ec834..1426db31d 100644 --- a/src/blackmisc/aviation/aircraftsituationlist.h +++ b/src/blackmisc/aviation/aircraftsituationlist.h @@ -33,7 +33,7 @@ namespace BlackMisc //! Value object encapsulating a list of aircraft situations class BLACKMISC_EXPORT CAircraftSituationList : public CSequence, - public ITimestampObjectList, + public ITimestampWithOffsetObjectList, public ICallsignObjectList, public Mixin::MetaType { diff --git a/src/blackmisc/sequence.h b/src/blackmisc/sequence.h index a5b41ff22..f48589116 100644 --- a/src/blackmisc/sequence.h +++ b/src/blackmisc/sequence.h @@ -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 void sort(Predicate p) { diff --git a/src/blackmisc/timestampbased.cpp b/src/blackmisc/timestampbased.cpp index 3371ef872..874d2521a 100644 --- a/src/blackmisc/timestampbased.cpp +++ b/src/blackmisc/timestampbased.cpp @@ -290,6 +290,11 @@ namespace BlackMisc return (i >= static_cast(IndexOffsetMs)) && (i <= static_cast(IndexOffsetWithUnit)); } + bool ITimestampWithOffsetBased::hasOffsetTime() const + { + return m_timeOffsetMs != 0; + } + QString ITimestampWithOffsetBased::getTimeOffsetWithUnit() const { static const QString os("%1ms"); diff --git a/src/blackmisc/timestampbased.h b/src/blackmisc/timestampbased.h index 2c9e5977a..4f87a5d78 100644 --- a/src/blackmisc/timestampbased.h +++ b/src/blackmisc/timestampbased.h @@ -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; diff --git a/src/blackmisc/timestampobjectlist.cpp b/src/blackmisc/timestampobjectlist.cpp index 85d2541fd..1eb669849 100644 --- a/src/blackmisc/timestampobjectlist.cpp +++ b/src/blackmisc/timestampobjectlist.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -216,7 +217,7 @@ namespace BlackMisc void ITimestampObjectList::sortLatestFirst() { this->container().sortOldestFirst(); - std::reverse(this->container().begin(), this->container().end()); + this->container().reverse(); } template @@ -225,15 +226,111 @@ namespace BlackMisc this->container().sort(BlackMisc::Predicates::MemberLess(&OBJ::getMSecsSinceEpoch)); } - template - void ITimestampObjectList::push_frontMaxElements(const OBJ &object, int maxElements) + template + void ITimestampObjectList::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 + bool ITimestampObjectList::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 + bool ITimestampObjectList::isSortedLatestFirst() const + { + if (this->container().isEmpty()) { return true; } + qint64 min = std::numeric_limits ::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 + void ITimestampWithOffsetObjectList::sortAdjustedLatestFirst() + { + this->container().sortAdjustedOldestFirst(); + this->container().reverse(); + } + + template + void ITimestampWithOffsetObjectList::sortAdjustedOldestFirst() + { + this->container().sort(Predicates::MemberLess(&OBJ::getAdjustedMSecsSinceEpoch)); + } + + template + ITimestampWithOffsetObjectList::ITimestampWithOffsetObjectList() : ITimestampObjectList() + { + static_assert(std::is_base_of::value, "OBJ needs to implement ITimestampBased"); + } + + template + void ITimestampWithOffsetObjectList::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 + bool ITimestampWithOffsetObjectList::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 + bool ITimestampWithOffsetObjectList::isSortedAdjustedLatestFirst() const + { + if (this->container().isEmpty()) { return true; } + qint64 min = std::numeric_limits ::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; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; - template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; - template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; @@ -256,6 +351,9 @@ namespace BlackMisc template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampObjectList; + + template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampWithOffsetObjectList; + template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ITimestampWithOffsetObjectList; //! \endcond } // namespace diff --git a/src/blackmisc/timestampobjectlist.h b/src/blackmisc/timestampobjectlist.h index cf1dbf2ae..9dee725dd 100644 --- a/src/blackmisc/timestampobjectlist.h +++ b/src/blackmisc/timestampobjectlist.h @@ -12,6 +12,7 @@ #ifndef BLACKMISC_TIMESTAMPOBJECTLIST_H #define BLACKMISC_TIMESTAMPOBJECTLIST_H +#include "blackmisc/timestampbased.h" #include "blackmisc/blackmiscexport.h" #include #include @@ -22,8 +23,7 @@ namespace BlackMisc { //! List of objects with timestamp. //! Such objects should implement \sa ITimestampBased - template - class ITimestampObjectList + template 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 ITimestampWithOffsetObjectList : public ITimestampObjectList + { + 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 {