Convert to fancy new visitors

This commit is contained in:
Ciaran McCreesh 2013-05-23 21:00:24 +01:00
parent f91b6e03c2
commit 8629539830
6 changed files with 187 additions and 354 deletions

@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2010, 2011 Ciaran McCreesh
* Copyright (c) 2010, 2011, 2013 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
@ -58,60 +58,29 @@ AllowedToRemoveHelper::add_allowed_to_remove_spec(const PackageDepSpec & spec)
_imp->allowed_to_remove_specs.insert(spec);
}
namespace
{
struct AllowedToRemoveVisitor
{
bool visit(const DependentReason &) const
{
return true;
}
bool visit(const TargetReason &) const
{
return true;
}
bool visit(const DependencyReason &) const
{
return false;
}
bool visit(const WasUsedByReason &) const
{
return true;
}
bool visit(const ViaBinaryReason &) const
{
return false;
}
bool visit(const SetReason & r) const
{
return r.reason_for_set()->accept_returning<bool>(*this);
}
bool visit(const LikeOtherDestinationTypeReason & r) const
{
return r.reason_for_other()->accept_returning<bool>(*this);
}
bool visit(const PresetReason &) const
{
return false;
}
};
}
bool
AllowedToRemoveHelper::operator() (
const std::shared_ptr<const Resolution> & resolution,
const std::shared_ptr<const PackageID> & id) const
{
auto v = make_visitor(
[&] (const DependentReason &) { return true; },
[&] (const TargetReason &) { return true; },
[&] (const DependencyReason &) { return false; },
[&] (const WasUsedByReason &) { return true; },
[&] (const ViaBinaryReason &) { return false; },
[&] (const PresetReason &) { return false; },
[&] (const SetReason & r, const Revisit<bool, Reason> & revisit) {
return revisit(*r.reason_for_set());
},
[&] (const LikeOtherDestinationTypeReason & r, const Revisit<bool, Reason> & revisit) {
return revisit(*r.reason_for_other());
}
);
for (auto c(resolution->constraints()->begin()), c_end(resolution->constraints()->end()) ;
c != c_end ; ++c)
if ((*c)->reason()->accept_returning<bool>(AllowedToRemoveVisitor()))
if ((*c)->reason()->accept_returning<bool>(v))
return true;
return _imp->allowed_to_remove_specs.match_any(_imp->env, id, { });
@ -121,3 +90,4 @@ namespace paludis
{
template class Pimp<AllowedToRemoveHelper>;
}

@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2010, 2011 Ciaran McCreesh
* Copyright (c) 2010, 2011, 2013 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
@ -86,72 +86,53 @@ ConfirmHelper::set_allowed_to_break_system(const bool b)
_imp->allowed_to_break_system = b;
}
namespace
{
struct ConfirmVisitor
{
const Environment * const env;
const PackageDepSpecCollection & permit_downgrade_specs;
const PackageDepSpecCollection & permit_old_version_specs;
const PackageDepSpecCollection & allowed_to_break_specs;
const bool allowed_to_break_system;
const std::shared_ptr<const PackageID> id;
bool visit(const DowngradeConfirmation &) const
{
if (id)
if (permit_downgrade_specs.match_any(env, id, { }))
return true;
return false;
}
bool visit(const NotBestConfirmation &) const
{
if (id)
if (permit_old_version_specs.match_any(env, id, { }))
return true;
return false;
}
bool visit(const BreakConfirmation &) const
{
if (id)
if (allowed_to_break_specs.match_any(env, id, { }))
return true;
return false;
}
bool visit(const RemoveSystemPackageConfirmation &) const
{
return allowed_to_break_system;
}
bool visit(const MaskedConfirmation &) const
{
return false;
}
bool visit(const ChangedChoicesConfirmation &) const
{
return false;
}
};
}
bool
ConfirmHelper::operator() (
const std::shared_ptr<const Resolution> & resolution,
const std::shared_ptr<const RequiredConfirmation> & confirmation) const
{
auto id(get_decided_id_or_null(resolution->decision()));
return confirmation->accept_returning<bool>(ConfirmVisitor{_imp->env, _imp->permit_downgrade_specs,
_imp->permit_old_version_specs, _imp->allowed_to_break_specs, _imp->allowed_to_break_system, id});
return confirmation->make_accept_returning(
[&] (const DowngradeConfirmation &) {
if (id)
if (_imp->permit_downgrade_specs.match_any(_imp->env, id, { }))
return true;
return false;
},
[&] (const NotBestConfirmation &) {
if (id)
if (_imp->permit_old_version_specs.match_any(_imp->env, id, { }))
return true;
return false;
},
[&] (const BreakConfirmation &) {
if (id)
if (_imp->allowed_to_break_specs.match_any(_imp->env, id, { }))
return true;
return false;
},
[&] (const RemoveSystemPackageConfirmation &) {
return _imp->allowed_to_break_system;
},
[&] (const MaskedConfirmation &) {
return false;
},
[&] (const ChangedChoicesConfirmation &) {
return false;
}
);
}
namespace paludis
{
template class Pimp<ConfirmHelper>;
}

@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2010 Ciaran McCreesh
* Copyright (c) 2010, 2013 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
@ -23,45 +23,16 @@
using namespace paludis;
using namespace paludis::resolver;
namespace
{
struct IDVisitor
{
std::shared_ptr<const PackageID> visit(const ChangesToMakeDecision & decision) const
{
return decision.origin_id();
}
std::shared_ptr<const PackageID> visit(const BreakDecision & decision) const
{
return decision.existing_id();
}
std::shared_ptr<const PackageID> visit(const ExistingNoChangeDecision & decision) const
{
return decision.existing_id();
}
std::shared_ptr<const PackageID> visit(const NothingNoChangeDecision &) const
{
return nullptr;
}
std::shared_ptr<const PackageID> visit(const RemoveDecision &) const
{
return nullptr;
}
std::shared_ptr<const PackageID> visit(const UnableToMakeDecision &) const
{
return nullptr;
}
};
}
const std::shared_ptr<const PackageID>
paludis::resolver::get_decided_id_or_null(const std::shared_ptr<const Decision> & decision)
paludis::resolver::get_decided_id_or_null(const std::shared_ptr<const Decision> & d)
{
return decision->accept_returning<std::shared_ptr<const PackageID> >(IDVisitor());
return d->make_accept_returning(
[&] (const ChangesToMakeDecision & decision) { return decision.origin_id(); },
[&] (const BreakDecision & decision) { return decision.existing_id(); },
[&] (const ExistingNoChangeDecision & decision) { return decision.existing_id(); },
[&] (const NothingNoChangeDecision &) { return nullptr; },
[&] (const RemoveDecision &) { return nullptr; },
[&] (const UnableToMakeDecision &) { return nullptr; }
);
}

@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2010, 2011 Ciaran McCreesh
* Copyright (c) 2010, 2011, 2013 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
@ -24,7 +24,6 @@
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
#include <paludis/util/pimp-impl.hh>
#include <paludis/util/visitor_cast.hh>
#include <paludis/util/make_shared_copy.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/stringify.hh>
@ -67,63 +66,48 @@ GetDestinationTypesForBlockerHelper::set_target_destination_type(const Destinati
_imp->target_destination_type = d;
}
namespace
{
struct DestinationTypesFinder
{
const DestinationType target_destination_type;
DestinationTypes visit(const TargetReason &) const
{
return { target_destination_type };
}
DestinationTypes visit(const DependentReason &) const
{
return { dt_install_to_slash };
}
DestinationTypes visit(const ViaBinaryReason &) const
{
return { };
}
DestinationTypes visit(const WasUsedByReason &) const
{
return { dt_install_to_slash };
}
DestinationTypes visit(const DependencyReason &) const
{
return { dt_install_to_slash };
}
DestinationTypes visit(const PresetReason &) const
{
return { };
}
DestinationTypes visit(const LikeOtherDestinationTypeReason & r) const
{
return r.reason_for_other()->accept_returning<DestinationTypes>(*this);
}
DestinationTypes visit(const SetReason & r) const
{
return r.reason_for_set()->accept_returning<DestinationTypes>(*this);
}
};
}
DestinationTypes
GetDestinationTypesForBlockerHelper::operator() (
const BlockDepSpec &,
const std::shared_ptr<const Reason> & reason) const
{
return reason->accept_returning<DestinationTypes>(DestinationTypesFinder{_imp->target_destination_type});
return reason->make_accept_returning(
[&] (const TargetReason &) {
return DestinationTypes{ _imp->target_destination_type };
},
[&] (const DependentReason &) {
return DestinationTypes{ dt_install_to_slash };
},
[&] (const ViaBinaryReason &) {
return DestinationTypes{ };
},
[&] (const WasUsedByReason &) {
return DestinationTypes{ dt_install_to_slash };
},
[&] (const DependencyReason &) {
return DestinationTypes{ dt_install_to_slash };
},
[&] (const PresetReason &) {
return DestinationTypes{ };
},
[&] (const LikeOtherDestinationTypeReason & r, const Revisit<DestinationTypes, Reason> & revisit) {
return revisit(*r.reason_for_other());
},
[&] (const SetReason & r, const Revisit<DestinationTypes, Reason> & revisit) {
return revisit(*r.reason_for_set());
}
);
}
namespace paludis
{
template class Pimp<GetDestinationTypesForBlockerHelper>;
}

