/* 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/simulation/simulatedaircraftlist.h" #include "blackmisc/simulation/interpolationsetuplist.h" #include "blackmisc/aviation/callsignobjectlist.h" #include "blackmisc/aviation/callsign.h" #include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/aircraftsituationlist.h" #include "blackmisc/aviation/flightplanlist.h" #include "blackmisc/network/clientlist.h" #include "blackmisc/predicates.h" #include namespace BlackMisc { namespace Aviation { template ICallsignObjectList::ICallsignObjectList() { } template const CONTAINER &ICallsignObjectList::container() const { return static_cast(*this); } template CONTAINER &ICallsignObjectList::container() { return static_cast(*this); } template bool ICallsignObjectList::containsCallsign(const CCallsign &callsign) const { return this->container().contains(&OBJ::getCallsign, callsign); } template int ICallsignObjectList::applyIfCallsign(const CCallsign &callsign, const CPropertyIndexVariantMap &variantMap, bool skipEqualValues) { return this->container().applyIf(&OBJ::getCallsign, callsign, variantMap, skipEqualValues); } template CCallsignSet ICallsignObjectList::getCallsigns() const { CCallsignSet cs; for (const OBJ &obj : this->container()) { cs.push_back(obj.getCallsign()); } return cs; } template QStringList ICallsignObjectList::getCallsignStrings(bool sorted) const { return this->getCallsigns().getCallsignStrings(sorted); } template CONTAINER ICallsignObjectList::findByCallsign(const CCallsign &callsign) const { return this->container().findBy(&OBJ::getCallsign, callsign); } template CONTAINER ICallsignObjectList::findByCallsigns(const CCallsignSet &callsigns) const { return this->container().findBy(Predicates::MemberIsAnyOf(&OBJ::getCallsign, callsigns)); } template OBJ ICallsignObjectList::findFirstByCallsign(const CCallsign &callsign, const OBJ &ifNotFound) const { return this->container().findFirstByOrDefault(&OBJ::getCallsign, callsign, ifNotFound); } template OBJ ICallsignObjectList::findLastByCallsign(const CCallsign &callsign, const OBJ &ifNotFound) const { for (auto current = container().end(); current != container().begin() ; /* Do nothing */) { --current; if (current->getCallsign() == callsign) { return *current; } } return ifNotFound; } template CONTAINER ICallsignObjectList::findBySuffix(const QString &suffix) const { CONTAINER r; if (suffix.isEmpty()) { return r; } const QString sfxUpper(suffix.trimmed().toUpper()); r = this->container().findBy([ = ](const OBJ & csObj) { return (csObj.getCallsign().getSuffix() == sfxUpper); }); return r; } template int ICallsignObjectList::firstIndexOfCallsign(const CCallsign &callsign) { for (int i = 0; i < this->container().size(); i++) { if (this->container()[i].getCallsign() == callsign) { return i; } } return -1; } template int ICallsignObjectList::removeByCallsign(const CCallsign &callsign) { return this->container().removeIf(&OBJ::getCallsign, callsign); } template int ICallsignObjectList::removeByCallsigns(const CCallsignSet &callsigns) { return this->container().removeIf([ & ](const OBJ & obj) { return callsigns.contains(obj.getCallsign()); }); } template QMap ICallsignObjectList::getSuffixes() const { QMap r; for (const OBJ &csObj : this->container()) { const QString s = csObj.getCallsign().getSuffix(); if (s.isEmpty()) { continue; } if (r.contains(s)) { r[s] = r[s] + 1; } else { r.insert(s, 1); } } return r; } template QHash ICallsignObjectList::splitPerCallsign() const { CONTAINER copyContainer(container()); copyContainer.sortByCallsign(); QHash result; CCallsign cs; for (const OBJ &csObj : copyContainer) { if (csObj.getCallsign().isEmpty()) { Q_ASSERT(false); // there should be no empty callsigns continue; } if (cs != csObj.getCallsign()) { cs = csObj.getCallsign(); CONTAINER perCallsign({ csObj }); result.insert(cs, perCallsign); } else { result[cs].push_back(csObj); } } return result; } template int ICallsignObjectList::replaceOrAddObjectByCallsign(const OBJ &otherObject) { const CCallsign cs(otherObject.getCallsign()); if (cs.isEmpty()) { return 0; } CONTAINER ©(this->container()); copy.removeByCallsign(cs); copy.push_back(otherObject); return 1; } template int ICallsignObjectList::replaceOrAddObjectsByCallsign(const CONTAINER &others) { if (others.isEmpty()) { return 0; } int c = 0; CONTAINER copy(this->container()); for (const OBJ &obj : others) { const CCallsign cs(obj.getCallsign()); if (cs.isEmpty()) { continue; } copy.removeByCallsign(cs); copy.push_back(obj); c++; } *this = copy; return c; } template void ICallsignObjectList::sortByCallsign() { container().sortBy(&OBJ::getCallsign); } template QMap ICallsignObjectList::asCallsignMap() const { QMap map; for (const OBJ &obj : this->container()) { map.insert(obj.getCallsign(), obj); } return map; } template QHash ICallsignObjectList::asCallsignHash() const { QHash hash; for (const OBJ &obj : this->container()) { if (obj.getCallsign().isEmpty()) { continue; } hash.insert(obj.getCallsign(), obj); } return hash; } template CONTAINER ICallsignObjectList::sortedByCallsign() const { CONTAINER copy(this->container()); copy.sortByCallsign(); return copy; } template int ICallsignObjectList::incrementalUpdateOrAdd(const OBJ &objectBeforeChanges, const CPropertyIndexVariantMap &changedValues) { int c; const CCallsign cs = objectBeforeChanges.getCallsign(); if (this->containsCallsign(cs)) { if (changedValues.isEmpty()) { return 0; } c = this->container().applyIf(&OBJ::getCallsign, cs, changedValues); } else { c = 1; if (changedValues.isEmpty()) { this->container().push_back(objectBeforeChanges); } else { OBJ objectAdded(objectBeforeChanges); objectAdded.apply(changedValues); this->container().push_back(objectAdded); } } return c; } // see here for the reason of thess forward instantiations // https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl //! \cond PRIVATE template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ICallsignObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ICallsignObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ICallsignObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ICallsignObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ICallsignObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE ICallsignObjectList; //! \endcond } // namespace } // namespace