Boost logo

Boost :

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk