
Tobias Schwinger wrote:
As already admitted (in my reply to Ion), stateful function objects would be more flexible for the non-intrusive stuff.
I think a custom ValueTraits class just offers the necessary tools to build the stateless (or using global variables) non-intrusive approach. An alternative would be store a copy of ValueTraits inside the container, yielding to a stateful function object. Container constructors should take an additional ValueTraits parameter, guaranteeing that the internal ValueTraits will be copy constructor. If no ValueTraits object is provided a default constructed one might be used. If EBO is used there wouldn't be any size overhead for the default case (member or base ValueTraits).
There are two much template parameters, already, and it seems that applying Boost.Parameter (to the template parameters of containers) would suit that library well:
The fact is that containers could accept an arbitrary number of options For example: slist could just also store a pointer to the last element, so that more functions are now constant-time functions. As mentioned, the bucket management could be more customizable. There is no logical requirement to have a bucket array. Buckets can be represented with a ramdom access iterator and a size, so that buckets can be implemented with a deque or any other container that might be more suitable for an application.
Positional template parameters whose meaning isn't immediately obvious (such as e.g. the non-type boolean ConstantTimeSize used by the Intrusive containers) tend make interfaces unintuitive, because readers of client code without in-depth knowledge of the library have to figure out what the arguments refer to. Named arguments OTOH lead to self-explanatory code.
I don't know much about Boost.Parameter but my goal is maintain Boost.Intrusive independent of heavy template-metaprogramming machinery, because the library is adequate for embedded systems and I wouldn't want the executable to grow with type-info information/increased compilation time created by meta-programming (I might absolutely wrong with this sentence, so please feel free to correct). I want to maintain the library *simple*. But I agree that so many options might confuse users. Maybe a configuration structure might be better: struct options { //If not present, defaults to true static const bool contant_time_size = true; //If not present, defaults to std::size_t typedef unsigned short size_type; //... }; list<T, options>
I'd also like to see a 'T' parameter for straightforwardness
template< class T, // [...] class container;
so one could just say
container<T>
given 'T' has appropriate hooks installed. That "nested 'value_traits' business" feels pretty clumsy (much more than having the hooks inject public names) and it was my main motivation to look for something better.
One option would be to detect if the passed value parameter is a value_traits class. If not, a base hook is supposed. But note that if several base hooks are used, you *must* tell the container which hook you want to use: struct tag1; struct tag2; struct my_type : public list_hook<tag1> , public list_hook<tag2> {}; No automatic detection will work here. T is the same for slist, but the hook to be used is different. What I could do, is to simplify the most common case (simple base hook).
Hope I haven't complained too much... The library is great; I have the impression that a lot of care went into the implementation -- its interface just /deserves/ some polishing ;-).
I agree. It's just that I haven't found a better interface that preserves all the possibilities of the library. But I'm pretty sure that interface exists ;-) Regards, Ion