@ -66,60 +66,25 @@ GetDestinationTypesForErrorHelper::set_target_destination_type(const Destination
_imp->target_destination_type = d;
}
namespace
{
struct DestinationTypesFinder
{
const DestinationType target_destination_type;
DestinationTypes visit(const TargetReason &) const
{
return { target_destination_type };
}
DestinationTypes visit(const DependentReason &) const
{
return { dt_install_to_slash };
}
DestinationTypes visit(const ViaBinaryReason &) const
{
return { };
}
DestinationTypes visit(const WasUsedByReason &) const
{
return { dt_install_to_slash };
}
DestinationTypes visit(const DependencyReason &) const
{
return { dt_install_to_slash };
}
DestinationTypes visit(const PresetReason &) const
{
return { };
}
DestinationTypes visit(const LikeOtherDestinationTypeReason & r) const
{
return r.reason_for_other()->accept_returning<DestinationTypes>(*this);
}
DestinationTypes visit(const SetReason & r) const
{
return r.reason_for_set()->accept_returning<DestinationTypes>(*this);
}
};
}
DestinationTypes
GetDestinationTypesForErrorHelper::operator() (
const PackageDepSpec &,
const std::shared_ptr<const Reason> & reason) const
{
return reason->accept_returning<DestinationTypes>(DestinationTypesFinder{_imp->target_destination_type});
return reason->make_accept_returning(
[&] (const TargetReason &) { return DestinationTypes{ _imp->target_destination_type }; },
[&] (const DependentReason &) { return DestinationTypes{ dt_install_to_slash }; },
[&] (const ViaBinaryReason &) { return DestinationTypes{ }; },
[&] (const WasUsedByReason &) { return DestinationTypes{ dt_install_to_slash }; },
[&] (const DependencyReason &) { return DestinationTypes{ dt_install_to_slash }; },
[&] (const PresetReason &) { return DestinationTypes{ }; },
[&] (const LikeOtherDestinationTypeReason & r, const Revisit<DestinationTypes, Reason> & revisit) {
return revisit(*r.reason_for_other());
},
[&] (const SetReason & r, const Revisit<DestinationTypes, Reason> & revisit) {
return revisit(*r.reason_for_set());
}
);
}
namespace paludis

