[Aptitude-svn-commit] r3848 - in branches/aptitude-0.3/aptitude: . src/generic/problemresolver

Daniel Burrows dburrows at costa.debian.org
Mon Aug 15 20:25:44 UTC 2005


Author: dburrows
Date: Mon Aug 15 20:25:41 2005
New Revision: 3848

Added:
   branches/aptitude-0.3/aptitude/src/generic/problemresolver/dummy_universe.cc
   branches/aptitude-0.3/aptitude/src/generic/problemresolver/dummy_universe.h
Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/problemresolver/Makefile.am
   branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc
Log:
Split out the dummy universe.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Mon Aug 15 20:25:41 2005
@@ -1,5 +1,10 @@
 2005-08-15  Daniel Burrows  <dburrows at debian.org>
 
+	* src/generic/problemresolver/Makefile.am, src/generic/problemresolver/dummy_universe.cc, src/generic/problemresolver/dummy_universe.h, src/generic/problemresolver/test.cc:
+
+	  Split the dummy universe out of the resolver test program so
+	  that it can be used by other code.
+
 	* src/generic/Makefile.am:
 
 	  Add exceptions.h to Makefile.am.

Modified: branches/aptitude-0.3/aptitude/src/generic/problemresolver/Makefile.am
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/problemresolver/Makefile.am	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/problemresolver/Makefile.am	Mon Aug 15 20:25:41 2005
@@ -4,4 +4,6 @@
 
 noinst_PROGRAMS=test
 
-test_SOURCES=test.cc dump_universe.h exceptions.h problemresolver.h solution.h
+test_SOURCES=test.cc dump_universe.h \
+	dummy_universe.cc dummy_universe.h \
+	exceptions.h problemresolver.h solution.h

Added: branches/aptitude-0.3/aptitude/src/generic/problemresolver/dummy_universe.cc
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/generic/problemresolver/dummy_universe.cc	Mon Aug 15 20:25:41 2005
@@ -0,0 +1,152 @@
+// dummy_universe.cc
+//
+//   Copyright (C) 2005 Daniel Burrows
+//
+//   This program is free software; you can redistribute it and/or
+//   modify it under the terms of the GNU General Public License as
+//   published by the Free Software Foundation; either version 2 of
+//   the License, or (at your option) any later version.
+//
+//   This program 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; see the file COPYING.  If not, write to
+//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+//   Boston, MA 02111-1307, USA.
+
+#include "dummy_universe.h"
+
+using namespace std;
+
+dummy_package::dummy_package(const string &_name, unsigned int id)
+  :name(_name), ID(id)
+{
+}
+
+dummy_package::~dummy_package()
+{
+  for(version_iterator i=versions.begin(); i!=versions.end(); ++i)
+    delete *i;
+}
+
+dummy_version *dummy_package::version_from_name(const string &the_name) const
+{
+  for(version_iterator i=versions.begin(); i!=versions.end(); ++i)
+    if((*i)->get_name()==the_name)
+      return *i;
+
+  throw NoSuchNameError("version of package "+name, the_name);
+}
+
+bool dummy_dep::broken() const
+{
+  if(source->get_package().current_version() != *source)
+    return false;
+
+  for(solver_iterator i=target_set.begin();
+      i!=target_set.end(); ++i)
+    if((*i)->get_package().current_version() == **i)
+      return false;
+
+  return true;
+}
+
+dummy_universe::~dummy_universe()
+{
+  for(vector<dummy_package *>::const_iterator i=packages.begin();
+      i!=packages.end(); ++i)
+    delete *i;
+
+  for(vector<dummy_dep *>::const_iterator i=deps.begin();
+      i!=deps.end(); ++i)
+    delete *i;
+}
+
+
+void dummy_universe::add_package(const string &name,
+				 vector<string> the_versions,
+				 const string &curname)
+{
+  assert(!the_versions.empty());
+
+  packages.push_back(new dummy_package(name, packages.size()));
+
+  for(vector<string>::const_iterator i=the_versions.begin();
+      i!=the_versions.end(); ++i)
+    {
+      versions.push_back(new dummy_version(*i, packages.back(), versions.size()));
+      packages.back()->add_version(versions.back());
+    }
+
+  packages.back()->set_current_version(packages.back()->version_from_name(curname));
+
+  packages_by_name[name]=packages.back();
+}
+
+void dummy_universe::add_dep(const string &pkg_name, const string &pkg_ver,
+			     const vector<pair<string, string> > &target_names,
+			     bool is_conflict, bool is_soft)
+{
+  dummy_package *pkg=find_package_internal(pkg_name);
+
+  set<dummy_version *, compare_dummy_versions> targets;
+  set<dummy_package *, compare_dummy_packages> packages;
+
+  for(vector<pair<string, string> >::const_iterator i=target_names.begin();
+      i!=target_names.end(); ++i)
+    {
+      dummy_package *pkg=find_package_internal(i->first);
+
+      packages.insert(pkg);
+      targets.insert(pkg->version_from_name(i->second));
+    }
+
+  if(!is_conflict)
+    deps.push_back(new dummy_dep(pkg->version_from_name(pkg_ver),
+				 vector<dummy_version *>(targets.begin(), targets.end()),
+				 deps.size(),
+				 is_soft));
+  else
+    {
+      set<dummy_version *> targets2;
+
+      for(set<dummy_package *>::const_iterator i=packages.begin();
+	  i!=packages.end(); ++i)
+	for(dummy_package::version_iterator j=(*i)->versions_begin();
+	    j!=(*i)->versions_end(); ++j)
+	  if(targets.find(*j)==targets.end())
+	    targets2.insert(*j);
+
+      deps.push_back(new dummy_dep(pkg->version_from_name(pkg_ver),
+				   vector<dummy_version *>(targets2.begin(), targets2.end()),
+				   deps.size(),
+				   is_soft));
+    }
+
+  dummy_dep *newdep=deps.back();
+
+  newdep->get_source().add_dep(newdep);
+
+  for(dummy_dep::solver_iterator i=newdep->solvers_begin();
+      i!=newdep->solvers_end(); ++i)
+    (*i)->add_revdep(newdep);
+}
+
+
+ostream &operator<<(ostream &out, const dummy_universe::dep &d)
+{
+  out << d.get_source().get_package().get_name() << " " << d.get_source().get_name() << " -> {";
+  for(dummy_universe::dep::solver_iterator i=d.solvers_begin();
+      !i.end(); ++i)
+    {
+      if(i!=d.solvers_begin())
+	out << ", ";
+      out << (*i).get_package().get_name() << " " << (*i).get_name();
+    }
+  out << "}";
+
+  return out;
+}

