/* Copyright (C) 2015 * swift Project Community / Contributors * * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, * including this file, may be copied, modified, propagated, or distributed except according to the terms * contained in the LICENSE file. */ #include "blackmisc/timestampobjectlist.h" #include "blackmisc/predicates.h" #include "blackmisc/aviation/aircraftsituationlist.h" #include "blackmisc/aviation/aircraftpartslist.h" #include "blackmisc/aviation/liverylist.h" #include "blackmisc/aviation/aircrafticaocodelist.h" #include "blackmisc/aviation/airlineicaocodelist.h" #include "blackmisc/simulation/aircraftmodellist.h" #include "blackmisc/simulation/distributorlist.h" #include "blackmisc/network/textmessage.h" #include "blackmisc/network/textmessagelist.h" #include "blackmisc/statusmessagelist.h" #include "blackmisc/identifierlist.h" #include "blackmisc/countrylist.h" #include #include #include #include namespace BlackMisc { template ITimestampObjectList::ITimestampObjectList() { static_assert(std::is_base_of::value, "OBJ needs to implement ITimestampBased"); } template const CONTAINER &ITimestampObjectList::container() const { return static_cast(*this); } template CONTAINER &ITimestampObjectList::container() { return static_cast(*this); } template CONTAINER ITimestampObjectList::findBefore(qint64 msSinceEpoch) const { return this->container().findBy([&](const OBJ & obj) { return obj.isOlderThan(msSinceEpoch); }); } template CONTAINER ITimestampObjectList::findBeforeAndRemove(qint64 msSinceEpoch) { CONTAINER result(findBefore(msSinceEpoch)); this->removeBefore(msSinceEpoch); return result; } template CONTAINER ITimestampObjectList::findBeforeNowMinusOffset(qint64 msOffset) const { return this->findBefore(QDateTime::currentMSecsSinceEpoch() - msOffset); } template CONTAINER ITimestampObjectList::findBefore(const QDateTime &dateTime) const { return this->findBefore(dateTime.toMSecsSinceEpoch()); } template CONTAINER ITimestampObjectList::findAfter(qint64 msSinceEpoc) const { return this->container().findBy([&](const OBJ & obj) { return obj.isNewerThan(msSinceEpoc); }); } template QList ITimestampObjectList::splitByTime(qint64 msSinceEpoch, bool sortedLatestFirst) const { QList result { {}, {} }; const auto &c = this->container(); if (sortedLatestFirst) { // O(log n) comparisons and O(n) copies struct Comparator { bool operator()(const OBJ &a, qint64 b) const { return a.isNewerThan(b); } bool operator()(qint64 a, const OBJ &b) const { return b.isOlderThan(a); } }; auto it = std::upper_bound(c.begin(), c.end(), msSinceEpoch, Comparator()); std::copy(c.begin(), it, std::back_inserter(result[0])); std::copy(it, c.end(), std::back_inserter(result[1])); } else { // O(n) comparisons and O(n) copies std::partition_copy(c.begin(), c.end(), std::back_inserter(result[0]), std::back_inserter(result[1]), [msSinceEpoch](const OBJ & obj) { return ! obj.isNewerThan(msSinceEpoch); }); } return result; } template OBJ ITimestampObjectList::latestObject() const { if (this->container().isEmpty()) { return OBJ(); } auto latest = std::max_element(container().begin(), container().end(), [](const OBJ & a, const OBJ & b) { return a.getMSecsSinceEpoch() < b.getMSecsSinceEpoch(); }); return *latest; } template OBJ ITimestampObjectList::oldestObject() const { if (this->container().isEmpty()) { return OBJ(); } auto oldest = std::min_element(container().begin(), container().end(), [](const OBJ & a, const OBJ & b) { return a.getMSecsSinceEpoch() < b.getMSecsSinceEpoch(); }); return *oldest; } template CONTAINER ITimestampObjectList::findAfter(const QDateTime &dateTime) const { return this->findAfter(dateTime.toMSecsSinceEpoch()); } template void ITimestampObjectList::removeBefore(const QDateTime &dateTime) { this->removeBefore(dateTime.toMSecsSinceEpoch()); } template void ITimestampObjectList::removeBefore(qint64 msSinceEpoc) { this->container().removeIf([&](const OBJ & obj) { return obj.isOlderThan(msSinceEpoc); }); } template void ITimestampObjectList::removeOlderThanNowMinusOffset(qint64 offsetMs) { const qint64 epoch = QDateTime::currentMSecsSinceEpoch() - offsetMs; this->container().removeIf([&](const OBJ & obj) { return obj.isOlderThan(epoch); }); } template void ITimestampObjectList::sortLatestFirst() { this->container().sortOldestFirst(); std::reverse(this->container().begin(), this->container().end()); } template void ITimestampObjectList::sortOldestFirst() { this->container().sort(BlackMisc::Predicates::MemberLess(&OBJ::getMSecsSinceEpoch)); } template void ITimestampObjectList::push_frontMaxElements(const OBJ &object, int maxElements) { Q_ASSERT(maxElements > 1); if (this->container().size() >= (maxElements - 1)) { this->container().truncate(maxElements - 1); } this->container().push_front(object); } // see here for the reason of thess forward instantiations // http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; } // namespace