[intrusive] recursive intrusive data structures

hi all, is there an easy way to define recursive data structures? something like: struct my_node: boost::intrusive::list_base_hook<> { boost::intrusive::list<my_node> children; }; i am currently using a base class as helper, which causes very dirty code, since i explicitly need to cast from the base to the main class all over the place: struct my_node_base: boost::intrusive::list_base_hook<> {}; struct node: my_node_base { boost::intrusive::list<my_node_base> children; }; thanks, tim -- tim@klingt.org http://tim.klingt.org Life is really simple, but we insist on making it complicated. Confucius

On 14/06/2010 9:39, Tim Blechmann wrote:
This works on MSVC 7.1: struct my_node : public boost::intrusive::list_base_hook<> { public: boost::intrusive::list<my_node> children; }; int main() { my_node mnode; my_node mnode2; mnode.children.clear(); mnode.children.insert(mnode.children.begin(), mnode2); return 0; } Best, Ion

this doesn't: template <typename T> struct my_node: public boost::intrusive::list_base_hook<> { public: boost::intrusive::list<my_node<T> > children; }; int main() { boost::intrusive::list<my_node<int> > nodes; return 0; } instantiating an intrusive list outside of the specific class, the gcc complains: error: ‘my_node<T>::children’ has incomplete type any idea? thanks, tim -- tim@klingt.org http://tim.klingt.org Art is either a complaint or do something else John Cage quoting Jasper Johns

On 14/06/2010 21:32, Ion Gaztañaga wrote:
Sorry about the long delay, but I diddn't have time to look at this until know. I just realized that you can avoid any default hook (so the template machinery does not need instantiate the (incomplete, because of recursive definition) type "my_type" to discover hook attributes (the hook might have different properties: pointer-type, auto_unlink, tag, etc...). You can say it explicitly. Example: #include <boost/intrusive/list.hpp> #include <cassert> using namespace boost::intrusive; typedef list_base_hook<> BaseHook; class Foo : public BaseHook { public: list< Foo, base_hook<BaseHook> > children; }; int main() { Foo f, f2; list< Foo, base_hook<BaseHook> > l; l.insert(l.begin(), f); l.begin()->children.insert(l.begin()->children.begin(), f2); assert(l.size() == l.begin()->children.size()); //Clear list in correct order to avoid any safe-hook assertion l.begin()->children.clear(); l.clear(); return 0; } Telling "list" the hook type avoids any early Foo instantiation. I will see if other intrusive containers work the same way, put a test in the library and add this note to the documentation. I hope this helps, Ion
participants (2)
-
Ion Gaztañaga
-
Tim Blechmann