/* Copyright (C) 2016 * 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. 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/orderablelist.h" #include "blackmisc/predicates.h" #include "blackmisc/simulation/aircraftmodellist.h" #include "blackmisc/simulation/distributorlist.h" #include "blackmisc/statusmessagelist.h" #include #include namespace BlackMisc { template IOrderableList::IOrderableList() { static_assert(std::is_base_of::value, "OBJ needs to implement IOrderable"); } template const CONTAINER &IOrderableList::container() const { return static_cast(*this); } template CONTAINER &IOrderableList::container() { return static_cast(*this); } template void IOrderableList::sortDescendingByOrder() { IOrderableList::container().sortAscendingByOrder(); std::reverse(this->container().begin(), this->container().end()); } template void IOrderableList::sortAscendingByOrder() { IOrderableList::container().sort(Predicates::MemberLess(&OBJ::getOrder)); } template void IOrderableList::resetOrder(int offset) { int c = offset; for (OBJ &obj : container()) { obj.setOrder(c++); } } template bool IOrderableList::needsOrder() const { for (const OBJ &obj : container()) { if (!obj.hasValidOrder()) { return true; } } return false; } template QList IOrderableList::orderValues() const { QList orders; for (const OBJ &obj : container()) { if (!obj.hasValidOrder()) { continue; } orders.append(obj.getOrder()); } return orders; } template CONTAINER IOrderableList::withoutItemsOfSameOrder(const CONTAINER &items) const { const QList orders = items.orderValues(); if (orders.isEmpty()) { return this->container(); } CONTAINER newContainer; for (const OBJ &obj : container()) { if (orders.contains(obj.getOrder())) { continue; } newContainer.push_back(obj); } return newContainer; } template void IOrderableList::removeItemsWithSameOrder(const CONTAINER &items) { const QList orders = items.orderValues(); if (orders.isEmpty()) { return; } CONTAINER newContainer; for (const OBJ &obj : container()) { if (orders.contains(obj.getOrder())) { continue; } newContainer.push_back(obj); } this->container() = newContainer; } template void IOrderableList::moveTo(const CONTAINER &items, int targetOrder) { if (items.isEmpty()) { return; } CONTAINER newContainer(this->withoutItemsOfSameOrder(items)); // this container without items CONTAINER newItems(items); const int shift = items.size(); newContainer.sortAscendingByOrder(); // sorted by old order newContainer.resetOrder(); for (OBJ &obj : newContainer) { if (obj.getOrder() < targetOrder) { continue; } obj.setOrder(obj.getOrder() + shift); } newItems.sortAscendingByOrder(); // sort by old order newItems.resetOrder(targetOrder); newContainer.push_back(newItems); this->container() = newContainer; } template void IOrderableList::freezeOrder() { int c = 0; for (OBJ &obj : container()) { obj.setOrder(c++); } } template void IOrderableList::freezeOrderReverse() { int c = this->container().size() - 1; for (OBJ &obj : container()) { obj.setOrder(c--); } } template OBJ IOrderableList::minOrderOrDefault() const { if (container().isEmpty()) { return OBJ(); } OBJ min = container().front(); for (const OBJ &obj : container()) { if (!obj.hasValidOrder()) { continue; } if (obj.getOrder() < min.getOrder()) { min = obj; } } return min; } template OBJ IOrderableList::maxOrderOrDefault() const { if (container().isEmpty()) { return OBJ(); } OBJ max = container().front(); for (const OBJ &obj : container()) { if (!obj.hasValidOrder()) { continue; } if (obj.getOrder() > max.getOrder()) { max = obj; } } return max; } //! \cond PRIVATE template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IOrderableList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IOrderableList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IOrderableList; //! \endcond } // namespace