@ -160,112 +160,6 @@ GetResolventsForHelper::set_target_slots(const bool best, const bool installed,
namespace
{
struct DestinationTypesFinder
{
const Environment * const env;
const DestinationType target_destination_type;
const bool want_target_dependencies;
const bool want_target_runtime_dependencies;
const bool want_dependencies_on_slash;
const bool want_runtime_dependencies_on_slash;
const std::shared_ptr<const PackageID> package_id;
DestinationTypes visit(const TargetReason &) const
{
return { target_destination_type };
}
DestinationTypes visit(const DependentReason &) const
{
return { dt_install_to_slash };
}
DestinationTypes visit(const ViaBinaryReason &) const
{
return { };
}
DestinationTypes visit(const WasUsedByReason &) const
{
return { dt_install_to_slash };
}
DestinationTypes visit(const DependencyReason & dep) const
{
DestinationTypes extras, slash;
switch (target_destination_type)
{
case dt_create_binary:
{
bool binary_if_possible(false);
if (want_target_dependencies)
binary_if_possible = true;
else if (want_target_runtime_dependencies)
{
/* this will track run deps of build deps, which isn't
* really right... */
if (is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
binary_if_possible = true;
}
if (binary_if_possible && can_make_binary_for(package_id))
extras += dt_create_binary;
}
break;
case dt_install_to_chroot:
{
bool chroot_if_possible(false);
if (want_target_dependencies)
chroot_if_possible = true;
else if (want_target_runtime_dependencies)
{
if (is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
chroot_if_possible = true;
}
if (chroot_if_possible && can_chroot(package_id))
extras += dt_install_to_chroot;
}
break;
case dt_install_to_slash:
break;
case last_dt:
throw InternalError(PALUDIS_HERE, "unhandled dt");
}
if (want_runtime_dependencies_on_slash ^ want_dependencies_on_slash)
{
if (want_dependencies_on_slash && ! is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
slash += dt_install_to_slash;
if (want_runtime_dependencies_on_slash && is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
slash += dt_install_to_slash;
}
else if (want_runtime_dependencies_on_slash || want_dependencies_on_slash)
slash += dt_install_to_slash;
return extras | slash;
}
DestinationTypes visit(const PresetReason &) const
{
return { };
}
DestinationTypes visit(const LikeOtherDestinationTypeReason & r) const
{
return r.reason_for_other()->accept_returning<DestinationTypes>(*this);
}
DestinationTypes visit(const SetReason & r) const
{
return r.reason_for_set()->accept_returning<DestinationTypes>(*this);
}
};
DestinationTypes get_destination_types_for_fn(
const Environment * const env,
const PackageDepSpec &,
@ -277,9 +171,77 @@ namespace
const std::shared_ptr<const PackageID> & package_id,
const std::shared_ptr<const Reason> & reason)
{
DestinationTypesFinder f{env, target_destination_type, want_target_dependencies, want_target_runtime_dependencies,
want_dependencies_on_slash, want_runtime_dependencies_on_slash, package_id};
return reason->accept_returning<DestinationTypes>(f);
return reason->make_accept_returning(
[&] (const TargetReason &) { return DestinationTypes{ target_destination_type }; },
[&] (const DependentReason &) { return DestinationTypes{ dt_install_to_slash }; },
[&] (const ViaBinaryReason &) { return DestinationTypes{ }; },
[&] (const WasUsedByReason &) { return DestinationTypes{ dt_install_to_slash }; },
[&] (const PresetReason &) { return DestinationTypes{ }; },
[&] (const LikeOtherDestinationTypeReason & r, const Revisit<DestinationTypes, Reason> & revisit) {
return revisit(*r.reason_for_other());
},
[&] (const SetReason & r, const Revisit<DestinationTypes, Reason> & revisit) {
return revisit(*r.reason_for_set());
},
[&] (const DependencyReason & dep) {
DestinationTypes extras, slash;
switch (target_destination_type)
{
case dt_create_binary:
{
bool binary_if_possible(false);
if (want_target_dependencies)
binary_if_possible = true;
else if (want_target_runtime_dependencies)
{
/* this will track run deps of build deps, which isn't
* really right... */
if (is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
binary_if_possible = true;
}
if (binary_if_possible && can_make_binary_for(package_id))
extras += dt_create_binary;
}
break;
case dt_install_to_chroot:
{
bool chroot_if_possible(false);
if (want_target_dependencies)
chroot_if_possible = true;
else if (want_target_runtime_dependencies)
{
if (is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
chroot_if_possible = true;
}
if (chroot_if_possible && can_chroot(package_id))
extras += dt_install_to_chroot;
}
break;
case dt_install_to_slash:
break;
case last_dt:
throw InternalError(PALUDIS_HERE, "unhandled dt");
}
if (want_runtime_dependencies_on_slash ^ want_dependencies_on_slash)
{
if (want_dependencies_on_slash && ! is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
slash += dt_install_to_slash;
if (want_runtime_dependencies_on_slash && is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
slash += dt_install_to_slash;
}
else if (want_runtime_dependencies_on_slash || want_dependencies_on_slash)
slash += dt_install_to_slash;
return extras | slash;
}
);
}
bool can_use_cache(const PackageDepSpec & spec)