$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2007-08-26 04:08:14
Ion Gaztañaga wrote:
> Hi to all,
>
> First of all, thanks to all who participated in recent threads
> about Boost.Intrusive options and extended configurability discussions.
> These days I've been experimenting a bit with this option and also with
> stateful value_traits (those who could allow non-intrusive hooks).
>
> -----------------------------------------
> -----------------------------------------
> Passing policies to hooks and containers
> -----------------------------------------
> ------------------------------------------
>
> As you know, one of my main concerns is that a container explicitly set
> with some options, should have the same type as another container
> defined with the same options in a different order. I meant:
>
> list<T, base_hook<my_base_hook>, constant_time_size<false> >
>
> should have the same type as:
>
> list<T, constant_time_size<false>, base_hook<my_base_hook> > l;
>
> My preferred alternative is the more verbose:
>
> typedef list_options
> < base_hook<my_base_hook>
> , constant_time_size<false>
> >::type options_t;
>
> list<T, options_t> l;
>
> that guarantees the same type for the same options.
>
> 1) Implemented interface:
>
> I've implemented all current container options using this approach. I've
> chosen a different options configurer "list_options", "slist_options"...
> because otherwise, I couldn't set defaults that could lead to the
> correct types.
That's not necessary: We can combine the options into a nested template
in 'options<...>::type' that takes in the defaults.
> Some options must not be set in the container *but in the hook*, since
> options affect both the hook and the container. Examples: void pointer
> definition, the linking policy. I think hook options can be unified so I
> have:
>
> typedef hook_options
> < void_pointer<offset_ptr<void> >
> , link<normal_link>
> , tag<my_tag>
> >::type hook_options_t;
>
> class my_type
> : public list_base_hook<hook_options_t>
> {
> typedef list_base_hook<hook_options_t> my_hook_t;
> }
>
> typedef list_options
> < base_hook<my_hook_t>
> , size_type<std::size_t>
> >::type options_t;
>
> list<T, options_t> l;
>
> As you can see, specifying options can be quite verbose (comparing it to
> the old way, but as new options are added (for example, custom buckets
> definition in hash containers) users don't have put arguments in order
> and can change only the options they want to change from the default.
Yes. It's inferior to a full named parameter solution and it requires
much more metaprogramming to work and probably compiles slower and has
more header dependencies than a lightweight solution.
Do you really have strong evidence (rather than just suspicions) that
you get something in return? IOW: Did you benchmark the difference
between a named parameter interface (with measures to reduce bloat, as
discussed) and the interface you propose?
> 2) Declaration of new classes:
>
> template<class T, class ListOptions>
> class list;
>
> template<class T, class SlistOptions>
> class slist;
>
> template<class T, class Pred, class SetOptions>
> class set;
>
> template<class T, class Hash, class Equal, class UsetOptions>
> class unordered_set;
>
> So the declaration of intrusive containers would be exactly the same as
> the STL containers plus an options argument.
>
Consistency with STL weighs little against awkward usage. Everything
that has a default is optional and should be an option.
> 3) Problem: Definition of member hooks is very long
>
> class my_type
> {
> list_member_hook member_hook_;
> }
>
> typedef list_options
> < member_hook<my_type, list_member_hook, &my_type::member_hook_>
> >::type options;
>
> list<my_type, options> l;
>
> Why? Because I can't make C++ deduce a pointer to member value in a
> single template parameter passed to a class. It would be nice that C++
> could deduce my_type and list_member_hook from the value directly
> yielding to:
>
> typedef list_options
> //Deduce my_type and list_member_hook automatically
> < member_hook<&my_type::member_hook_>
> >::type options;
It will always be repetitive. Only thing we could do is provide a macro
for convenience.
>
> 4) Custom value_traits
>
> Current interface takes a value_traits class as the first parameter in
> containers:
>
> template<class ValueTraits, bool...>
> class list;
>
> ValueTraits concept is very powerful because allows separating the
> concepts of a Node and a Value. The node is the minimal structure that
> is need to form a group of nodes (group of pointers to form a list, a
> tree...) and the Value is the whole user type that is somehow related to
> the node (via inheritance, membership, or other).
>
> Intrusive documentation offers examples of custom ValueTraits to reuse
> nodes for different containers or to deal with non modifiable ABI of old
> code. This is still possible specifying
> the value_traits instead of the hook:
>
> typedef list_options
> < value_traits<my_value_traits>
> >::type options;
One could argue ValueTraits (as any traits blob) is too powerful. Why do
you still it? Can't you split it up into options?
Regards,
Tobias