
Alberto Ganesh Barbati ha escrito:
JOAQUIN LOPEZ MU?Z ha scritto:
Well, if you think this line of research is interesting I can pursue it.
First of all, thanks for having considered my feedback.
This is what reviews are for :) Thanks for providing the feedback in the first place.
I was tempted to say that I liked the keyed_flyweight approach, but I preferred reading the rest of the thread before replying. When I reached the post of yours where you mention the "third" case where the keys are stored inside or can otherwise be computed from values, I realized that maybe we could not only get that case, but let it all happen (including the non-keyed case) with just one flyweight class template. Here's how I see it:
1) we have two types: key_type for keys and value_type for values. The two types can be coincident (as in your non-keyed proposal) or be different (keyed case)
2) the constructor of flyweight semantically takes keys, not values
OK so far.
3) keys (not values) are fed as-is to the factory insert() method: here's the key point, it's up to the factory to determine whether the key is already present and if it's not present to construct the corresponding value. There's actually no need for a find() method.
find() would still be useful in combination with rw locks.
The flyweight template need not know how to compare keys with values, actually it does not even need to know that it is happening.
How do I know if value_type is convertible to key_type? I need asistance from the user.
Let me say it again with different words: the flyweight/factory interface has only one method, namely insert() as in the current design. A possible map-base factory might implement the factory::insert() method as a double call map::find() and map::insert(), this would just be an implementation detail of the factory, the flyweight machinery needs not be aware of that.
4) the insert() method returns a handle
5) the factory provides a way to extract values from handles
The rest of the design would more or less stays exactly the same.
Well, this is a valid approach, but I'd rather factories remained dumber so that all this intelligence is implemented in the core, because of the following reason (among others): STL associative containers (which are the natural components upon which to implement factories) are either set-like (key_type=value_type) or map-like (key_type is a fixed part of value_type, which does not coincide with user's provided T). To be able to accept both the keyed and non-keyed variants, the container would have to deal with a more general notion of key extraction. Boost.MultiIndex can do that, but I don't want to tie flyweight to that lib. On the other hand, I don't know how to solve the third case (T convertible to K) with dumb factories :-( Maybe this third case is not worth implementing, given that the external key variant shouldn't require that much extra storage (shared values ought to be comparatively few with respect to the number of flyweight objects pointing to them.) Maybe I can provide an external flyweight wrapping both behaviors flyweight<T,...> // classical flyweight flyweight<T,key<K>,...> keyed flyweight or something to that effect. I definitely have to think this carefully. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo