Boost logo

Boost :

From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2007-09-08 05:30:22


Hi Boost.Intrusive user,

-------
1 Info
-------

  As you might know, recently an interface change was discussed for
Boost.Intrusive and more configurability was required. The discussion
lead to the following templatized option specifiers:

typedef list
   < member_hook<Hook>
   , constant_time_size<false>
   , size_type<unsigned short>
   , any_future_options<option_value>
   ....
> MyList;

I've implemented this approach and my first results were not very
encouraging: list_test obj grew from 3.5MB to 11MB, compilation times
skyrocketed, debug symbol files were really big...

However, I started shortcutting internal symbols to reduce symbol length
and I've reduced the bloat to 4.5MB obj and moderately increased
compilation time. The executable has grown a bit (5-10% in release mode)
but I still don't know why (maybe I still get some long symbols there
but machine code has not grown). My conclusion is: Be careful with
meta-programming.

The current implementation, if the user does not specify any hook or
value traits, the container automatically uses the corresponding base
hook with the default tag, so defining a class to be insertable in
different containers is pretty easy:

using namespace boost::intrusive;

class my_class
: list_base_hook< link<auto_unlink> >
, slist_base_hook< link<safe_unlink>, void_pointer<offset_ptr<void> >
, set_base_hook<>
{};

typedef list<my_class> MyList;
typedef slist<my_class> MySlist;
typedef set<my_class> MySet;

I plan to upload a version with the new interface to get more comments.

--------------------------
2 Configuratility problem
--------------------------

Now that compile_time configurability is more self-describing (which was
one of the main goals of the change) we must also allow stateful option
configurability. This means that constructors of containers must take
objects of configured stateful policies. stateful policies can be:

* Stateful ValueTraits
* Comparison or Equality predicates
* Hash functors
* Any new stateful option we might imagine

So a container might end with a long list of initializers:

unordered_set
( bucket_info
, const hash &h = hash()
, const equal &e = equal()
, const value_traits &v = value_traits()
, const my_new_option &n()
, ....)

Obviously, if the user has to pass a stateful value_traits, he has to
also specify all previous parameters. Similarly to template parameters,
I would like to achieve something like:

typedef unoredered_set
< value_traits<my_stateful_value_traits>
, hash <my_hash>
, equal<my_stateful_equal>
> MyUset;

//my_value_traits_conf is passed to the internally built
//value traits, all other options are default constructed
MyUset u1 (to_value_traits(my_value_traits_conf));

//my_stateful_equal_conf is passed to the internally built
//equal, all other options are default constructed
MyUset u2 (to_equal(my_stateful_equal_conf));

//my_stateful_equal_conf is passed to the internally built
//equal, _value_traits_conf is passed to the internally built
//value traits, all other options are default constructed
MyUset u3 (to_equal(my_stateful_equal_conf)
           ,to_value_traits(my_value_traits_conf));

I've thought about implementing this with a brute-force approach but
since I know there are people who knows much more than me in this
configurability issues, I would like to know how could we efficiently
implement this. Compile-time performance appreciated. Big props
guaranteed in the documentation.

Regards,

Ion


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