Commit eccf1dc1 authored by Daniel Teske's avatar Daniel Teske

Even more algorithm usage in ProjectExplorer

Add Utils::transform and anyOf that take a member function pointer.
Remove bestElementOr it's unused.

Use declval<T> in transform's return type, because msvc does evaluate
T() and for types that don't have simple constructor this fails.
Add std::remove_reference since decltype returns a reference for
lvalues.

Change-Id: I22248b226748eeb27af0d300182d574438d7f756
Reviewed-by: default avatarEike Ziller <eike.ziller@digia.com>
parent 71b56d2b
......@@ -31,6 +31,7 @@
#define ALGORITHM_H
#include <algorithm>
#include <functional>
#if QT_VERSION < 0x050000
#ifndef Q_REQUIRED_RESULT
......@@ -46,6 +47,20 @@
namespace Utils
{
//////////////////
// anyOf
/////////////////
// anyOf taking a member function pointer
template<typename T, typename R, typename S>
bool anyOf(const T &container, R (S::*predicate)() const)
{
static_assert(std::is_convertible<typename T::iterator::value_type, S *>::value
|| std::is_convertible<typename T::iterator::value_type, S>::value,
"elements of the container must be convertible to the member function pointer's class.");
static_assert(std::is_convertible<R, bool>::value, "return type of predicate needs to be convertible to bool");
return std::any_of(container.begin(), container.end(), std::mem_fn(predicate));
}
template<typename T, typename F>
bool anyOf(const T &container, F predicate)
......@@ -53,12 +68,18 @@ bool anyOf(const T &container, F predicate)
return std::any_of(container.begin(), container.end(), predicate);
}
//////////////////
// allOf
/////////////////
template<typename T, typename F>
bool allOf(const T &container, F predicate)
{
return std::all_of(container.begin(), container.end(), predicate);
}
//////////////////
// erase
/////////////////
template<typename T, typename F>
void erase(QList<T> &container, F predicate)
{
......@@ -66,6 +87,9 @@ void erase(QList<T> &container, F predicate)
container.end());
}
//////////////////
// contains
/////////////////
template<typename T, typename F>
bool contains(const T &container, F function)
{
......@@ -76,6 +100,9 @@ bool contains(const T &container, F function)
return it != end;
}
//////////////////
// findOr
/////////////////
template<typename T, typename F>
typename T::value_type findOr(const T &container, typename T::value_type other, F function)
{
......@@ -89,23 +116,45 @@ typename T::value_type findOr(const T &container, typename T::value_type other,
}
template<typename T, typename F>
typename T::value_type bestElementOr(const T &container, typename T::value_type other, F function)
typename T::value_type findOrDefault(const T &container, F function)
{
typename T::const_iterator end = container.end();
typename T::const_iterator begin = container.begin();
return findOr(container, typename T::value_type(), function);
}
typename T::const_iterator it = std::min_element(begin, end, function);
if (it == end)
return other;
return *it;
//////////////////
// transform
/////////////////
// transform taking a member function pointer
template<typename T, typename R, typename S>
Q_REQUIRED_RESULT
auto transform(const QList<T> &container, R (S::*p)() const) -> QList<R>
{
static_assert(std::is_convertible<T, S *>::value
|| std::is_convertible<T, S>::value,
"elements of container must be convertible to S");
QList<R> result;
result.reserve(container.size());
std::transform(container.begin(), container.end(),
std::back_inserter(result),
std::mem_fn(p));
return result;
}
namespace {
// needed for msvc 2010, that doesn't have a declval
// can be removed once we stop supporting it
template<typename T>
T &&declval();
}
// Note: add overloads for other container types as needed
template<typename T, typename F>
Q_REQUIRED_RESULT
auto transform(const QList<T> &container, F function) -> QList<decltype(function(T()))>
auto transform(const QList<T> &container, F function)
-> QList<typename std::remove_reference<decltype(function(declval<T>()))>::type>
{
QList<decltype(function(T()))> result;
QList<typename std::remove_reference<decltype(function(declval<T>()))>::type> result;
result.reserve(container.size());
std::transform(container.begin(), container.end(),
std::back_inserter(result),
......@@ -113,6 +162,9 @@ auto transform(const QList<T> &container, F function) -> QList<decltype(function
return result;
}
//////////////////
// sort
/////////////////
template <typename Container>
inline void sort(Container &c)
{
......
......@@ -156,17 +156,14 @@ Utils::AbstractMacroExpander *BuildConfiguration::macroExpander()
QList<Core::Id> BuildConfiguration::knownStepLists() const
{
return Utils::transform(m_stepLists, [](BuildStepList *list) {
return list->id();
});
return Utils::transform(m_stepLists, &BuildStepList::id);
}
BuildStepList *BuildConfiguration::stepList(Core::Id id) const
{
foreach (BuildStepList *list, m_stepLists)
if (id == list->id())
return list;
return 0;
return Utils::findOrDefault(m_stepLists, [id](BuildStepList *list) {
return id == list->id();
});
}
QVariantMap BuildConfiguration::toMap() const
......
......@@ -37,6 +37,7 @@
#include "target.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
using namespace ProjectExplorer;
......@@ -121,11 +122,9 @@ bool BuildStepList::isEmpty() const
bool BuildStepList::contains(Core::Id id) const
{
foreach (BuildStep *bs, steps()) {
if (bs->id() == id)
return true;
}
return false;
return Utils::anyOf(steps(), [id](BuildStep *bs){
return bs->id() == id;
});
}
void BuildStepList::cloneSteps(BuildStepList *source)
......
......@@ -38,6 +38,7 @@
#include "projectexplorerconstants.h"
#include "toolchainmanager.h"
#include <utils/algorithm.h>
#include <utils/detailswidget.h>
#include <utils/environment.h>
#include <utils/pathchooser.h>
......@@ -218,17 +219,14 @@ IOutputParser *CustomToolChain::outputParser() const
QStringList CustomToolChain::headerPathsList() const
{
QStringList list;
foreach (const HeaderPath &headerPath, m_systemHeaderPaths)
list << headerPath.path();
return list;
return Utils::transform(m_systemHeaderPaths, &HeaderPath::path);
}
void CustomToolChain::setHeaderPaths(const QStringList &list)
{
m_systemHeaderPaths.clear();
foreach (const QString &headerPath, list)
m_systemHeaderPaths << HeaderPath(headerPath.trimmed(), HeaderPath::GlobalHeaderPath);
m_systemHeaderPaths = Utils::transform(list, [](const QString &headerPath) {
return HeaderPath(headerPath.trimmed(), HeaderPath::GlobalHeaderPath);
});
}
void CustomToolChain::setCompilerCommand(const FileName &path)
......@@ -272,9 +270,7 @@ const QStringList &CustomToolChain::cxx11Flags() const
void CustomToolChain::setMkspecs(const QString &specs)
{
m_mkspecs.clear();
foreach (const QString &spec, specs.split(QLatin1Char(',')))
m_mkspecs << FileName::fromString(spec);
m_mkspecs = Utils::transform(specs.split(QLatin1Char(',')), &FileName::fromString);
}
QString CustomToolChain::mkspecs() const
......
......@@ -32,6 +32,8 @@
#include "deployablefile.h"
#include "projectexplorer_export.h"
#include <utils/algorithm.h>
#include <QList>
#include <QSet>
......@@ -60,11 +62,9 @@ public:
DeployableFile deployableForLocalFile(const QString &localFilePath) const
{
foreach (const DeployableFile &d, m_files) {
if (d.localFilePath().toString() == localFilePath)
return d;
}
return DeployableFile();
return Utils::findOrDefault(m_files, [&localFilePath](const DeployableFile &d) {
return d.localFilePath().toString() == localFilePath;
});
}
bool operator==(const DeploymentData &other) const
......
......@@ -39,6 +39,7 @@
#include <utils/persistentsettings.h>
#include <utils/qtcassert.h>
#include <utils/portlist.h>
#include <utils/algorithm.h>
#include <QFileInfo>
#include <QHash>
......@@ -368,11 +369,9 @@ IDevice::Ptr DeviceManager::mutableDevice(Core::Id id) const
bool DeviceManager::hasDevice(const QString &name) const
{
foreach (const IDevice::Ptr &device, d->devices) {
if (device->displayName() == name)
return true;
}
return false;
return Utils::anyOf(d->devices, [&name](const IDevice::Ptr &device) {
return device->displayName() == name;
});
}
IDevice::ConstPtr DeviceManager::find(Core::Id id) const
......
......@@ -119,9 +119,7 @@ void DeviceSettingsWidget::initGui()
const QList<IDeviceFactory *> &factories
= ExtensionSystem::PluginManager::getObjects<IDeviceFactory>();
bool hasDeviceFactories = Utils::anyOf(factories, [](IDeviceFactory *factory) {
return factory->canCreate();
});
bool hasDeviceFactories = Utils::anyOf(factories, &IDeviceFactory::canCreate);
m_ui->addConfigButton->setEnabled(hasDeviceFactories);
......
......@@ -35,6 +35,7 @@
#include "projectexplorerconstants.h"
#include "toolchainmanager.h"
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/hostosinfo.h>
#include <utils/synchronousprocess.h>
......@@ -682,9 +683,7 @@ QVariantMap GccToolChain::toMap() const
data.insert(QLatin1String(compilerPlatformCodeGenFlagsKeyC), m_platformCodeGenFlags);
data.insert(QLatin1String(compilerPlatformLinkerFlagsKeyC), m_platformLinkerFlags);
data.insert(QLatin1String(targetAbiKeyC), m_targetAbi.toString());
QStringList abiList;
foreach (const Abi &a, m_supportedAbis)
abiList.append(a.toString());
QStringList abiList = Utils::transform(m_supportedAbis, &Abi::toString);
data.insert(QLatin1String(supportedAbisKeyC), abiList);
return data;
}
......
......@@ -39,6 +39,7 @@
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/abi.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QFileInfo>
......@@ -130,12 +131,11 @@ QVariant ToolChainKitInformation::defaultValue(Kit *k) const
Abi abi = Abi::hostAbi();
foreach (ToolChain *tc, tcList) {
if (tc->targetAbi() == abi)
return tc->id();
}
ToolChain *tc = Utils::findOr(tcList, tcList.first(), [&abi](ToolChain *tc) {
return tc->targetAbi() == abi;
});
return tcList.at(0)->id();
return tc->id();
}
QList<Task> ToolChainKitInformation::validate(const Kit *k) const
......
......@@ -409,19 +409,16 @@ Kit *KitManager::find(Core::Id id)
if (!id.isValid())
return 0;
foreach (Kit *k, kits()) {
if (k->id() == id)
return k;
}
return 0;
return Utils::findOrDefault(kits(), [id](Kit *k) {
return k->id() == id;
});
}
Kit *KitManager::find(const KitMatcher &matcher)
{
foreach (Kit *k, d->m_kitList)
if (matcher.matches(k))
return k;
return 0;
return Utils::findOrDefault(d->m_kitList, [&matcher](Kit *k) {
return matcher.matches(k);
});
}
Kit *KitManager::defaultKit()
......@@ -509,10 +506,8 @@ bool KitManager::registerKit(ProjectExplorer::Kit *k)
QTC_ASSERT(k->id().isValid(), return false);
foreach (Kit *current, kits()) {
if (k == current)
return false;
}
if (kits().contains(k))
return false;
k->setDisplayName(uniqueKitName(k, k->displayName(), kits()));
......
......@@ -34,6 +34,7 @@
#include "kitmanager.h"
#include <coreplugin/coreconstants.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QApplication>
......@@ -253,11 +254,9 @@ KitManagerConfigWidget *KitModel::widget(const QModelIndex &index)
bool KitModel::isDirty() const
{
foreach (KitNode *n, m_manualRoot->childNodes) {
if (n->widget->isDirty())
return true;
}
return false;
return Utils::anyOf(m_manualRoot->childNodes, [](KitNode *n) {
return n->widget->isDirty();
});
}
bool KitModel::isDirty(Kit *k) const
......@@ -371,15 +370,12 @@ QModelIndex KitModel::index(KitNode *node, int column) const
KitNode *KitModel::findWorkingCopy(Kit *k) const
{
foreach (KitNode *n, m_autoRoot->childNodes) {
if (n->widget->workingCopy() == k)
return n;
}
foreach (KitNode *n, m_manualRoot->childNodes) {
if (n->widget->workingCopy() == k)
return n;
}
return 0;
auto compareWorkingCopy = [&k](KitNode *n){ return n->widget->workingCopy() == k; };
KitNode *n = Utils::findOrDefault(m_autoRoot->childNodes, compareWorkingCopy);
if (!n)
n = Utils::findOrDefault(m_manualRoot->childNodes, compareWorkingCopy);
return n;
}
KitNode *KitModel::createNode(KitNode *parent, Kit *k)
......
......@@ -864,12 +864,8 @@ void MiniProjectTargetSelector::doLayout(bool keepSize)
onlySummary = true;
} else {
if (visibleLineCount < 3) {
foreach (Project *p, SessionManager::projects()) {
if (p->needsConfiguration()) {
visibleLineCount = 3;
break;
}
}
if (Utils::anyOf(SessionManager::projects(), &Project::needsConfiguration))
visibleLineCount = 3;
}
if (visibleLineCount)
summaryLabelHeight = visibleLineCount * QFontMetrics(m_summaryLabel->font()).height()
......
......@@ -227,14 +227,14 @@ void Project::setActiveTarget(Target *target)
Target *Project::target(Core::Id id) const
{
return Utils::findOr(d->m_targets, 0, [&id](Target *target) {
return Utils::findOrDefault(d->m_targets, [&id](Target *target) {
return target->id() == id;
});
}
Target *Project::target(Kit *k) const
{
return Utils::findOr(d->m_targets, 0, [&k](Target *target) {
return Utils::findOrDefault(d->m_targets, [&k](Target *target) {
return target->kit() == k;
});
}
......@@ -499,7 +499,7 @@ void Project::setup(QList<const BuildInfo *> infoList)
continue;
Target *t = target(k);
if (!t) {
t = Utils::findOr(toRegister, 0, [&k](Target *i){
t = Utils::findOrDefault(toRegister, [&k](Target *i){
return i->kit() == k;
});
}
......
......@@ -1490,13 +1490,7 @@ QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileName
}
updateActions();
bool switchToProjectsMode = false;
foreach (Project *p, openedPro) {
if (p->needsConfiguration()) {
switchToProjectsMode = true;
break;
}
}
bool switchToProjectsMode = Utils::anyOf(openedPro, &Project::needsConfiguration);
if (!openedPro.isEmpty()) {
if (switchToProjectsMode)
......@@ -2260,12 +2254,11 @@ void ProjectExplorerPlugin::runProjectContextMenu()
bool ProjectExplorerPlugin::hasBuildSettings(Project *pro)
{
foreach (Project *project, SessionManager::projectOrder(pro))
if (project
return Utils::anyOf(SessionManager::projectOrder(pro), [](Project *project) {
return project
&& project->activeTarget()
&& project->activeTarget()->activeBuildConfiguration())
return true;
return false;
&& project->activeTarget()->activeBuildConfiguration();
});
}
QPair<bool, QString> ProjectExplorerPlugin::buildSettingsEnabled(Project *pro)
......@@ -2352,12 +2345,11 @@ bool ProjectExplorerPlugin::coreAboutToClose()
bool ProjectExplorerPlugin::hasDeploySettings(Project *pro)
{
foreach (Project *project, SessionManager::projectOrder(pro))
if (project->activeTarget()
return Utils::anyOf(SessionManager::projectOrder(pro), [](Project *project) {
return project->activeTarget()
&& project->activeTarget()->activeDeployConfiguration()
&& !project->activeTarget()->activeDeployConfiguration()->stepList()->isEmpty())
return true;
return false;
&& !project->activeTarget()->activeDeployConfiguration()->stepList()->isEmpty();
});
}
void ProjectExplorerPlugin::runProject(Project *pro, RunMode mode, const bool forceSkipDeploy)
......@@ -2539,15 +2531,14 @@ void ProjectExplorerPlugin::updateDeployActions()
bool enableDeploySessionAction = true;
if (d->m_projectExplorerSettings.buildBeforeDeploy) {
foreach (Project *project, SessionManager::projectOrder(0)) {
if (project
&& project->activeTarget()
auto hasDisabledBuildConfiguration = [](Project *project) {
return project && project->activeTarget()
&& project->activeTarget()->activeBuildConfiguration()
&& !project->activeTarget()->activeBuildConfiguration()->isEnabled()) {
enableDeploySessionAction = false;
break;
}
}
&& !project->activeTarget()->activeBuildConfiguration()->isEnabled();
};
if (Utils::anyOf(SessionManager::projectOrder(0), hasDisabledBuildConfiguration))
enableDeploySessionAction = false;
}
if (!hasProjects || !hasDeploySettings(0) || BuildManager::isBuilding())
enableDeploySessionAction = false;
......@@ -2885,9 +2876,7 @@ void ProjectExplorerPlugin::addNewFile()
QVariantMap map;
map.insert(QLatin1String(Constants::PREFERRED_PROJECT_NODE), QVariant::fromValue(d->m_currentNode));
if (d->m_currentProject) {
QList<Id> profileIds;
foreach (Target *target, d->m_currentProject->targets())
profileIds << target->id();
QList<Id> profileIds = Utils::transform(d->m_currentProject->targets(), &Target::id);
map.insert(QLatin1String(Constants::PROJECT_KIT_IDS), QVariant::fromValue(profileIds));
}
ICore::showNewItemDialog(tr("New File", "Title of dialog"),
......@@ -2907,9 +2896,7 @@ void ProjectExplorerPlugin::addNewSubproject()
QVariantMap map;
map.insert(QLatin1String(Constants::PREFERRED_PROJECT_NODE), QVariant::fromValue(d->m_currentNode));
if (d->m_currentProject) {
QList<Id> profileIds;
foreach (Target *target, d->m_currentProject->targets())
profileIds << target->id();
QList<Id> profileIds = Utils::transform(d->m_currentProject->targets(), &Target::id);
map.insert(QLatin1String(Constants::PROJECT_KIT_IDS), QVariant::fromValue(profileIds));
}
......
......@@ -33,6 +33,8 @@
#include "projectnodes.h"
#include "projectwizardpage.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
#include <coreplugin/icore.h>
......@@ -128,9 +130,7 @@ void ProjectFileWizardExtension::firstExtensionPageShown(
if (debugExtension)
qDebug() << Q_FUNC_INFO << files.size();
QStringList fileNames;
foreach (const GeneratedFile &f, files)
fileNames.push_back(f.path());
QStringList fileNames = Utils::transform(files, &GeneratedFile::path);
m_context->page->setFiles(fileNames);
QStringList filePaths;
......@@ -140,8 +140,7 @@ void ProjectFileWizardExtension::firstExtensionPageShown(
filePaths << generatedProjectFilePath(files);
} else {
projectAction = ProjectExplorer::AddNewFile;
foreach (const GeneratedFile &gf, files)
filePaths << gf.path();
filePaths = Utils::transform(files, &GeneratedFile::path);
}
Node *contextNode = extraValues.value(QLatin1String(Constants::PREFERRED_PROJECT_NODE)).value<Node *>();
......@@ -204,9 +203,7 @@ bool ProjectFileWizardExtension::processProject(
}
*removeOpenProjectAttribute = true;
} else {
QStringList filePaths;
foreach (const GeneratedFile &generatedFile, files)
filePaths << generatedFile.path();
QStringList filePaths = Utils::transform(files, &GeneratedFile::path);
if (!folder->addFiles(filePaths)) {
*errorMessage = tr("Failed to add one or more files to project\n\"%1\" (%2).").
arg(folder->path(), filePaths.join(QString(QLatin1Char(','))));
......
......@@ -42,6 +42,7 @@
#include <utils/fileutils.h>
#include <utils/stringutils.h>
#include <utils/algorithm.h>