Added: branches/aptitude-0.3/aptitude/src/generic/problemresolver/dummy_universe.h
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/generic/problemresolver/dummy_universe.h	Mon Aug 15 20:25:41 2005
@@ -0,0 +1,730 @@
+// dummy_universe.h                               -*-c++-*-
+//
+//   Copyright (C) 2005 Daniel Burrows
+//
+//   This program is free software; you can redistribute it and/or
+//   modify it under the terms of the GNU General Public License as
+//   published by the Free Software Foundation; either version 2 of
+//   the License, or (at your option) any later version.
+//
+//   This program 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; see the file COPYING.  If not, write to
+//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+//   Boston, MA 02111-1307, USA.
+//
+// A package dependency universe that's not terribly efficient, but
+// easy to set up for testing.
+
+#ifndef DUMMY_UNIVERSE_H
+#define DUMMY_UNIVERSE_H
+
+#include <iostream>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "../exception.h"
+
+// An error type that's thrown when a name lookup fails.
+class NoSuchNameError:public Exception
+{
+  std::string name;
+  std::string type;
+public:
+  NoSuchNameError(const std::string &_type, const std::string &_name)
+    :name(_name), type(_type) {}
+
+  std::string errmsg() const {return "No "+type+" named "+name;}
+};
+
+template<class T1, class T2>
+class wrap_ptr_iter
+{
+  typename std::vector<T1 *>::const_iterator realiter, realend;
+public:
+  wrap_ptr_iter(const std::vector<T1 *> &parent)
+    :realiter(parent.begin()), realend(parent.end())
+  {
+  }
+
+  wrap_ptr_iter(const typename std::vector<T1 *>::const_iterator &begin,
+		const typename std::vector<T1 *>::const_iterator &end)
+    :realiter(begin), realend(end)
+  {
+  }
+
+  bool operator==(const wrap_ptr_iter &other) const
+  {
+    return realiter==other.realiter;
+  }
+
+  bool operator!=(const wrap_ptr_iter &other) const
+  {
+    return realiter!=other.realiter;
+  }
+
+  bool end() const
+  {
+    return realiter == realend;
+  }
+
+  wrap_ptr_iter &operator++()
+  {
+    ++realiter;
+    return *this;
+  }
+
+  const T2 operator*() const
+  {
+    return T2(*realiter);
+  }
+};
+
+class dummy_universe;
+class dummy_version;
+
+/** A dummy package type */
+class dummy_package
+{
+  /** The name of the package is not used by the generic algorithm,
+   *  but is used as helpful output from the test cases.
+   */
+  std::string name;
+
+  /** The versions of this package.  The first entry in this list is
+   *  the current version.
+   */
+  std::vector<dummy_version *> versions;
+
+  /** The current version of this package; defaults to the first
+   *  element of "versions".
+   */
+  dummy_version *cur;
+
+  /** The ID of this version. */
+  unsigned int ID;
+
+  dummy_package(const dummy_package &other);
+public:
+  typedef std::vector<dummy_version *>::const_iterator version_iterator;
+
+  /** Creates a dummy package. */
+  dummy_package(const std::string &_name, unsigned int id);
+
+  virtual ~dummy_package();
+
+  std::string get_name() const {return name;}
+  unsigned int get_id() const {return ID;}
+
+  /** Dummy packages are equivalent iff they are the same object. */
+  bool operator==(const dummy_package &other) const
+  {
+    return this == &other;
+  }
+
+  bool operator!=(const dummy_package &other) const
+  {
+    return this != &other;
+  }
+
+  bool operator<(const dummy_package &other) const
+  {
+    return ID < other.ID;
+  }
+
+  void add_version(dummy_version *version)
+  {
+    if(versions.empty())
+      cur=version;
+    versions.push_back(version);
+  }
+
+  const dummy_version &current_version() const {return *cur;}
+  version_iterator versions_begin() const {return versions.begin();}
+  version_iterator versions_end() const {return versions.end();}
+
+  /** Returns the version corresponding to the given name or aborts */
+  dummy_version *version_from_name(const std::string &the_name) const;
+
+  /** Sets the current version to the given version. */
+  void set_current_version(dummy_version *v)
+  {
+    cur=v;
+  }
+};
+
+class dummy_dep;
+
+/** A dummy version type */
+class dummy_version
+{
+  std::string name;
+
+  const dummy_package *package;
+
+  std::vector<dummy_dep *> revdeps;
+  std::vector<dummy_dep *> deps;
+
+  /** The numerical ID of this version. */
+  int ID;
+
+  dummy_version(const dummy_version &other);
+public:
+  typedef std::vector<dummy_dep *>::const_iterator revdep_iterator;
+  typedef std::vector<dummy_dep *>::const_iterator dep_iterator;
+
+  dummy_version(const std::string &_name, const dummy_package *_package,
+		unsigned int id)
+    :name(_name), package(_package), ID(id)
+  {
+  }
+
+  std::string get_name() const {return name;}
+  unsigned int get_id() const {return ID;}
+
+  bool operator==(const dummy_version &other) const
+  {
+    return this == &other;
+  }
+
+  bool operator!=(const dummy_version &other) const
+  {
+    return this != &other;
+  }
+
+  bool operator<(const dummy_version &other) const
+  {
+    return ID < other.ID;
+  }
+
+  void add_revdep(dummy_dep *dep)
+  {
+    revdeps.push_back(dep);
+  }
+
+  void add_dep(dummy_dep *dep)
+  {
+    deps.push_back(dep);
+  }
+
+  const dummy_package &get_package() const {return *package;}
+
+  revdep_iterator revdeps_begin() const {return revdeps.begin();}
+  revdep_iterator revdeps_end() const {return revdeps.end();}
+
+  dep_iterator deps_begin() const {return deps.begin();}
+  dep_iterator deps_end() const {return deps.end();}
+};
+
+/** Indicates that either package_1 depends upon package_2 or
+ *  package_1 conflicts with package_2.
+ */
+class dummy_dep
+{
+  dummy_version *source;
+  std::vector<dummy_version *> target_set;
+
+  dummy_dep(const dummy_dep &other);
+
+  unsigned int ID;
+
+  bool soft;
+public:
+  typedef std::vector<dummy_version *>::const_iterator solver_iterator;
+
+  dummy_dep(dummy_version *_source,
+	    const std::vector<dummy_version *> &_target_set,
+	    unsigned int _ID, bool _soft)
+    :source(_source), target_set(_target_set), ID(_ID), soft(_soft)
+  {
+  }
+
+  bool is_soft() const
+  {
+    return soft;
+  }
+
+  bool operator==(const dummy_dep &other) const
+  {
+    return this==&other;
+  }
+
+  bool operator!=(const dummy_dep &other) const
+  {
+    return this!=&other;
+  }
+
+  bool operator<(const dummy_dep &other) const
+  {
+    return ID<other.ID;
+  }
+
+  dummy_version &get_source() const {return *source;}
+
+  solver_iterator solvers_begin() const
+  {
+    return target_set.begin();
+  }
+
+  solver_iterator solvers_end() const
+  {
+    return target_set.end();
+  }
+
+  /** Not part of the generic interface (although it could be);
+   *  returns \b true if the dep is not satisfied in the global
+   *  state (i.e., ignores any solution computation in progress).
+   */
+  bool broken() const;
+};
+
+/** Represents the world of all packages and dependencies. */
+class dummy_universe
+{
+public:
+  class version;
+  class dep;
+
+  class package
+  {
+    const dummy_package *real_package;
+  public:
+    package():real_package(0) {}
+    package(const dummy_package *_real_package)
+      :real_package(_real_package)
+    {
+    }
+
+    typedef wrap_ptr_iter<dummy_version, version> version_iterator;
+
+    bool operator==(const package &other) const
+    {
+      return real_package==other.real_package;
+    }
+
+    bool operator!=(const package &other) const
+    {
+      return real_package!=other.real_package;
+    }
+
+    bool operator<(const package &other) const
+    {
+      return (*real_package)<(*other.real_package);
+    }
+
+    std::string get_name() const
+    {
+      return real_package->get_name();
+    }
+
+    unsigned int get_id() const
+    {
+      return real_package->get_id();
+    }
+
+    version current_version() const
+    {
+      return version(&real_package->current_version());
+    }
+
+    version version_from_name(const std::string &name) const
+    {
+      return version(real_package->version_from_name(name));
+    }
+
+    wrap_ptr_iter<dummy_version, version> versions_begin() const
+    {
+      return wrap_ptr_iter<dummy_version, version>(real_package->versions_begin(), real_package->versions_end());
+    }
+  };
+
+  class version
+  {
+    const dummy_version *real_version;
+  public:
+    typedef wrap_ptr_iter<dummy_dep, dep> revdep_iterator;
+    typedef wrap_ptr_iter<dummy_dep, dep> dep_iterator;
+
+    version():real_version(0) {}
+    version(const dummy_version *_real_version)
+      :real_version(_real_version)
+    {
+    }
+
+    bool operator==(const version &other) const
+    {
+      return real_version==other.real_version;
+    }
+
+    bool operator!=(const version &other) const
+    {
+      return real_version!=other.real_version;
+    }
+
+    bool operator<(const version &other) const
+    {
+      return (*real_version)<(*other.real_version);
+    }
+
+    package get_package() const
+    {
+      return package(&real_version->get_package());
+    }
+
+    std::string get_name() const
+    {
+      return real_version->get_name();
+    }
+
+    unsigned int get_id() const
+    {
+      return real_version->get_id();
+    }
+
+    wrap_ptr_iter<dummy_dep, dep> revdeps_begin() const
+    {
+      return wrap_ptr_iter<dummy_dep, dep>(real_version->revdeps_begin(),
+					   real_version->revdeps_end());
+    }
+
+    wrap_ptr_iter<dummy_dep, dep> deps_begin() const
+    {
+      return wrap_ptr_iter<dummy_dep, dep>(real_version->deps_begin(),
+					   real_version->deps_end());
+    }
+  };
+
+
+  class dep
+  {
+    const dummy_dep *real_dep;
+  public:
+    dep():real_dep(0) {}
+    dep(const dummy_dep *_real_dep)
+      :real_dep(_real_dep)
+    {
+    }
+    dep(const dep &other)
+      :real_dep(other.real_dep)
+    {
+    }
+
+    typedef wrap_ptr_iter<dummy_version, version> solver_iterator;
+
+    bool is_soft() const
+    {
+      return real_dep->is_soft();
+    }
+
+    bool operator==(const dep &other) const
+    {
+      return real_dep==other.real_dep;
+    }
+
+    bool operator!=(const dep &other) const
+    {
+      return real_dep!=other.real_dep;
+    }
+
+    bool operator<(const dep &other) const
+    {
+      return (*real_dep)<(*other.real_dep);
+    }
+
+    version get_source() const
+    {
+      return version(&real_dep->get_source());
+    }
+
+    wrap_ptr_iter<dummy_version, version> solvers_begin() const
+    {
+      return wrap_ptr_iter<dummy_version, version>(real_dep->solvers_begin(),
+						   real_dep->solvers_end());
+    }
+
+    template<class Sol>
+    bool broken_under(const Sol& s) const
+    {
+      if(s.version_of(get_source().get_package()) != get_source())
+	return false;
+
+      for(dummy_dep::solver_iterator i=real_dep->solvers_begin();
+	  i!=real_dep->solvers_end(); ++i)
+	if(s.version_of(version(*i).get_package()) == version(*i))
+	  return false;
+
+      return true;
+    }
+  };
+
+
+  typedef wrap_ptr_iter<dummy_package, package> package_iterator;
+  typedef wrap_ptr_iter<dummy_dep, dep> dep_iterator;
+
+  /** Finds broken dependencies. */
+  class broken_dep_iterator
+  {
+    std::vector<dummy_dep *>::const_iterator realiter;
+    std::vector<dummy_dep *>::const_iterator realend;
+  public:
+    broken_dep_iterator(const std::vector<dummy_dep *>::const_iterator &_realiter,
+			const std::vector<dummy_dep *>::const_iterator &_realend)
+      :realiter(_realiter), realend(_realend)
+    {
+      while(realiter!=realend && !(*realiter)->broken())
+	++realiter;
+    }
+
+    bool operator==(const broken_dep_iterator &other) const
+    {
+      return realiter==other.realiter;
+    }
+
+    bool operator!=(const broken_dep_iterator &other) const
+    {
+      return realiter!=other.realiter;
+    }
+
+    bool end() const
+    {
+      return realiter == realend;
+    }
+
+    const dep operator*() const
+    {
+      assert(realiter!=realend);
+      return *realiter;
+    }
+
+    broken_dep_iterator &operator++()
+    {
+      if(realiter!=realend)
+	++realiter;
+
+      while(realiter!=realend && !(*realiter)->broken())
+	++realiter;
+
+      return *this;
+    }
+  };
+
+private:
+  /** All the packages in the universe. */
+  std::vector<dummy_package *> packages;
+  /** All the dependencies in the universe. */
+  std::vector<dummy_dep *> deps;
+  /** All the versions in the universe. */
+  std::vector<dummy_version *> versions;
+
+  /** Indexes packages by name. */
+  std::map<std::string, dummy_package *> packages_by_name;
+
+  struct compare_dummy_packages
+  {
+    bool operator()(dummy_package *p1, dummy_package *p2)
+    {
+      return p1->get_id() < p2->get_id();
+    }
+  };
+
+  struct compare_dummy_versions
+  {
+    bool operator()(dummy_version *v1, dummy_version *v2)
+    {
+      return v1->get_id() < v2->get_id();
+    }
+  };
+
+  dummy_package *find_package_internal(const std::string &pkg_name)
+  {
+    std::map<std::string, dummy_package *>::const_iterator pfound=packages_by_name.find(pkg_name);
+
+    if(pfound==packages_by_name.end())
+      throw NoSuchNameError("package", pkg_name);
+
+    return pfound->second;
+  }
+
+public:
+  virtual ~dummy_universe();
+
+  /** Lo, and it was a void, without form. */
+  dummy_universe() {}
+
+  /** Add a package to the universe.
+   *
+   *  \param name the name of the new package.
+   *  \param the_versions the names of the versions of that package.
+   *         The first element of the list is the current version.
+   */
+  void add_package(const std::string &name,
+		   std::vector<std::string> the_versions,
+		   const std::string &curname);
+
+  /** Find a package by name. */
+  package find_package(const std::string &pkg_name)
+  {
+    return find_package_internal(pkg_name);
+  }
+
+  /** Add a dependency to the universe.  For convenience
+   *  this is std::string-based.
+   */
+  void add_dep(const std::string &pkg_name, const std::string &pkg_ver,
+	       const std::vector<std::pair<std::string, std::string> > &target_names,
+	       bool is_conflict, bool is_soft);
+
+  std::vector<package>::size_type get_package_count() const
+  {
+    return packages.size();
+  }
+
+  std::vector<version>::size_type get_version_count() const
+  {
+    return versions.size();
+  }
+
+  package_iterator packages_begin() const
+  {
+    return packages;
+  }
+
+  dep_iterator deps_begin() const
+  {
+    return deps;
+  }
+
+  broken_dep_iterator broken_begin() const
+  {
+    return broken_dep_iterator(deps.begin(), deps.end());
+  }
+};
+
+// A refcounting wrapper for a dummy_universe; used to sanitize memory
+// management without copying all over (and because the resolver
+// expects to be able to have a full copy of its argument type)
+class dummy_universe_ref
+{
+  struct _rep
+  {
+    int refcount;
+    dummy_universe *universe;
+
+    /** Start with 1 ref since our creator holds a ref. */
+    _rep(dummy_universe *_universe)
+      :refcount(1), universe(_universe)
+    {
+    }
+
+    void incref() {++refcount;}
+    void decref() {--refcount; if(refcount==0) delete this;}
+  };
+
+  _rep *rep;
+public:
+  typedef dummy_universe::package package;
+  typedef dummy_universe::version version;
+  typedef dummy_universe::dep dep;
+  typedef dummy_universe::package_iterator package_iterator;
+  typedef dummy_universe::dep_iterator dep_iterator;
+  typedef dummy_universe::broken_dep_iterator broken_dep_iterator;
+
+  dummy_universe_ref()
+    :rep(NULL)
+  {
+  }
+
+  dummy_universe_ref(const dummy_universe_ref &other)
+    :rep(other.rep)
+  {
+    if(rep)
+      rep->incref();
+  }
+
+  /** Assumes this is the first reference to the universe. */
+  dummy_universe_ref(dummy_universe *universe)
+    :rep(new _rep(universe))
+  {
+  }
+
+  ~dummy_universe_ref()
+  {
+    if(rep)
+      rep->decref();
+  }
+
+  dummy_universe_ref &operator=(const dummy_universe_ref &other)
+  {
+    if(other.rep)
+      other.rep->incref();
+    if(rep)
+      rep->decref();
+    rep=other.rep;
+
+    return *this;
+  }
+
+  operator void*() const
+  {
+    return (void *) (rep && rep->universe);
+  }
+
+  void add_package(const std::string &name,
+		   std::vector<std::string> the_versions,
+		   const std::string &curname) const
+  {
+    rep->universe->add_package(name, the_versions, curname);
+  }
+
+  void add_dep(std::string pkg_name, std::string pkg_ver,
+	       const std::vector<std::pair<std::string, std::string> > &target_names,
+	       bool is_conflict, bool is_soft)
+  {
+    rep->universe->add_dep(pkg_name, pkg_ver,
+			   target_names, is_conflict, is_soft);
+  }
+
+  package find_package(const std::string &pkg_name) const
+  {
+    return rep->universe->find_package(pkg_name);
+  }
+
+  std::vector<package>::size_type get_package_count() const
+  {
+    return rep->universe->get_package_count();
+  }
+
+  std::vector<version>::size_type get_version_count() const
+  {
+    return rep->universe->get_version_count();
+  }
+
+  package_iterator packages_begin() const
+  {
+    return rep->universe->packages_begin();
+  }
+
+  dep_iterator deps_begin() const
+  {
+    return rep->universe->deps_begin();
+  }
+
+  broken_dep_iterator broken_begin() const
+  {
+    return rep->universe->broken_begin();
+  }
+};
+
+template<class T>
+class generic_problem_resolver;
+typedef generic_problem_resolver<dummy_universe_ref> dummy_resolver;
+
+std::ostream &operator<<(std::ostream &out, const dummy_universe::dep &d);
+
+#endif // DUMMY_UNIVERSE_H

