
Dear All, Thank you for your support! I succeed to attach BGL to multi_index_container (MIC). You can find the code below. In addition to compilation and linking, it also almost works :-). Unfortunately, I met following problems: 1) Indexers used in "indexed_by" by MIC can do reasonable job if they get input more sinsible then "void* cont&". See my comments in ItemHolderKey. 2) to use additional indices of MIC I use public visibility of m_vertices member. That is not good and should hidden somehow, e.g. with a functions like "put" and "get" 3) Ignoring item 2, to be able to use additional indices in m_vertices, its type should be available outside somehow. For this test program, I just hope the keys are always found in the container. Real life is different. I also commented this in the end of "main" function. Probably, I should say why am I doing all that: I'm not satisfied with vertex_descriptor being void* or int because they are not stable enough. The former breaks down if I copy the graph, the latter - if I add or remove something. Kind regards, Alexander -------- sample code -------------- #include <iostream> #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/sequenced_index.hpp> #include <boost/graph/adjacency_list.hpp> using namespace boost; using namespace boost::multi_index; using namespace std; template<class Index> struct MICSelector { typedef Index index; }; struct Item { Item(int _a=0, int _b=0, int _c=0) : a(_a), b(_b), c(_c) {} int a,b,c; }; struct ItemHolder { ItemHolder(int id=0, const Item item=Item()) : m_ID(id), m_item(item) {} int m_ID; Item m_item; }; struct ItemHolderKey { typedef int result_type; int operator()(const ItemHolder& v) const { return v.m_ID; } template<class P> int operator()(const typename P& p) const { // How can I convert // "void* const& p" to // "const ItemHolder& ih"? return 1;//(p); } }; typedef indexed_by < sequenced<> ,ordered_non_unique< ItemHolderKey > // and other indices
Index;
typedef adjacency_list < listS, MICSelector<Index>, bidirectionalS, ItemHolder
MG;
namespace boost { // the specialization for your selector template<class Index, class ValueType> struct container_gen<MICSelector<Index>, ValueType> { typedef multi_index_container <ValueType,Index> type; }; namespace graph_detail { // I think, it is kind of std::list struct MIC_tag : virtual public reversible_container_tag, virtual public back_insertion_sequence_tag { }; template <class T,class I> MIC_tag container_category (const multi_index_container<T,I> &) { return MIC_tag(); } template <class T,class I> stable_tag iterator_stability (const multi_index_container<T,I> &) { return stable_tag(); } template <class T,class I> struct container_traits< typename multi_index_container<T,I> > { typedef MIC_tag category; typedef stable_tag iterator_stability; }; } }; int main(int argc, char* argv[]) { MG mg; MG::vertex_descriptor vd1 = add_vertex( ItemHolder( 1, Item(1) ), mg ); MG::vertex_descriptor vd2 = add_vertex( ItemHolder( 2, Item(2) ), mg ); add_edge( vd1, vd2, mg ); int key1 = mg[vd1].m_ID; int key2 = mg[vd2].m_ID; // Store key1, key2 to use to different views // over mg. Those views are going to use those // keys as follows: // It's important to be able to get the type of // mg.m_vertices out, to be able to to the // following: /* typedef MG::vertices_container::nth_index<1> Index; Index::type& idx = mg.m_vertices.get<1>(); Index::iterator f = idx.find( key1 ); if ( f != idx.end() ) { MG::vertex_descriptor v1 = *mg.m_vertices.project<0>( f ); depth_first_visit( mg, v1, ... ); } // otherwise, we have to use as below: */ MG::vertex_descriptor v1 = *mg.m_vertices.project<0>( mg.m_vertices.get<1>().find( key1 ) ); return 0; } -------- sample code --------------