Exheredludis/paludis/resolver/resolver.cc
Saleem Abdulrasool 64ba7d5be8 modernize: use default method synthesis
Convert a number of destructors to default synthesized functions.  Try to
inline a few instances into the header.  It should be possible to inline all of
them, however, gcc seems to emit a number of warnings.  Furthermore, some of the
destructors are pure-virtualed, but provide an implementation.  Placing the
definition into the header causes ODR violations.
2016-08-06 11:58:04 -07:00

182 lines
6.3 KiB
C++

/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2009, 2010, 2011 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
* Public License version 2, as published by the Free Software Foundation.
*
* Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <paludis/resolver/resolver.hh>
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/decider.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
#include <paludis/resolver/reason.hh>
#include <paludis/resolver/resolutions_by_resolvent.hh>
#include <paludis/resolver/orderer.hh>
#include <paludis/resolver/decisions.hh>
#include <paludis/resolver/job_list.hh>
#include <paludis/resolver/job_lists.hh>
#include <paludis/resolver/nag.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/make_shared_copy.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/pimp-impl.hh>
#include <paludis/environment.hh>
#include <paludis/notifier_callback.hh>
#include <paludis/spec_tree.hh>
#include <paludis/repository.hh>
#include <algorithm>
#include <set>
using namespace paludis;
using namespace paludis::resolver;
namespace paludis
{
template <>
struct Imp<Resolver>
{
const Environment * const env;
const ResolverFunctions fns;
const std::shared_ptr<Resolved> resolved;
const std::shared_ptr<Decider> decider;
const std::shared_ptr<Orderer> orderer;
Imp(const Environment * const e, const ResolverFunctions & f) :
env(e),
fns(f),
resolved(std::make_shared<Resolved>(make_named_values<Resolved>(
n::job_lists() = make_shared_copy(make_named_values<JobLists>(
n::execute_job_list() = std::make_shared<JobList<ExecuteJob>>(),
n::pretend_job_list() = std::make_shared<JobList<PretendJob>>()
)),
n::nag() = std::make_shared<NAG>(),
n::resolutions_by_resolvent() = std::make_shared<ResolutionsByResolvent>(),
n::taken_change_or_remove_decisions() = std::make_shared<OrderedChangeOrRemoveDecisions>(),
n::taken_unable_to_make_decisions() = std::make_shared<Decisions<UnableToMakeDecision>>(),
n::taken_unconfirmed_decisions() = std::make_shared<Decisions<ConfirmableDecision>>(),
n::taken_unorderable_decisions() = std::make_shared<OrderedChangeOrRemoveDecisions>(),
n::untaken_change_or_remove_decisions() = std::make_shared<Decisions<ChangeOrRemoveDecision>>(),
n::untaken_unable_to_make_decisions() = std::make_shared<Decisions<UnableToMakeDecision>>()
))),
decider(std::make_shared<Decider>(e, f, resolved->resolutions_by_resolvent())),
orderer(std::make_shared<Orderer>(e, f, resolved))
{
}
};
}
Resolver::Resolver(const Environment * const e, const ResolverFunctions & f) :
_imp(e, f)
{
}
Resolver::~Resolver() = default;
void
Resolver::add_target(const PackageOrBlockDepSpec & spec, const std::string & extra_information)
{
_imp->decider->add_target_with_reason(spec, std::make_shared<TargetReason>(extra_information));
}
namespace
{
typedef std::set<SetName> RecursingNames;
struct SetExpander
{
const Environment * const env;
const std::shared_ptr<Decider> & decider;
const std::shared_ptr<const Reason> reason;
RecursingNames & recurse;
SetExpander(const Environment * const e,
const std::shared_ptr<Decider> & d,
const std::shared_ptr<const Reason> & r,
RecursingNames & c) :
env(e),
decider(d),
reason(r),
recurse(c)
{
}
void visit(const SetSpecTree::NodeType<NamedSetDepSpec>::Type & n) const
{
if (! recurse.insert(n.spec()->name()).second)
throw RecursivelyDefinedSetError(stringify(n.spec()->name()));
const std::shared_ptr<const SetSpecTree> set(env->set(n.spec()->name()));
if (! set)
throw NoSuchSetError(stringify(n.spec()->name()));
set->top()->accept(SetExpander(env, decider,
std::make_shared<SetReason>(n.spec()->name(), reason), recurse));
recurse.erase(n.spec()->name());
}
void visit(const SetSpecTree::NodeType<AllDepSpec>::Type & n) const
{
std::for_each(indirect_iterator(n.begin()), indirect_iterator(n.end()), accept_visitor(*this));
}
void visit(const SetSpecTree::NodeType<PackageDepSpec>::Type & n) const
{
decider->add_target_with_reason(*n.spec(), reason);
}
};
}
void
Resolver::add_target(const SetName & set_name, const std::string & extra_information)
{
Context context("When adding set target '" + stringify(set_name) + "':");
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
const std::shared_ptr<const SetSpecTree> set(_imp->env->set(set_name));
if (! set)
throw NoSuchSetError(stringify(set_name));
RecursingNames recurse;
set->top()->accept(SetExpander(_imp->env, _imp->decider, std::make_shared<TargetReason>(extra_information), recurse));
}
void
Resolver::purge()
{
_imp->decider->purge();
}
void
Resolver::resolve()
{
_imp->decider->resolve();
_imp->orderer->resolve();
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Done"));
}
const std::shared_ptr<const Resolved>
Resolver::resolved() const
{
return _imp->resolved;
}