
Hi Tobias, as Ion already wrote the idea is interesting. However I have some remarks: Tobias Schwinger wrote:
#include <boost/detail/lightweight_test.hpp> #include <map>
class foo : public intrusive::slist_node_mgmt_data<foo> // Note: Base class does not insert any names { int val_data; public:
foo(int data) : val_data(data) { }
int data() const { return this->val_data; }
// Note: No "member hook" }; IMHO 'ptr_next' is still injected in the name space of foo, since visiblitiy and accessibility are orthogonal concepts.
// Management facility std::map<bar*,intrusive::slist_node_mgmt_data<bar> > bar_management;
intrusive::slist_node_mgmt_data<bar>& get_mgmt(bar& that) { return bar_management[& that]; } get_mgmt should be a functor. It's extremely difficult to pass contextual information to a free standing function. Your example shows that right off by simply operating on a global variable.
The question is if we can or should (ab)use the traits class for this or if we introduce another template parameter like this: //-------------------------------------- struct default_mgmt { template< typename Element, class Traits > slist_node_mgmt_data<Element,Traits>&operator() (slist_node_mgmt_data<Element,Traits>& that) { return that; } } // single-linked list (incomplete for illustration) template< typename T, class Mgmt = default_mgmt, class Traits = slist_node_traits<T> > class slist : boost::noncopyable { typedef Traits traits; Mgmt get_mgmt; public: slist(const Mgmt& m) : get_mgmt(m) {} void push_front(reference x) { get_mgmt(x).ptr_next = this->ptr_first; this->ptr_first = & x; } }; // Ok, let's try non-intrusive Intrusive ;-) typedef std::map<bar*,intrusive::slist_node_mgmt_data<bar> > bar_chainer; struct bar_mgmt { bar_chainer& bar_management_; bar_mgmt(bar_chainer& b) : bar_management_(b) {} slist_node_mgmt_data<bar>& operator()(bar& that) { return bar_management_[&that]; } }; void bar_test() { // now a local variable is feasible: std::map<bar*,intrusive::slist_node_mgmt_data<bar> > bar_management; intrusive::slist<bar, bar_mgmt> my_list(bar_mgmt(bar_management)); // aso. } //-------------------------------------- Something along those lines. Of course the user is now responsible for the proper lifetime management of bar_management. But I don't consider this to be an big issue as it is a typically problem of functors containing references. Best regards Olaf Krzikalla