Boost logo

Boost :

From: JOAQUIN LOPEZ MU?Z (joaquin_at_[hidden])
Date: 2007-11-14 17:29:52


Hi Emil

----- Mensaje original -----
De: Emil Dotchevski <emil_at_[hidden]>
Fecha: Miércoles, Noviembre 14, 2007 8:36 pm
Asunto: Re: [boost] Formal review request: Flyweight
Para: boost_at_[hidden]

[...]
> struct name_tag1{};
> typedef flyweight<std::string,tag<name_tag1> > str1_t;
>
> struct name_tag2{};
> typedef flyweight<std::string,tag<name_tag2> > str2_t;
>
> The problem is that now str1_t and str2_t are distinct types in the
> type system, yet they are identical semantically. Suppose I have a
> function that takes a flyweight string like this:
>
> void foo( flyweight<std::string> const & s );
>
> Even if implicit conversions between different configurations of
> flyweight<std::string> exists, calling foo with str1_t or str2_t
would
> create unwanted temporary objects. Besides, such conversions will
> create a default-configured flyweight<std::string>, which is not
> desirable. The only option I would have is to make foo a template
> which is unfortunate because it would increase physical coupling
> unnecessarily.
>
> Compare this with the way users supply custom allocators to
> shared_ptr:
>
http://www.boost.org/libs/smart_ptr/shared_ptr.htm#allocator_constructo
r
>
> Two shared_ptr<T> objects that use different allocators, once
> initialized, are indistinguishable from each other because they
> are of
> the same type, shared_ptr<T>.
>
> I would like flyweight<T> configuration to work similarly.

Your proposal is, as I see it, to some extent akin to a
*local_flyweight* variant Tobias Schwinger and I were privately
discussing some time ago: The shared_ptr allocator ctor accepts
the *context* the shared_ptr object needs during its lifetime,
namely the associated allocator and deleter. For flyweight, the
context consists of the flyweight factory and some synchronization
objects. So, the analog of shared_ptr allocator ctor in the
realm of flyweight would be something like:

  template<typename T1,...,typename Tn>
  local_flyweight([const] T1&,...,[const] Tn&,context *);

where context is an associated type containing all the
static stuff, the factory and such. This can be done
and would achieve a separation of "domains" without
using different types, just as you demand (if I'm getting
you right). This local_flyweight<> has other features
apart from domain separation, like for instance the
ability for the user to control the lifetime of the
flyweight and the possibility of creating unlimited
domains at run time (tag separation is a compile time
artifact and as such the number of different domains
one can create this way is fixed at programming time.)

Why implementing this in a different class than flyweight<>
itself? The reason is the value objects of local_flyweight<>
(the elements stored at the flyweight factory, which contain
the shared data as well as some bookkeeping info) must have
a pointer to its context, whereas in the case of flyweight<>
this context is associated to the type itself, thus saving
us a pointer per value.

Would this local_flyweight<> address your needs?
If so, I plan to evolve the idea over time and either have
it implemented for the review or else included in the future
work section. Let me know what you think about it.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


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