diff options
-rw-r--r-- | src/generic/problemresolver/choice_set.h | 73 | ||||
-rw-r--r-- | tests/test_choice_set.cc | 37 |
2 files changed, 110 insertions, 0 deletions
diff --git a/src/generic/problemresolver/choice_set.h b/src/generic/problemresolver/choice_set.h index 45f51767..e2e2146d 100644 --- a/src/generic/problemresolver/choice_set.h +++ b/src/generic/problemresolver/choice_set.h @@ -69,6 +69,64 @@ private: typedef typename PackageUniverse::version version; typedef typename PackageUniverse::dep dep; +public: + /** \brief A slow but convenient way to iterate over this set. */ + class const_iterator + { + friend class generic_choice_set; + + typename imm::map<package, choice>::const_iterator install_version_iter; + typename imm::map<package, choice>::const_iterator install_version_end_iter; + typename imm::set<choice>::const_iterator not_install_version_iter; + + const_iterator(const typename imm::map<package, choice>::const_iterator _install_version_iter, + const typename imm::map<package, choice>::const_iterator _install_version_end_iter, + const typename imm::set<choice>::const_iterator _not_install_version_iter) + : install_version_iter(_install_version_iter), + install_version_end_iter(_install_version_end_iter), + not_install_version_iter(_not_install_version_iter) + { + } + + public: + bool operator==(const const_iterator &other) const + { + return install_version_iter == other.install_version_iter && + not_install_version_iter == other.not_install_version_iter; + } + + bool operator!=(const const_iterator &other) const + { + return !((*this) == other); + } + + const choice &operator*() const + { + if(install_version_iter != install_version_end_iter) + return install_version_iter->second; + else + return *not_install_version_iter; + } + + const_iterator &operator++() + { + if(install_version_iter != install_version_end_iter) + ++install_version_iter; + else + ++not_install_version_iter; + + return *this; + } + + const_iterator operator++(int) + { + const_iterator rval(*this); + ++(*this); + return rval; + } + }; + +private: // Note: no iterators on this structure because they'd be a pain to // write and they should never be used (use for_each instead, it's a // lot more efficient). @@ -82,6 +140,7 @@ private: // would be more efficient or not. imm::set<choice> not_install_version_choices; + friend std::ostream &operator<< <PackageUniverse>(std::ostream &out, const generic_choice_set<PackageUniverse> &choices); // Used to apply a for_each on choices to each element of the @@ -213,6 +272,20 @@ public: { } + const_iterator begin() const + { + return const_iterator(install_version_choices.begin(), + install_version_choices.end(), + not_install_version_choices.begin()); + } + + const_iterator end() const + { + return const_iterator(install_version_choices.end(), + install_version_choices.end(), + not_install_version_choices.end()); + } + /** \brief Insert every choice in the given set into this set, * overriding more general options with more specific ones. */ diff --git a/tests/test_choice_set.cc b/tests/test_choice_set.cc index f3bd4e54..d8a7936d 100644 --- a/tests/test_choice_set.cc +++ b/tests/test_choice_set.cc @@ -86,6 +86,36 @@ class Choice_Set_Test : public CppUnit::TestFixture } }; + struct contents_enumerator + { + std::vector<choice> &rval; + + contents_enumerator(std::vector<choice> &_rval) + : rval(_rval) + { + } + + bool operator()(const choice &c) const + { + rval.push_back(c); + return true; + } + }; + + void test_contents_iterator(const choice_set &s) + { + std::vector<choice> expected, observed; + + s.for_each(contents_enumerator(expected)); + + for(choice_set::const_iterator it = s.begin(); it != s.end(); ++it) + observed.push_back(*it); + + CPPUNIT_ASSERT_EQUAL(expected.size(), observed.size()); + for(std::vector<choice>::size_type i = 0; i < expected.size(); ++i) + CPPUNIT_ASSERT_EQUAL(expected[i], observed[i]); + }; + static imm::set<choice> get_contents(const choice_set &s) { imm::set<choice> rval; @@ -153,6 +183,7 @@ public: CPPUNIT_ASSERT_EQUAL(expected, get_contents(s)); CPPUNIT_ASSERT_EQUAL(expected, get_contents(make_choice_set_narrow(expected))); CPPUNIT_ASSERT_EQUAL(s, make_choice_set_narrow(expected)); + test_contents_iterator(s); const choice c1(make_install_version(av2)); s.insert_or_narrow(c1); @@ -162,6 +193,7 @@ public: CPPUNIT_ASSERT_EQUAL(expected, get_contents(s)); CPPUNIT_ASSERT_EQUAL(expected, get_contents(make_choice_set_narrow(expected))); CPPUNIT_ASSERT_EQUAL(s, make_choice_set_narrow(expected)); + test_contents_iterator(s); const choice c2(make_install_version_from_dep_source(av2, av3d1)); expected.erase(c1); @@ -172,6 +204,7 @@ public: CPPUNIT_ASSERT_EQUAL(expected, get_contents(s)); CPPUNIT_ASSERT_EQUAL(expected, get_contents(make_choice_set_narrow(expected))); CPPUNIT_ASSERT_EQUAL(s, make_choice_set_narrow(expected)); + test_contents_iterator(s); const choice c3(make_break_soft_dep(av2d1)); s.insert_or_narrow(c3); @@ -180,6 +213,7 @@ public: CPPUNIT_ASSERT_EQUAL(expected, get_contents(s)); CPPUNIT_ASSERT_EQUAL(expected, get_contents(make_choice_set_narrow(expected))); CPPUNIT_ASSERT_EQUAL(s, make_choice_set_narrow(expected)); + test_contents_iterator(s); const choice c4(make_install_version_from_dep_source(bv1, bv2d1)); s.insert_or_narrow(c4); @@ -189,6 +223,7 @@ public: CPPUNIT_ASSERT_EQUAL(expected, get_contents(s)); CPPUNIT_ASSERT_EQUAL(expected, get_contents(make_choice_set_narrow(expected))); CPPUNIT_ASSERT_EQUAL(s, make_choice_set_narrow(expected)); + test_contents_iterator(s); const choice c5(make_install_version(bv1)); s.insert_or_narrow(c5); @@ -197,6 +232,7 @@ public: CPPUNIT_ASSERT_EQUAL(expected, get_contents(s)); CPPUNIT_ASSERT_EQUAL(expected, get_contents(make_choice_set_narrow(expected))); CPPUNIT_ASSERT_EQUAL(s, make_choice_set_narrow(expected)); + test_contents_iterator(s); const choice c6(make_break_soft_dep(av3d1)); @@ -206,6 +242,7 @@ public: CPPUNIT_ASSERT_EQUAL(expected, get_contents(s)); CPPUNIT_ASSERT_EQUAL(expected, get_contents(make_choice_set_narrow(expected))); CPPUNIT_ASSERT_EQUAL(s, make_choice_set_narrow(expected)); + test_contents_iterator(s); } void testContainsChoice() |