|
Boost : |
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk