From 586f605d049a850f1bdfc70b158cd0a293a1e75a Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Sat, 16 Oct 2021 18:41:47 +0100 Subject: [PATCH] Delegate parts of CSequence to a non-template implementation To reduce build time. --- src/blackmisc/blackmiscexport.h | 10 ++++++ src/blackmisc/sequence.cpp | 31 +++++++++++++++++ src/blackmisc/sequence.h | 33 ++++++++++++++++++- .../fscommon/aircraftcfgentrieslist.cpp | 4 +++ .../fscommon/aircraftcfgentrieslist.h | 6 ++++ src/blackmisc/verify.h | 8 ----- 6 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 src/blackmisc/sequence.cpp diff --git a/src/blackmisc/blackmiscexport.h b/src/blackmisc/blackmiscexport.h index 65b89a617..cf65a1b5d 100644 --- a/src/blackmisc/blackmiscexport.h +++ b/src/blackmisc/blackmiscexport.h @@ -37,4 +37,14 @@ # define BLACKMISC_EXPORT_DECLARE_TEMPLATE #endif +/*! + * \def BLACK_NO_INLINE + * Prevent function inlining + */ +#ifdef Q_CC_MSVC +#define BLACK_NO_INLINE __declspec(noinline) +#else +#define BLACK_NO_INLINE __attribute__((noinline)) +#endif + #endif // guard diff --git a/src/blackmisc/sequence.cpp b/src/blackmisc/sequence.cpp new file mode 100644 index 000000000..2c6bb0898 --- /dev/null +++ b/src/blackmisc/sequence.cpp @@ -0,0 +1,31 @@ +/* Copyright (C) 2021 + * 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. + */ + +//! \file + +#include "blackmisc/sequence.h" +#include + +namespace BlackMisc::Private +{ + QVector findIndices(int size, const std::function &predicate) + { + QVector result(size); + std::iota(result.begin(), result.end(), 0); + result.erase(std::remove_if(result.begin(), result.end(), std::not_fn(predicate)), result.end()); + return result; + } + + QVector sortIndices(int size, const std::function &cmp) + { + QVector result(size); + std::iota(result.begin(), result.end(), 0); + std::sort(result.begin(), result.end(), cmp); + return result; + } +} diff --git a/src/blackmisc/sequence.h b/src/blackmisc/sequence.h index 480973918..997c4dcf9 100644 --- a/src/blackmisc/sequence.h +++ b/src/blackmisc/sequence.h @@ -14,12 +14,14 @@ #include "blackmisc/containerbase.h" #include "blackmisc/mixin/mixinicon.h" #include "blackmisc/mixin/mixindatastream.h" +#include "blackmisc/blackmiscexport.h" #include #include #include #include #include #include +#include //! \cond #define BLACK_TEMPLATE_SEQUENCE_MIXINS(NS, T, List, Extern) \ @@ -63,6 +65,15 @@ namespace BlackMisc { + namespace Private + { + //! \private Decouple finding from value type. + BLACKMISC_EXPORT BLACK_NO_INLINE QVector findIndices(int size, const std::function &predicate); + + //! \private Decouple sorting from value type. + BLACKMISC_EXPORT BLACK_NO_INLINE QVector sortIndices(int size, const std::function &cmp); + } + /*! * Generic sequential container with value semantics. * \tparam T the type of elements contained. @@ -306,6 +317,20 @@ namespace BlackMisc //! Return an iterator to the first element equal to the given object, or the end iterator if not found. O(n). const_iterator find(const T &object) const { return std::find(cbegin(), cend(), object); } + using CContainerBase>::findBy; + + //! \copydoc BlackMisc::CRangeBase::findBy + template + CSequence findBy(Predicate p) const + { + QVector found; + for (int i : Private::findIndices(size(), [&p, this](int i) { return p((*this)[i]); })) + { + found.push_back((*this)[i]); + } + return found; + } + //! Modify by applying a value map to each element for which a given predicate returns true. //! \return The number of elements modified. template @@ -460,7 +485,13 @@ namespace BlackMisc //! In-place sort by a given comparator predicate. template void sort(Predicate p) { - std::sort(begin(), end(), p); + QVector temp; + temp.reserve(size()); + for (int i : Private::sortIndices(size(), [&p, this](int a, int b) { return p((*this)[a], (*this)[b]); })) + { + temp.push_back(std::move((*this)[i])); + } + m_impl = std::move(temp); } //! In-place sort by some particular key(s). diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp index d204dd2aa..74981a83a 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp +++ b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.cpp @@ -21,6 +21,10 @@ BLACK_DEFINE_SEQUENCE_MIXINS(BlackMisc::Simulation::FsCommon, CAircraftCfgEntrie namespace BlackMisc::Simulation::FsCommon { + CAircraftCfgEntriesList::CAircraftCfgEntriesList() = default; + + CAircraftCfgEntriesList::CAircraftCfgEntriesList(const CSequence& other) : CSequence(other) {} + bool CAircraftCfgEntriesList::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) { if (title.isEmpty()) { return false; } diff --git a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.h b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.h index f7cc1588d..79231ad96 100644 --- a/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.h +++ b/src/blackmisc/simulation/fscommon/aircraftcfgentrieslist.h @@ -38,6 +38,12 @@ namespace BlackMisc::Simulation::FsCommon BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CAircraftCfgEntriesList) using CSequence::CSequence; + //! Default constructor. + CAircraftCfgEntriesList(); + + //! Construct from a base class object. + CAircraftCfgEntriesList(const CSequence &other); + //! Contains model with title? bool containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive); diff --git a/src/blackmisc/verify.h b/src/blackmisc/verify.h index 97ab3540e..c93ef957f 100644 --- a/src/blackmisc/verify.h +++ b/src/blackmisc/verify.h @@ -13,14 +13,6 @@ #include "blackmisc/blackmiscexport.h" -//! \cond -#ifdef Q_CC_MSVC -#define BLACK_NO_INLINE __declspec(noinline) -#else -#define BLACK_NO_INLINE __attribute__((noinline)) -#endif -//! \endcond - namespace BlackMisc::Private { //! \private Do nothing.