aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-10-04 21:03:34 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-10-04 21:03:34 +0000
commit34c4559c9b6abb75e64336966c78998f94e192b6 (patch)
tree0f2f1f88f4c4f332e86a6c38cb2d40059f0d267d
parent2c378e279e1330d1fa02feceac4676342a2baafe (diff)
downloadpaludis-34c4559c9b6abb75e64336966c78998f94e192b6.tar.gz
paludis-34c4559c9b6abb75e64336966c78998f94e192b6.tar.xz
Make DepSpecFlattener a template to avoid the need for icky casting
-rw-r--r--doc/doc_main.doxygen2
-rw-r--r--doc/examples/Makefile.am10
-rw-r--r--doc/examples/example_contents.cc2
-rw-r--r--doc/examples/example_dep_label.cc2
-rw-r--r--doc/examples/example_dep_spec.cc2
-rw-r--r--doc/examples/example_dep_spec_flattener.cc135
-rw-r--r--doc/examples/example_dep_tree.cc2
-rw-r--r--paludis/dep_list/dep_list.cc4
-rw-r--r--paludis/dep_spec_flattener.cc84
-rw-r--r--paludis/dep_spec_flattener.hh61
-rw-r--r--paludis/dep_tree.cc11
-rw-r--r--paludis/dep_tree.hh44
-rw-r--r--paludis/repositories/e/e_key.cc4
-rw-r--r--paludis/repositories/e/ebuild_entries.cc8
-rw-r--r--paludis/repositories/e/vdb_repository.cc9
-rw-r--r--paludis/repositories/fake/fake_installed_repository.cc4
-rw-r--r--paludis/tasks/uninstall_task.cc10
-rw-r--r--paludis/util/files.m41
-rw-r--r--paludis/util/visitor_cast.hh191
-rw-r--r--python/dep_spec.cc9
-rw-r--r--src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc2
21 files changed, 427 insertions, 170 deletions
diff --git a/doc/doc_main.doxygen b/doc/doc_main.doxygen
index 987e3a5..c68453f 100644
--- a/doc/doc_main.doxygen
+++ b/doc/doc_main.doxygen
@@ -53,6 +53,7 @@
* - \ref example_dep_label.cc "example_dep_label.cc"
* - \ref example_dep_spec.cc "example_dep_spec.cc"
* - \ref example_dep_tree.cc "example_dep_tree.cc"
+ * - \ref example_dep_spec_flattener.cc "example_dep_spec_flattener.cc"
*/
/** \defgroup g_exceptions Exceptions
@@ -61,3 +62,4 @@
*
* \ingroup g_paludis
*/
+
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
index 645c085..7d1c647 100644
--- a/doc/examples/Makefile.am
+++ b/doc/examples/Makefile.am
@@ -15,7 +15,8 @@ noinst_PROGRAMS = \
example_contents \
example_dep_label \
example_dep_spec \
- example_dep_tree
+ example_dep_tree \
+ example_dep_spec_flattener
EXTRA_DIST = $(noinst_SCRIPTS)
@@ -67,6 +68,13 @@ example_dep_tree_LDFLAGS = \
$(top_builddir)/paludis/args/libpaludisargs.la \
$(top_builddir)/paludis/environments/libpaludisenvironments.la
+example_dep_spec_flattener_SOURCES = example_dep_spec_flattener.cc
+example_dep_spec_flattener_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la \
+ $(top_builddir)/paludis/environments/libpaludisenvironments.la
+
built-sources : $(BUILT_SOURCES)
for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
diff --git a/doc/examples/example_contents.cc b/doc/examples/example_contents.cc
index 639e6f0..f728c24 100644
--- a/doc/examples/example_contents.cc
+++ b/doc/examples/example_contents.cc
@@ -72,7 +72,7 @@ int main(int argc, char * argv[])
try
{
CommandLine::get_instance()->run(argc, argv,
- "example_action", "EXAMPLE_ACTION_OPTIONS", "EXAMPLE_ACTION_CMDLINE");
+ "example_contents", "EXAMPLE_CONTENTS_OPTIONS", "EXAMPLE_CONTENTS_CMDLINE");
/* We start with an Environment, respecting the user's '--environment' choice. */
tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
diff --git a/doc/examples/example_dep_label.cc b/doc/examples/example_dep_label.cc
index 344a8b6..58d5545 100644
--- a/doc/examples/example_dep_label.cc
+++ b/doc/examples/example_dep_label.cc
@@ -153,7 +153,7 @@ int main(int argc, char * argv[])
try
{
CommandLine::get_instance()->run(argc, argv,
- "example_action", "EXAMPLE_ACTION_OPTIONS", "EXAMPLE_ACTION_CMDLINE");
+ "example_dep_label", "EXAMPLE_DEP_LABEL_OPTIONS", "EXAMPLE_DEP_LABEL_CMDLINE");
/* We start with an Environment, respecting the user's '--environment' choice. */
tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
diff --git a/doc/examples/example_dep_spec.cc b/doc/examples/example_dep_spec.cc
index f74eb79..129c2b3 100644
--- a/doc/examples/example_dep_spec.cc
+++ b/doc/examples/example_dep_spec.cc
@@ -37,7 +37,7 @@ int main(int argc, char * argv[])
try
{
CommandLine::get_instance()->run(argc, argv,
- "example_action", "EXAMPLE_ACTION_OPTIONS", "EXAMPLE_ACTION_CMDLINE");
+ "example_dep_spec", "EXAMPLE_DEP_SPEC_OPTIONS", "EXAMPLE_DEP_SPEC_CMDLINE");
/* We start with an Environment, respecting the user's '--environment' choice. */
tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
diff --git a/doc/examples/example_dep_spec_flattener.cc b/doc/examples/example_dep_spec_flattener.cc
new file mode 100644
index 0000000..dcbfbf3
--- /dev/null
+++ b/doc/examples/example_dep_spec_flattener.cc
@@ -0,0 +1,135 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_dep_spec_flattener.cc "example_dep_spec_flattener.cc" .
+ *
+ * \ingroup g_dep_spec
+ */
+
+/** \example example_dep_spec_flattener.cc
+ *
+ * This example demonstrates how to use DepSpecFlattener. It extracts various
+ * metadata items from a package.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <cstdlib>
+#include <set>
+#include <map>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_dep_spec_flattener", "EXAMPLE_DEP_SPEC_FLATTENER_OPTIONS", "EXAMPLE_DEP_SPEC_FLATTENER_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for all installed packages. */
+ tr1::shared_ptr<const PackageIDSequence> ids(
+ env->package_database()->query(
+ query::SupportsAction<InstalledAction>(),
+ qo_order_by_version));
+
+ /* For each ID: */
+ for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ cout << "Information about '" << **i << "':" << endl;
+
+ /* Do we have a provides key? All PackageID key methods may return a
+ * zero pointer. */
+ if ((*i)->provide_key())
+ {
+ /* Create our flattener... */
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> provides(env.get(), *i);
+
+ /* Populate it by making it visit the key's value */
+ (*i)->provide_key()->value()->accept(provides);
+
+ /* The results are available through DepSpecFlattener::begin()
+ * and ::end(). These return an iterator to a tr1::shared_ptr<>,
+ * so we use indirect_iterator to add a level of dereferencing.*/
+ cout << " " << left << setw(24) << "Provides:" << " "
+ << join(indirect_iterator(provides.begin()), indirect_iterator(provides.end()), " ")
+ << endl;
+ }
+
+ /* Again for homepage */
+ if ((*i)->homepage_key())
+ {
+ DepSpecFlattener<SimpleURISpecTree, SimpleURIDepSpec> homepages(env.get(), *i);
+ (*i)->homepage_key()->value()->accept(homepages);
+
+ cout << " " << left << setw(24) << "Homepages:" << " "
+ << join(indirect_iterator(homepages.begin()), indirect_iterator(homepages.end()), " ")
+ << endl;
+ }
+
+ /* And again for restricts. There's no global restrict key, since
+ * it has no meaning outside of the repositories that support it.
+ * Instead, we use PackageID::find_metadata to see if the key we
+ * want exists, and then visitor_cast<> to see whether it's of a
+ * suitable type (the key could be something other than a
+ * MetadataSpecTreeKey<RestrictSpecTree>). */
+ if ((*i)->end_metadata() != (*i)->find_metadata("RESTRICT") &&
+ visitor_cast<const MetadataSpecTreeKey<RestrictSpecTree> >(**(*i)->find_metadata("RESTRICT")))
+ {
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(env.get(), *i);
+
+ visitor_cast<const MetadataSpecTreeKey<RestrictSpecTree> >(
+ **(*i)->find_metadata("RESTRICT"))->value()->accept(restricts);
+
+ cout << " " << left << setw(24) << "Restricts:" << " "
+ << join(indirect_iterator(restricts.begin()), indirect_iterator(restricts.end()), " ")
+ << endl;
+ }
+
+ cout << endl;
+ }
+ }
+ catch (const Exception & e)
+ {
+ /* Paludis exceptions can provide a handy human-readable backtrace and
+ * an explanation message. Where possible, these should be displayed. */
+ cout << endl;
+ cout << "Unhandled exception:" << endl
+ << " * " << e.backtrace("\n * ")
+ << e.message() << " (" << e.what() << ")" << endl;
+ return EXIT_FAILURE;
+ }
+ catch (const std::exception & e)
+ {
+ cout << endl;
+ cout << "Unhandled exception:" << endl
+ << " * " << e.what() << endl;
+ return EXIT_FAILURE;
+ }
+ catch (...)
+ {
+ cout << endl;
+ cout << "Unhandled exception:" << endl
+ << " * Unknown exception type. Ouch..." << endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+
diff --git a/doc/examples/example_dep_tree.cc b/doc/examples/example_dep_tree.cc
index 3d6c7ae..335da1b 100644
--- a/doc/examples/example_dep_tree.cc
+++ b/doc/examples/example_dep_tree.cc
@@ -154,7 +154,7 @@ int main(int argc, char * argv[])
try
{
CommandLine::get_instance()->run(argc, argv,
- "example_action", "EXAMPLE_ACTION_OPTIONS", "EXAMPLE_ACTION_CMDLINE");
+ "example_dep_tree", "EXAMPLE_DEP_TREE_OPTIONS", "EXAMPLE_DEP_TREE_CMDLINE");
/* We start with an Environment, respecting the user's '--environment' choice. */
tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
diff --git a/paludis/dep_list/dep_list.cc b/paludis/dep_list/dep_list.cc
index c71825a..cb764db 100644
--- a/paludis/dep_list/dep_list.cc
+++ b/paludis/dep_list/dep_list.cc
@@ -1000,7 +1000,7 @@ DepList::add_package(const tr1::shared_ptr<const PackageID> & p, tr1::shared_ptr
/* add provides */
if (p->provide_key())
{
- DepSpecFlattener f(_imp->env, _imp->current_package_id());
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->env, _imp->current_package_id());
p->provide_key()->value()->accept(f);
if (f.begin() != f.end() && ! DistributionData::get_instance()->distribution_from_string(
@@ -1008,7 +1008,7 @@ DepList::add_package(const tr1::shared_ptr<const PackageID> & p, tr1::shared_ptr
throw DistributionConfigurationError("Package '" + stringify(*p) + "' has PROVIDEs, but this distribution "
"does not support old style virtuals");
- for (DepSpecFlattener::ConstIterator i(f.begin()), i_end(f.end()) ; i != i_end ; ++i)
+ for (DepSpecFlattener<ProvideSpecTree, PackageDepSpec>::ConstIterator i(f.begin()), i_end(f.end()) ; i != i_end ; ++i)
{
tr1::shared_ptr<VersionRequirements> v(new VersionRequirements);
v->push_back(VersionRequirement(vo_equal, p->version()));
diff --git a/paludis/dep_spec_flattener.cc b/paludis/dep_spec_flattener.cc
index 42feef6..93a82fd 100644
--- a/paludis/dep_spec_flattener.cc
+++ b/paludis/dep_spec_flattener.cc
@@ -17,8 +17,9 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <paludis/dep_spec.hh>
#include <paludis/dep_spec_flattener.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/dep_tree.hh>
#include <paludis/environment.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
@@ -26,29 +27,18 @@
#include <list>
#include <algorithm>
-/** \file
- * Implementation of dep_spec_flattener.hh.
- *
- * \ingroup grpdepspecflattener
- */
-
using namespace paludis;
namespace paludis
{
- /**
- * Implementation data for DepSpecFlattener.
- *
- * \ingroup grpdepspecflattener
- */
- template<>
- struct Implementation<DepSpecFlattener>
+ template <>
+ template <typename Heirarchy_, typename Item_>
+ struct Implementation<DepSpecFlattener<Heirarchy_, Item_> >
{
const Environment * const env;
-
const tr1::shared_ptr<const PackageID> pkg;
- std::list<tr1::shared_ptr<const StringDepSpec > > specs;
+ std::list<tr1::shared_ptr<const Item_> > specs;
Implementation(const Environment * const e,
const tr1::shared_ptr<const PackageID> p) :
@@ -59,65 +49,53 @@ namespace paludis
};
}
-DepSpecFlattener::DepSpecFlattener(
+template <typename Heirarchy_, typename Item_>
+DepSpecFlattener<Heirarchy_, Item_>::DepSpecFlattener(
const Environment * const env,
const tr1::shared_ptr<const PackageID> & pkg) :
- PrivateImplementationPattern<DepSpecFlattener>(new Implementation<DepSpecFlattener>(
- env, pkg))
+ PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >(
+ new Implementation<DepSpecFlattener<Heirarchy_, Item_> >(env, pkg))
{
}
-DepSpecFlattener::~DepSpecFlattener()
+template <typename Heirarchy_, typename Item_>
+DepSpecFlattener<Heirarchy_, Item_>::~DepSpecFlattener()
{
}
-DepSpecFlattener::ConstIterator
-DepSpecFlattener::begin() const
+template <typename Heirarchy_, typename Item_>
+typename DepSpecFlattener<Heirarchy_, Item_>::ConstIterator
+DepSpecFlattener<Heirarchy_, Item_>::begin() const
{
return ConstIterator(_imp->specs.begin());
}
-DepSpecFlattener::ConstIterator
-DepSpecFlattener::end() const
+template <typename Heirarchy_, typename Item_>
+typename DepSpecFlattener<Heirarchy_, Item_>::ConstIterator
+DepSpecFlattener<Heirarchy_, Item_>::end() const
{
return ConstIterator(_imp->specs.end());
}
-void DepSpecFlattener::visit_sequence(const UseDepSpec & u,
- FlattenableSpecTree::ConstSequenceIterator cur,
- FlattenableSpecTree::ConstSequenceIterator e)
+template <typename Heirarchy_, typename Item_>
+void
+DepSpecFlattener<Heirarchy_, Item_>::visit_sequence(const UseDepSpec & u,
+ typename Heirarchy_::ConstSequenceIterator cur,
+ typename Heirarchy_::ConstSequenceIterator e)
{
if (_imp->env->query_use(u.flag(), *_imp->pkg) ^ u.inverse())
std::for_each(cur, e, accept_visitor(*this));
}
-void DepSpecFlattener::visit_leaf(const PlainTextDepSpec & p)
-{
- _imp->specs.push_back(tr1::static_pointer_cast<const StringDepSpec>(p.clone()));
-}
-
-void DepSpecFlattener::visit_leaf(const PackageDepSpec & p)
-{
- _imp->specs.push_back(tr1::static_pointer_cast<const StringDepSpec>(p.clone()));
-}
-
-void DepSpecFlattener::visit_leaf(const BlockDepSpec & p)
-{
- _imp->specs.push_back(tr1::static_pointer_cast<const StringDepSpec>(p.clone()));
-}
-
-void DepSpecFlattener::visit_leaf(const SimpleURIDepSpec & p)
+template <typename Heirarchy_, typename Item_>
+void
+DepSpecFlattener<Heirarchy_, Item_>::visit_leaf(const Item_ & p)
{
- _imp->specs.push_back(tr1::static_pointer_cast<const StringDepSpec>(p.clone()));
+ _imp->specs.push_back(tr1::static_pointer_cast<const Item_>(p.clone()));
}
-void DepSpecFlattener::visit_leaf(const LicenseDepSpec & p)
-{
- _imp->specs.push_back(tr1::static_pointer_cast<const StringDepSpec>(p.clone()));
-}
-
-void DepSpecFlattener::visit_leaf(const FetchableURIDepSpec & p)
-{
- _imp->specs.push_back(tr1::static_pointer_cast<const StringDepSpec>(p.clone()));
-}
+template class DepSpecFlattener<ProvideSpecTree, PackageDepSpec>;
+template class DepSpecFlattener<SetSpecTree, PackageDepSpec>;
+template class DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec>;
+template class DepSpecFlattener<SimpleURISpecTree, SimpleURIDepSpec>;
diff --git a/paludis/dep_spec_flattener.hh b/paludis/dep_spec_flattener.hh
index 68a43b5..a32f12b 100644
--- a/paludis/dep_spec_flattener.hh
+++ b/paludis/dep_spec_flattener.hh
@@ -20,20 +20,25 @@
#ifndef PALUDIS_GUARD_PALUDIS_DEP_ATOM_FLATTENER_HH
#define PALUDIS_GUARD_PALUDIS_DEP_ATOM_FLATTENER_HH 1
-#include <paludis/dep_spec.hh>
-#include <paludis/dep_tree.hh>
#include <paludis/environment-fwd.hh>
#include <paludis/package_id-fwd.hh>
+#include <paludis/dep_spec-fwd.hh>
#include <paludis/util/attributes.hh>
#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/tr1_memory.hh>
+#include <paludis/util/visitor.hh>
#include <libwrapiter/libwrapiter_forward_iterator-fwd.hh>
/** \file
* Declarations for DepSpecFlattener.
*
- * \ingroup grpdepspecflattener
+ * \ingroup g_dep_spec
+ *
+ * \section Examples
+ *
+ * - \ref example_dep_spec_flattener.cc "example_dep_spec_flattener.cc"
*/
namespace paludis
@@ -42,39 +47,41 @@ namespace paludis
* Extract the enabled components of a dep heirarchy for a particular
* package.
*
- * This is useful for picking out SRC_URI, PROVIDE etc components. It is
- * <b>not</b> suitable for heirarchies that can contain || ( ) blocks.
+ * This template can be instantiated as:
+ *
+ * - DepSpecFlattener<ProvideSpecTree, PlainTextDepSpec>
+ * - DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec>
+ * - DepSpecFlattener<SetSpecTree, PackageDepSpec>
+ * - DepSpecFlattener<SimpleURISpecTree, SimpleURIDepSpec>
+ *
+ * It is <b>not</b> suitable for heirarchies that can contain AnyDepSpec
+ * or any kind of label.
*
- * \ingroup grpdepspecflattener
+ * \ingroup g_dep_spec
+ * \since 0.26
* \nosubgrouping
*/
+ template <typename Heirarchy_, typename Item_>
class PALUDIS_VISIBLE DepSpecFlattener :
- private InstantiationPolicy<DepSpecFlattener, instantiation_method::NonCopyableTag>,
- public ConstVisitor<FlattenableSpecTree>,
- public ConstVisitor<FlattenableSpecTree>::VisitConstSequence<DepSpecFlattener, AllDepSpec>,
- private PrivateImplementationPattern<DepSpecFlattener>
+ private InstantiationPolicy<DepSpecFlattener<Heirarchy_, Item_>, instantiation_method::NonCopyableTag>,
+ private PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >,
+ public ConstVisitor<Heirarchy_>,
+ public ConstVisitor<Heirarchy_>::template VisitConstSequence<DepSpecFlattener<Heirarchy_, Item_>, AllDepSpec>
{
+ private:
+ using PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >::_imp;
+
public:
///\name Visit methods
///{
- using ConstVisitor<FlattenableSpecTree>::VisitConstSequence<DepSpecFlattener, AllDepSpec>::visit_sequence;
+ using ConstVisitor<Heirarchy_>::template VisitConstSequence<DepSpecFlattener<Heirarchy_, Item_>, AllDepSpec>::visit_sequence;
void visit_sequence(const UseDepSpec &,
- FlattenableSpecTree::ConstSequenceIterator,
- FlattenableSpecTree::ConstSequenceIterator);
-
- void visit_leaf(const PackageDepSpec &);
-
- void visit_leaf(const PlainTextDepSpec &);
+ typename Heirarchy_::ConstSequenceIterator,
+ typename Heirarchy_::ConstSequenceIterator);
- void visit_leaf(const BlockDepSpec &);
-
- void visit_leaf(const FetchableURIDepSpec &);
-
- void visit_leaf(const SimpleURIDepSpec &);
-
- void visit_leaf(const LicenseDepSpec &);
+ void visit_leaf(const Item_ &);
///}
@@ -89,12 +96,12 @@ namespace paludis
///\}
///\name Iterate over our dep specs
- ///{
+ ///\{
- typedef libwrapiter::ForwardIterator<DepSpecFlattener, const tr1::shared_ptr<const StringDepSpec> > ConstIterator;
+ typedef libwrapiter::ForwardIterator<DepSpecFlattener<Heirarchy_, Item_>,
+ const tr1::shared_ptr<const Item_> > ConstIterator;
ConstIterator begin() const;
-
ConstIterator end() const;
///\}
diff --git a/paludis/dep_tree.cc b/paludis/dep_tree.cc
index d68a758..efdf9f0 100644
--- a/paludis/dep_tree.cc
+++ b/paludis/dep_tree.cc
@@ -53,17 +53,6 @@ template class TreeLeaf<SimpleURISpecTree, SimpleURIDepSpec>;
template class ConstTreeSequence<SimpleURISpecTree, AllDepSpec>;
template class ConstTreeSequence<SimpleURISpecTree, UseDepSpec>;
-template class ConstVisitor<FlattenableSpecTree>;
-template class ConstAcceptInterface<FlattenableSpecTree>;
-template class TreeLeaf<FlattenableSpecTree, PackageDepSpec>;
-template class TreeLeaf<FlattenableSpecTree, BlockDepSpec>;
-template class TreeLeaf<FlattenableSpecTree, PlainTextDepSpec>;
-template class TreeLeaf<FlattenableSpecTree, SimpleURIDepSpec>;
-template class TreeLeaf<FlattenableSpecTree, FetchableURIDepSpec>;
-template class TreeLeaf<FlattenableSpecTree, LicenseDepSpec>;
-template class ConstTreeSequence<FlattenableSpecTree, AllDepSpec>;
-template class ConstTreeSequence<FlattenableSpecTree, UseDepSpec>;
-
template class ConstVisitor<ProvideSpecTree>;
template class ConstAcceptInterface<ProvideSpecTree>;
template class TreeLeaf<ProvideSpecTree, PackageDepSpec>;
diff --git a/paludis/dep_tree.hh b/paludis/dep_tree.hh
index 43fc135..fa48a5c 100644
--- a/paludis/dep_tree.hh
+++ b/paludis/dep_tree.hh
@@ -181,50 +181,6 @@ namespace paludis
};
/**
- * A heirarchy of things that can be flattened.
- *
- * This heirarchy is not constructed; it is only used for declaring
- * certain visitors (e.g. DepSpecFlattener).
- *
- * \see DepSpecFlattener
- * \since 0.26
- * \ingroup g_dep_spec
- * \nosubgrouping
- */
- struct FlattenableSpecTree :
- VisitorTypes<
- FlattenableSpecTree,
- DepSpec,
- TreeLeaf<FlattenableSpecTree, PlainTextDepSpec>,
- TreeLeaf<FlattenableSpecTree, SimpleURIDepSpec>,
- TreeLeaf<FlattenableSpecTree, FetchableURIDepSpec>,
- TreeLeaf<FlattenableSpecTree, PackageDepSpec>,
- TreeLeaf<FlattenableSpecTree, BlockDepSpec>,
- TreeLeaf<FlattenableSpecTree, LicenseDepSpec>,
- ConstTreeSequence<FlattenableSpecTree, AllDepSpec>,
- ConstTreeSequence<FlattenableSpecTree, UseDepSpec>
- >
- {
- /**
- * A formatter that can handle any formattable type found in a
- * FlattenableSpecTree.
- *
- * \ingroup g_dep_spec
- * \since 0.26
- * \nosubgrouping
- */
- typedef Formatter<
- UseDepSpec,
- PlainTextDepSpec,
- SimpleURIDepSpec,
- FetchableURIDepSpec,
- LicenseDepSpec,
- PackageDepSpec,
- BlockDepSpec
- > Formatter;
- };
-
- /**
* A heirarchy of provided packages.
*
* \ingroup g_dep_spec
diff --git a/paludis/repositories/e/e_key.cc b/paludis/repositories/e/e_key.cc
index 540aac3..4d8ec55 100644
--- a/paludis/repositories/e/e_key.cc
+++ b/paludis/repositories/e/e_key.cc
@@ -362,10 +362,10 @@ EFetchableURIKey::initial_label() const
if (! _imp->initial_label)
{
- DepSpecFlattener f(_imp->env, _imp->id);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> f(_imp->env, _imp->id);
if (_imp->id->restrict_key())
_imp->id->restrict_key()->value()->accept(f);
- for (DepSpecFlattener::ConstIterator i(f.begin()), i_end(f.end()) ;
+ for (DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec>::ConstIterator i(f.begin()), i_end(f.end()) ;
i != i_end ; ++i)
{
if (_imp->id->eapi()->supported->ebuild_options->restrict_fetch->end() !=
diff --git a/paludis/repositories/e/ebuild_entries.cc b/paludis/repositories/e/ebuild_entries.cc
index cf2d02f..e00b2ab 100644
--- a/paludis/repositories/e/ebuild_entries.cc
+++ b/paludis/repositories/e/ebuild_entries.cc
@@ -281,11 +281,11 @@ EbuildEntries::fetch(const tr1::shared_ptr<const ERepositoryID> & id,
bool fetch_restrict(false);
{
- DepSpecFlattener restricts(_imp->params.environment, id);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, id);
if (id->restrict_key())
id->restrict_key()->value()->accept(restricts);
- for (DepSpecFlattener::ConstIterator i(restricts.begin()), i_end(restricts.end()) ;
+ for (DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec>::ConstIterator i(restricts.begin()), i_end(restricts.end()) ;
i != i_end ; ++i)
if (id->eapi()->supported->ebuild_options->restrict_fetch->end() !=
std::find(id->eapi()->supported->ebuild_options->restrict_fetch->begin(),
@@ -443,7 +443,7 @@ EbuildEntries::install(const tr1::shared_ptr<const ERepositoryID> & id,
bool userpriv_restrict;
{
- DepSpecFlattener restricts(_imp->params.environment, id);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, id);
if (id->restrict_key())
id->restrict_key()->value()->accept(restricts);
@@ -637,7 +637,7 @@ EbuildEntries::info(const tr1::shared_ptr<const ERepositoryID> & id,
bool userpriv_restrict;
{
- DepSpecFlattener restricts(_imp->params.environment, id);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, id);
if (id->restrict_key())
id->restrict_key()->value()->accept(restricts);
diff --git a/paludis/repositories/e/vdb_repository.cc b/paludis/repositories/e/vdb_repository.cc
index 7b2ccb3..26edb50 100644
--- a/paludis/repositories/e/vdb_repository.cc
+++ b/paludis/repositories/e/vdb_repository.cc
@@ -876,12 +876,12 @@ VDBRepository::load_provided_using_cache() const
continue;
}
- DepSpecFlattener f(_imp->params.environment, id);
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->params.environment, id);
tr1::shared_ptr<ProvideSpecTree::ConstItem> pp(parse_provide(
join(next(next(tokens.begin())), tokens.end(), " "), *EAPIData::get_instance()->eapi_from_string("paludis-1")));
pp->accept(f);
- for (DepSpecFlattener::ConstIterator p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
+ for (DepSpecFlattener<ProvideSpecTree, PackageDepSpec>::ConstIterator p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
result->push_back(RepositoryProvidesEntry::create()
.virtual_name(QualifiedPackageName((*p)->text()))
.provided_by(id));
@@ -925,10 +925,11 @@ VDBRepository::load_provided_the_slow_way() const
continue;
tr1::shared_ptr<const ProvideSpecTree::ConstItem> provide((*e)->provide_key()->value());;
- DepSpecFlattener f(_imp->params.environment, *e);
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->params.environment, *e);
provide->accept(f);
- for (DepSpecFlattener::ConstIterator p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
+ for (DepSpecFlattener<ProvideSpecTree, PackageDepSpec>::ConstIterator
+ p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
{
QualifiedPackageName pp((*p)->text());
diff --git a/paludis/repositories/fake/fake_installed_repository.cc b/paludis/repositories/fake/fake_installed_repository.cc
index 9ced042..7a87d69 100644
--- a/paludis/repositories/fake/fake_installed_repository.cc
+++ b/paludis/repositories/fake/fake_installed_repository.cc
@@ -87,10 +87,10 @@ FakeInstalledRepository::provided_packages() const
if (! (*v)->provide_key())
continue;
- DepSpecFlattener f(environment(), *v);
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(environment(), *v);
(*v)->provide_key()->value()->accept(f);
- for (DepSpecFlattener::ConstIterator q(f.begin()), q_end(f.end()) ; q != q_end ; ++q)
+ for (DepSpecFlattener<ProvideSpecTree, PackageDepSpec>::ConstIterator q(f.begin()), q_end(f.end()) ; q != q_end ; ++q)
result->push_back(RepositoryProvidesEntry::create()
.virtual_name(QualifiedPackageName((*q)->text()))
.provided_by(*v));
diff --git a/paludis/tasks/uninstall_task.cc b/paludis/tasks/uninstall_task.cc
index bd863a1..7a774ab 100644
--- a/paludis/tasks/uninstall_task.cc
+++ b/paludis/tasks/uninstall_task.cc
@@ -82,7 +82,7 @@ namespace paludis
UninstallActionOptions uninstall_options;
std::list<std::string> raw_targets;
- std::list<tr1::shared_ptr<PackageDepSpec> > targets;
+ std::list<tr1::shared_ptr<const PackageDepSpec> > targets;
bool pretend;
bool preserve_world;
@@ -175,11 +175,9 @@ UninstallTask::add_target(const std::string & target)
throw MultipleSetTargetsSpecified();
_imp->had_set_targets = true;
- DepSpecFlattener f(_imp->env, tr1::shared_ptr<const PackageID>());
+ DepSpecFlattener<SetSpecTree, PackageDepSpec> f(_imp->env, tr1::shared_ptr<const PackageID>());
spec->accept(f);
- for (DepSpecFlattener::ConstIterator i(f.begin()), i_end(f.end()) ; i != i_end ; ++i)
- _imp->targets.push_back(tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(
- stringify((*i)->text()), pds_pm_permissive)));
+ std::copy(f.begin(), f.end(), std::back_inserter(_imp->targets));
}
else
{
@@ -242,7 +240,7 @@ UninstallTask::execute()
if (_imp->unused)
list.add_unused();
else
- for (std::list<tr1::shared_ptr<PackageDepSpec> >::const_iterator t(_imp->targets.begin()),
+ for (std::list<tr1::shared_ptr<const PackageDepSpec> >::const_iterator t(_imp->targets.begin()),
t_end(_imp->targets.end()) ; t != t_end ; ++t)
{
Context local_context("When looking for target '" + stringify(**t) + "':");
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index d7e8cf2..c41c93a 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -57,4 +57,5 @@ add(`util', `hh')
add(`validated', `hh', `fwd', `test')
add(`virtual_constructor', `hh', `impl', `test')
add(`visitor', `hh', `impl', `fwd', `test')
+add(`visitor_cast', `hh', `test')
diff --git a/paludis/util/visitor_cast.hh b/paludis/util/visitor_cast.hh
new file mode 100644
index 0000000..50090cf
--- /dev/null
+++ b/paludis/util/visitor_cast.hh
@@ -0,0 +1,191 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_VISITOR_CAST_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_VISITOR_CAST_HH 1
+
+#include <paludis/util/visitor.hh>
+#include <paludis/util/tr1_type_traits.hh>
+
+namespace paludis
+{
+ namespace visitor_cast_internals
+ {
+ template <typename T_, bool b_>
+ struct GetResult
+ {
+ static T_ * get(const void * const)
+ {
+ return 0;
+ }
+ };
+
+ template <typename T_>
+ struct GetResult<T_, true>
+ {
+ static T_ * get(const T_ * const t)
+ {
+ return t;
+ }
+ };
+
+ template <typename Result_, typename Heirarchy_, typename Item_>
+ struct VisitorCastVisitorVisits :
+ virtual visitor_internals::Visits<const Item_>
+ {
+ Result_ * & result;
+
+ VisitorCastVisitorVisits(Result_ * & r) :
+ result(r)
+ {
+ }
+
+ void visit(const Item_ & i)
+ {
+ result = GetResult<const Result_, tr1::is_same<const Result_, const Item_>::value>::get(&i);
+ }
+ };
+
+ template <typename Result_, typename Heirarchy_, unsigned u_>
+ struct VisitorCastVisitorVisits<Result_, Heirarchy_, const NoType<u_> >
+ {
+ VisitorCastVisitorVisits(Result_ * &)
+ {
+ }
+ };
+
+ template <typename Result_, typename Heirarchy_, typename Item_>
+ struct VisitorCastVisitorVisits<Result_, Heirarchy_, const TreeLeaf<Heirarchy_, Item_> > :
+ virtual visitor_internals::Visits<const TreeLeaf<Heirarchy_, Item_> >
+ {
+ Result_ * & result;
+
+ VisitorCastVisitorVisits(Result_ * & r) :
+ result(r)
+ {
+ }
+
+ void visit_leaf(const Item_ & i)
+ {
+ result = GetResult<const Result_, tr1::is_same<const Result_, const Item_>::value>::get(&i);
+ }
+ };
+
+ template <typename Result_, typename Heirarchy_, typename Item_>
+ struct VisitorCastVisitorVisits<Result_, Heirarchy_, const ConstTreeSequence<Heirarchy_, Item_> > :
+ virtual visitor_internals::Visits<const ConstTreeSequence<Heirarchy_, Item_> >
+ {
+ Result_ * & result;
+
+ VisitorCastVisitorVisits(Result_ * & r) :
+ result(r)
+ {
+ }
+
+ void visit_sequence(const Item_ & i,
+ typename Heirarchy_::ConstSequenceIterator,
+ typename Heirarchy_::ConstSequenceIterator)
+ {
+ result = GetResult<const Result_, tr1::is_same<const Result_, const Item_>::value>::get(&i);
+ }
+ };
+
+ template <typename Result_, typename Heirarchy_, typename Item_>
+ struct VisitorCastVisitorVisits<Result_, Heirarchy_, const TreeSequence<Heirarchy_, Item_> > :
+ virtual visitor_internals::Visits<const TreeSequence<Heirarchy_, Item_> >
+ {
+ Result_ * & result;
+
+ VisitorCastVisitorVisits(Result_ * & r) :
+ result(r)
+ {
+ }
+
+ void visit_sequence(const Item_ & i,
+ typename Heirarchy_::SequenceIterator,
+ typename Heirarchy_::SequenceIterator)
+ {
+ result = GetResult<const Result_, tr1::is_same<const Result_, const Item_>::value>::get(&i);
+ }
+ };
+
+ template <typename Result_, typename Heirarchy_>
+ struct VisitorCastVisitor :
+ ConstVisitor<Heirarchy_>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem1>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem2>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem3>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem4>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem5>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem6>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem7>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem8>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem9>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem10>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem11>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem12>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem13>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem14>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem15>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem16>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem17>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem18>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem19>,
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem20>
+ {
+ Result_ * result;
+
+ VisitorCastVisitor() :
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem1>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem2>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem3>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem4>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem5>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem6>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem7>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem8>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem9>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem10>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem11>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem12>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem13>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem14>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem15>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem16>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem17>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem18>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem19>(result),
+ VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem20>(result),
+ result(0)
+ {
+ }
+ };
+ }
+
+ template <typename Result_, typename Item_>
+ Result_ *
+ visitor_cast(const Item_ & h)
+ {
+ visitor_cast_internals::VisitorCastVisitor<Result_, typename Item_::Heirarchy> v;
+ h.accept(v);
+ return v.result;
+ }
+}
+
+#endif
diff --git a/python/dep_spec.cc b/python/dep_spec.cc
index 433caf9..54abcce 100644
--- a/python/dep_spec.cc
+++ b/python/dep_spec.cc
@@ -791,13 +791,6 @@ struct NiceClassNames<SimpleURISpecTree>
const char * NiceClassNames<SimpleURISpecTree>::name = "SimpleURISpecTree";
template<>
-struct NiceClassNames<FlattenableSpecTree>
-{
- static const char * name;
-};
-const char * NiceClassNames<FlattenableSpecTree>::name = "FlattenableSpecTree";
-
-template<>
struct NiceClassNames<ProvideSpecTree>
{
static const char * name;
@@ -1269,7 +1262,6 @@ void expose_dep_spec()
register_tree_to_python<SimpleURISpecTree>();
register_tree_to_python<LicenseSpecTree>();
register_tree_to_python<SetSpecTree>();
- register_tree_to_python<FlattenableSpecTree>();
RegisterSpecTreeSPTRFromPython<DependencySpecTree>();
RegisterSpecTreeSPTRFromPython<ProvideSpecTree>();
@@ -1278,7 +1270,6 @@ void expose_dep_spec()
RegisterSpecTreeSPTRFromPython<SimpleURISpecTree>();
RegisterSpecTreeSPTRFromPython<LicenseSpecTree>();
RegisterSpecTreeSPTRFromPython<SetSpecTree>();
- RegisterSpecTreeSPTRFromPython<FlattenableSpecTree>();
/**
* DepSpec
diff --git a/src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc b/src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc
index 42717be..52e72df 100644
--- a/src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc
+++ b/src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc
@@ -253,7 +253,7 @@ PackagesListModel::populate_in_paludis_thread()
}
else if (_imp->packages_page->get_set())
{
- DepSpecFlattener f(_imp->main_window->environment(), tr1::shared_ptr<const PackageID>());
+ DepSpecFlattener<SetSpecTree, PackageDepSpec> f(_imp->main_window->environment(), tr1::shared_ptr<const PackageID>());
_imp->main_window->environment()->set(*_imp->packages_page->get_set())->accept(f);
std::set<std::string> a;
std::transform(indirect_iterator(f.begin()), indirect_iterator(f.end()), std::inserter(a, a.begin()),