$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Olaf Krzikalla (krzikalla_at_[hidden])
Date: 2007-08-09 05:03:53
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