Modified: branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc	Mon Aug 15 20:25:41 2005
@@ -21,6 +21,7 @@
 // in order to keep the APT end of things reasonably thin and
 // efficient.
 
+#include "dummy_universe.h"
 #include "problemresolver.h"
 
 #include <iostream>
@@ -33,820 +34,6 @@
 
 using namespace std;
 
-class Exception
-{
-public:
-  virtual string errmsg() const=0;
-  virtual ~Exception() {}
-};
-
-class NoSuchNameError:public Exception
-{
-  string name;
-  string type;
-public:
-  NoSuchNameError(string _type, string _name)
-    :name(_name), type(_type) {}
-
-  string errmsg() const {return "No "+type+" named "+name;}
-};
-
-template<class T1, class T2>
-class wrap_ptr_iter
-{
-  typename vector<T1 *>::const_iterator realiter, realend;
-public:
-  wrap_ptr_iter(const vector<T1 *> &parent)
-    :realiter(parent.begin()), realend(parent.end())
-  {
-  }
-
-  wrap_ptr_iter(const typename vector<T1 *>::const_iterator &begin,
-		const typename vector<T1 *>::const_iterator &end)
-    :realiter(begin), realend(end)
-  {
-  }
-
-  bool operator==(const wrap_ptr_iter &other) const
-  {
-    return realiter==other.realiter;
-  }
-
-  bool operator!=(const wrap_ptr_iter &other) const
-  {
-    return realiter!=other.realiter;
-  }
-
-  bool end() const
-  {
-    return realiter == realend;
-  }
-
-  wrap_ptr_iter &operator++()
-  {
-    ++realiter;
-    return *this;
-  }
-
-  const T2 operator*() const
-  {
-    return T2(*realiter);
-  }
-};
-
-class dummy_universe;
-class dummy_version;
-
-/** A dummy package type */
-class dummy_package
-{
-  /** The name of the package is not used by the generic algorithm,
-   *  but is used as helpful output from the test cases.
-   */
-  string name;
-
-  /** The versions of this package.  The first entry in this list is
-   *  the current version.
-   */
-  vector<dummy_version *> versions;
-
-  /** The current version of this package; defaults to the first
-   *  element of "versions".
-   */
-  dummy_version *cur;
-
-  /** The ID of this version. */
-  unsigned int ID;
-
-  dummy_package(const dummy_package &other);
-public:
-  typedef vector<dummy_version *>::const_iterator version_iterator;
-
-  /** Creates a dummy package. */
-  dummy_package(string _name, unsigned int id);
-
-  virtual ~dummy_package();
-
-  string get_name() const {return name;}
-  unsigned int get_id() const {return ID;}
-
-  /** Dummy packages are equivalent iff they are the same object. */
-  bool operator==(const dummy_package &other) const
-  {
-    return this == &other;
-  }
-
-  bool operator!=(const dummy_package &other) const
-  {
-    return this != &other;
-  }
-
-  bool operator<(const dummy_package &other) const
-  {
-    return ID < other.ID;
-  }
-
-  void add_version(dummy_version *version)
-  {
-    if(versions.empty())
-      cur=version;
-    versions.push_back(version);
-  }
-
-  const dummy_version &current_version() const {return *cur;}
-  version_iterator versions_begin() const {return versions.begin();}
-  version_iterator versions_end() const {return versions.end();}
-
-  /** Returns the version corresponding to the given name or aborts */
-  dummy_version *version_from_name(const string &the_name) const;
-
-  /** Sets the current version to the given version. */
-  void set_current_version(dummy_version *v)
-  {
-    cur=v;
-  }
-};
-
-class dummy_dep;
-
-/** A dummy version type */
-class dummy_version
-{
-  string name;
-
-  const dummy_package *package;
-
-  vector<dummy_dep *> revdeps;
-  vector<dummy_dep *> deps;
-
-  /** The numerical ID of this version. */
-  int ID;
-
-  dummy_version(const dummy_version &other);
-public:
-  typedef vector<dummy_dep *>::const_iterator revdep_iterator;
-  typedef vector<dummy_dep *>::const_iterator dep_iterator;
-
-  dummy_version(string _name, const dummy_package *_package,
-		unsigned int id)
-    :name(_name), package(_package), ID(id)
-  {
-  }
-
-  string get_name() const {return name;}
-  unsigned int get_id() const {return ID;}
-
-  bool operator==(const dummy_version &other) const
-  {
-    return this == &other;
-  }
-
-  bool operator!=(const dummy_version &other) const
-  {
-    return this != &other;
-  }
-
-  bool operator<(const dummy_version &other) const
-  {
-    return ID < other.ID;
-  }
-
-  void add_revdep(dummy_dep *dep)
-  {
-    revdeps.push_back(dep);
-  }
-
-  void add_dep(dummy_dep *dep)
-  {
-    deps.push_back(dep);
-  }
-
-  const dummy_package &get_package() const {return *package;}
-
-  revdep_iterator revdeps_begin() const {return revdeps.begin();}
-  revdep_iterator revdeps_end() const {return revdeps.end();}
-
-  dep_iterator deps_begin() const {return deps.begin();}
-  dep_iterator deps_end() const {return deps.end();}
-};
-
-dummy_package::dummy_package(string _name, unsigned int id)
-  :name(_name), ID(id)
-{
-}
-
-dummy_package::~dummy_package()
-{
-  for(version_iterator i=versions.begin(); i!=versions.end(); ++i)
-    delete *i;
-}
-
-dummy_version *dummy_package::version_from_name(const string &the_name) const
-{
-  for(version_iterator i=versions.begin(); i!=versions.end(); ++i)
-    if((*i)->get_name()==the_name)
-      return *i;
-
-  throw NoSuchNameError("version of package "+name, the_name);
-}
-
-/** Indicates that either package_1 depends upon package_2 or
- *  package_1 conflicts with package_2.
- */
-class dummy_dep
-{
-  dummy_version *source;
-  vector<dummy_version *> target_set;
-
-  dummy_dep(const dummy_dep &other);
-
-  unsigned int ID;
-
-  bool soft;
-public:
-  typedef vector<dummy_version *>::const_iterator solver_iterator;
-
-  dummy_dep(dummy_version *_source,
-	    const vector<dummy_version *> &_target_set,
-	    unsigned int _ID, bool _soft)
-    :source(_source), target_set(_target_set), ID(_ID), soft(_soft)
-  {
-  }
-
-  bool is_soft() const
-  {
-    return soft;
-  }
-
-  bool operator==(const dummy_dep &other) const
-  {
-    return this==&other;
-  }
-
-  bool operator!=(const dummy_dep &other) const
-  {
-    return this!=&other;
-  }
-
-  bool operator<(const dummy_dep &other) const
-  {
-    return ID<other.ID;
-  }
-
-  dummy_version &get_source() const {return *source;}
-
-  solver_iterator solvers_begin() const
-  {
-    return target_set.begin();
-  }
-
-  solver_iterator solvers_end() const
-  {
-    return target_set.end();
-  }
-
-  /** Not part of the generic interface (although it could be);
-   *  returns \b true if the dep is not satisfied in the global
-   *  state (i.e., ignores any solution computation in progress).
-   */
-  bool broken() const
-  {
-    if(source->get_package().current_version() != *source)
-      return false;
-
-    for(solver_iterator i=target_set.begin();
-	i!=target_set.end(); ++i)
-      if((*i)->get_package().current_version() == **i)
-	return false;
-
-    return true;
-  }
-};
-
-/** Represents the world of all packages and dependencies. */
-class dummy_universe
-{
-public:
-  class version;
-  class dep;
-
-  class package
-  {
-    const dummy_package *real_package;
-  public:
-    package():real_package(0) {}
-    package(const dummy_package *_real_package)
-      :real_package(_real_package)
-    {
-    }
-
-    typedef wrap_ptr_iter<dummy_version, version> version_iterator;
-
-    bool operator==(const package &other) const
-    {
-      return real_package==other.real_package;
-    }
-
-    bool operator!=(const package &other) const
-    {
-      return real_package!=other.real_package;
-    }
-
-    bool operator<(const package &other) const
-    {
-      return (*real_package)<(*other.real_package);
-    }
-
-    string get_name() const
-    {
-      return real_package->get_name();
-    }
-
-    unsigned int get_id() const
-    {
-      return real_package->get_id();
-    }
-
-    version current_version() const
-    {
-      return version(&real_package->current_version());
-    }
-
-    version version_from_name(string name) const
-    {
-      return version(real_package->version_from_name(name));
-    }
-
-    wrap_ptr_iter<dummy_version, version> versions_begin() const
-    {
-      return wrap_ptr_iter<dummy_version, version>(real_package->versions_begin(), real_package->versions_end());
-    }
-  };
-
-  class version
-  {
-    const dummy_version *real_version;
-  public:
-    typedef wrap_ptr_iter<dummy_dep, dep> revdep_iterator;
-    typedef wrap_ptr_iter<dummy_dep, dep> dep_iterator;
-
-    version():real_version(0) {}
-    version(const dummy_version *_real_version)
-      :real_version(_real_version)
-    {
-    }
-
-    bool operator==(const version &other) const
-    {
-      return real_version==other.real_version;
-    }
-
-    bool operator!=(const version &other) const
-    {
-      return real_version!=other.real_version;
-    }
-
-    bool operator<(const version &other) const
-    {
-      return (*real_version)<(*other.real_version);
-    }
-
-    package get_package() const
-    {
-      return package(&real_version->get_package());
-    }
-
-    string get_name() const
-    {
-      return real_version->get_name();
-    }
-
-    unsigned int get_id() const
-    {
-      return real_version->get_id();
-    }
-
-    wrap_ptr_iter<dummy_dep, dep> revdeps_begin() const
-    {
-      return wrap_ptr_iter<dummy_dep, dep>(real_version->revdeps_begin(),
-					   real_version->revdeps_end());
-    }
-
-    wrap_ptr_iter<dummy_dep, dep> deps_begin() const
-    {
-      return wrap_ptr_iter<dummy_dep, dep>(real_version->deps_begin(),
-					   real_version->deps_end());
-    }
-  };
-
-
-  class dep
-  {
-    const dummy_dep *real_dep;
-  public:
-    dep():real_dep(0) {}
-    dep(const dummy_dep *_real_dep)
-      :real_dep(_real_dep)
-    {
-    }
-    dep(const dep &other)
-      :real_dep(other.real_dep)
-    {
-    }
-
-    typedef wrap_ptr_iter<dummy_version, version> solver_iterator;
-
-    bool is_soft() const
-    {
-      return real_dep->is_soft();
-    }
-
-    bool operator==(const dep &other) const
-    {
-      return real_dep==other.real_dep;
-    }
-
-    bool operator!=(const dep &other) const
-    {
-      return real_dep!=other.real_dep;
-    }
-
-    bool operator<(const dep &other) const
-    {
-      return (*real_dep)<(*other.real_dep);
-    }
-
-    version get_source() const
-    {
-      return version(&real_dep->get_source());
-    }
-
-    wrap_ptr_iter<dummy_version, version> solvers_begin() const
-    {
-      return wrap_ptr_iter<dummy_version, version>(real_dep->solvers_begin(),
-						   real_dep->solvers_end());
-    }
-
-    template<class Sol>
-    bool broken_under(const Sol& s) const
-    {
-      if(s.version_of(get_source().get_package()) != get_source())
-	return false;
-
-      for(dummy_dep::solver_iterator i=real_dep->solvers_begin();
-	  i!=real_dep->solvers_end(); ++i)
-	if(s.version_of(version(*i).get_package()) == version(*i))
-	  return false;
-
-      return true;
-    }
-  };
-
-
-  typedef wrap_ptr_iter<dummy_package, package> package_iterator;
-  typedef wrap_ptr_iter<dummy_dep, dep> dep_iterator;
-
-  /** Finds broken dependencies. */
-  class broken_dep_iterator
-  {
-    vector<dummy_dep *>::const_iterator realiter;
-    vector<dummy_dep *>::const_iterator realend;
-  public:
-    broken_dep_iterator(const vector<dummy_dep *>::const_iterator &_realiter,
-			const vector<dummy_dep *>::const_iterator &_realend)
-      :realiter(_realiter), realend(_realend)
-    {
-      while(realiter!=realend && !(*realiter)->broken())
-	++realiter;
-    }
-
-    bool operator==(const broken_dep_iterator &other) const
-    {
-      return realiter==other.realiter;
-    }
-
-    bool operator!=(const broken_dep_iterator &other) const
-    {
-      return realiter!=other.realiter;
-    }
-
-    bool end() const
-    {
-      return realiter == realend;
-    }
-
-    const dep operator*() const
-    {
-      assert(realiter!=realend);
-      return *realiter;
-    }
-
-    broken_dep_iterator &operator++()
-    {
-      if(realiter!=realend)
-	++realiter;
-
-      while(realiter!=realend && !(*realiter)->broken())
-	++realiter;
-
-      return *this;
-    }
-  };
-
-private:
-  /** All the packages in the universe. */
-  vector<dummy_package *> packages;
-  /** All the dependencies in the universe. */
-  vector<dummy_dep *> deps;
-  /** All the versions in the universe. */
-  vector<dummy_version *> versions;
-
-  /** Indexes packages by name. */
-  map<string, dummy_package *> packages_by_name;
-
-  struct compare_dummy_packages
-  {
-    bool operator()(dummy_package *p1, dummy_package *p2)
-    {
-      return p1->get_id() < p2->get_id();
-    }
-  };
-
-  struct compare_dummy_versions
-  {
-    bool operator()(dummy_version *v1, dummy_version *v2)
-    {
-      return v1->get_id() < v2->get_id();
-    }
-  };
-
-  dummy_package *find_package_internal(string pkg_name)
-  {
-    map<string, dummy_package *>::const_iterator pfound=packages_by_name.find(pkg_name);
-
-    if(pfound==packages_by_name.end())
-      throw NoSuchNameError("package", pkg_name);
-
-    return pfound->second;
-  }
-
-public:
-  virtual ~dummy_universe()
-  {
-    for(vector<dummy_package *>::const_iterator i=packages.begin();
-	i!=packages.end(); ++i)
-      delete *i;
-
-    for(vector<dummy_dep *>::const_iterator i=deps.begin();
-	i!=deps.end(); ++i)
-      delete *i;
-  }
-
-  /** Lo, and it was a void, without form. */
-  dummy_universe() {}
-
-  /** Add a package to the universe.
-   *
-   *  \param name the name of the new package.
-   *  \param the_versions the names of the versions of that package.
-   *         The first element of the list is the current version.
-   */
-  void add_package(string name,
-		   vector<string> the_versions,
-		   string curname)
-  {
-    assert(!the_versions.empty());
-
-    packages.push_back(new dummy_package(name, packages.size()));
-
-    for(vector<string>::const_iterator i=the_versions.begin();
-	i!=the_versions.end(); ++i)
-      {
-	versions.push_back(new dummy_version(*i, packages.back(), versions.size()));
-	packages.back()->add_version(versions.back());
-      }
-
-    packages.back()->set_current_version(packages.back()->version_from_name(curname));
-
-    packages_by_name[name]=packages.back();
-  }
-
-  /** Find a package by name. */
-  package find_package(string pkg_name)
-  {
-    return find_package_internal(pkg_name);
-  }
-
-  /** Add a dependency to the universe.  For convenience
-   *  this is string-based.
-   */
-  void add_dep(string pkg_name, string pkg_ver,
-	       const vector<pair<string, string> > &target_names,
-	       bool is_conflict, bool is_soft)
-  {
-    dummy_package *pkg=find_package_internal(pkg_name);
-
-    set<dummy_version *, compare_dummy_versions> targets;
-    set<dummy_package *, compare_dummy_packages> packages;
-
-    for(vector<pair<string, string> >::const_iterator i=target_names.begin();
-	i!=target_names.end(); ++i)
-      {
-	dummy_package *pkg=find_package_internal(i->first);
-
-	packages.insert(pkg);
-	targets.insert(pkg->version_from_name(i->second));
-      }
-
-    if(!is_conflict)
-      deps.push_back(new dummy_dep(pkg->version_from_name(pkg_ver),
-				   vector<dummy_version *>(targets.begin(), targets.end()),
-				   deps.size(),
-				   is_soft));
-    else
-      {
-	set<dummy_version *> targets2;
-
-	for(set<dummy_package *>::const_iterator i=packages.begin();
-	    i!=packages.end(); ++i)
-	  for(dummy_package::version_iterator j=(*i)->versions_begin();
-	      j!=(*i)->versions_end(); ++j)
-	    if(targets.find(*j)==targets.end())
-	      targets2.insert(*j);
-
-	deps.push_back(new dummy_dep(pkg->version_from_name(pkg_ver),
-				     vector<dummy_version *>(targets2.begin(), targets2.end()),
-				     deps.size(),
-				     is_soft));
-      }
-
-    dummy_dep *newdep=deps.back();
-
-    newdep->get_source().add_dep(newdep);
-
-    for(dummy_dep::solver_iterator i=newdep->solvers_begin();
-	i!=newdep->solvers_end(); ++i)
-      (*i)->add_revdep(newdep);
-  }
-
-  vector<package>::size_type get_package_count() const
-  {
-    return packages.size();
-  }
-
-  vector<version>::size_type get_version_count() const
-  {
-    return versions.size();
-  }
-
-  package_iterator packages_begin() const
-  {
-    return packages;
-  }
-
-  dep_iterator deps_begin() const
-  {
-    return deps;
-  }
-
-  broken_dep_iterator broken_begin() const
-  {
-    return broken_dep_iterator(deps.begin(), deps.end());
-  }
-};
-
-// A refcounting wrapper for a dummy_universe; used to sanitize memory
-// management without copying all over (and because the resolver
-// expects to be able to have a full copy of its argument type)
-class dummy_universe_ref
-{
-  struct _rep
-  {
-    int refcount;
-    dummy_universe *universe;
-
-    /** Start with 1 ref since our creator holds a ref. */
-    _rep(dummy_universe *_universe)
-      :refcount(1), universe(_universe)
-    {
-    }
-
-    void incref() {++refcount;}
-    void decref() {--refcount; if(refcount==0) delete this;}
-  };
-
-  _rep *rep;
-public:
-  typedef dummy_universe::package package;
-  typedef dummy_universe::version version;
-  typedef dummy_universe::dep dep;
-  typedef dummy_universe::package_iterator package_iterator;
-  typedef dummy_universe::dep_iterator dep_iterator;
-  typedef dummy_universe::broken_dep_iterator broken_dep_iterator;
-
-  dummy_universe_ref()
-    :rep(NULL)
-  {
-  }
-
-  dummy_universe_ref(const dummy_universe_ref &other)
-    :rep(other.rep)
-  {
-    if(rep)
-      rep->incref();
-  }
-
-  /** Assumes this is the first reference to the universe. */
-  dummy_universe_ref(dummy_universe *universe)
-    :rep(new _rep(universe))
-  {
-  }
-
-  ~dummy_universe_ref()
-  {
-    if(rep)
-      rep->decref();
-  }
-
-  dummy_universe_ref &operator=(const dummy_universe_ref &other)
-  {
-    if(other.rep)
-      other.rep->incref();
-    if(rep)
-      rep->decref();
-    rep=other.rep;
-
-    return *this;
-  }
-
-  operator void*() const
-  {
-    return (void *) (rep && rep->universe);
-  }
-
-  void add_package(string name,
-		   vector<string> the_versions,
-		   string curname) const
-  {
-    rep->universe->add_package(name, the_versions, curname);
-  }
-
-  void add_dep(string pkg_name, string pkg_ver,
-	       const vector<pair<string, string> > &target_names,
-	       bool is_conflict, bool is_soft)
-  {
-    rep->universe->add_dep(pkg_name, pkg_ver,
-			   target_names, is_conflict, is_soft);
-  }
-
-  package find_package(string pkg_name) const
-  {
-    return rep->universe->find_package(pkg_name);
-  }
-
-  vector<package>::size_type get_package_count() const
-  {
-    return rep->universe->get_package_count();
-  }
-
-  vector<version>::size_type get_version_count() const
-  {
-    return rep->universe->get_version_count();
-  }
-
-  package_iterator packages_begin() const
-  {
-    return rep->universe->packages_begin();
-  }
-
-  dep_iterator deps_begin() const
-  {
-    return rep->universe->deps_begin();
-  }
-
-  broken_dep_iterator broken_begin() const
-  {
-    return rep->universe->broken_begin();
-  }
-};
-
-typedef generic_problem_resolver<dummy_universe_ref> dummy_resolver;
-
-ostream &operator<<(ostream &out, const dummy_resolver::dep &d)
-{
-  out << d.get_source().get_package().get_name() << " " << d.get_source().get_name() << " -> {";
-  for(dummy_resolver::dep::solver_iterator i=d.solvers_begin();
-      !i.end(); ++i)
-    {
-      if(i!=d.solvers_begin())
-	out << ", ";
-      out << (*i).get_package().get_name() << " " << (*i).get_name();
-    }
-  out << "}";
-
-  return out;
-}
-
 // To make things easier, the tests are specified as plaintext files.
 // The syntax is quite simple: it consists of whitespace-separated
 // words, of the form:
@@ -870,7 +57,7 @@
 {
   string msg;
 public:
-  ParseError(string _msg):msg(_msg) {}
+  ParseError(const string &_msg):msg(_msg) {}
 
   string errmsg() const {return msg;}
 };



More information about the Aptitude-svn-commit mailing list