#include #include #include #include #include #include #include #include typedef std::string MyString; typedef int MyTypeInfo; struct Foo { const MyString& name() const { static MyString result("test"); return(result); } virtual const MyTypeInfo& type_info() const { static const MyTypeInfo result = 1; return(result); } }; struct Bar : Foo { static const MyTypeInfo& tinfo() { static const int result = 2; return(result); } virtual const MyTypeInfo& type_info() const { return(tinfo()); } }; using boost::multi_index::indexed_by; using boost::multi_index::hashed_non_unique; using boost::multi_index::tag; using boost::multi_index::get; struct FooProxy { Foo*const foo_; FooProxy(Foo* foo) : foo_(foo) {} const MyString& get_name() const { return foo_->name(); } const MyTypeInfo& get_type() const { return foo_->type_info(); } }; template struct MyList : std::list { void append(const T& t) { this->push_back(t); }; }; struct ByName {}; struct ByType {}; typedef boost::multi_index_container< FooProxy , indexed_by< hashed_non_unique< tag, BOOST_MULTI_INDEX_CONST_MEM_FUN( FooProxy , const MyString&, get_name ) >, hashed_non_unique< tag, BOOST_MULTI_INDEX_CONST_MEM_FUN( FooProxy , const MyTypeInfo&, get_type ) > > > FooIndex; FooIndex foo_index_; typedef FooIndex::index::type FoosByName; typedef FooIndex::index::type FoosByType; // public abstract base iterator class FooIterator { public: virtual ~FooIterator() {} virtual bool more() const = 0; virtual Foo* cur() const = 0; virtual void next() = 0; protected: FooIterator() {} }; // private concrete iterator struct ByTypeFooIterator : public FooIterator { FoosByType::iterator cur_, end_; virtual bool more() const { return cur_ != end_; } virtual Foo* cur() const { return cur_->foo_; } virtual void next() { ++cur_; } }; // public method std::auto_ptr iterate(const MyTypeInfo& tinfo) { FoosByType& by_type = get(foo_index_); std::auto_ptr iter_ptr(new ByTypeFooIterator); boost::tie(iter_ptr->cur_, iter_ptr->end_) = by_type.equal_range(tinfo); return iter_ptr; } int main() { // part of unit test Foo*const expected_bar = new Bar; // Bar derives from Foo //foo_index_.insert(FooProxy(expected_bar)); for (std::auto_ptr i = iterate(Bar::tinfo()); i->more(); i->next()) { Foo*const curr = i->cur(); assert(expected_bar == curr); //CPPUNIT_ASSERT_EQUAL(expected_bar, curr); // only one Bar here } }