> Frank Mori Hess wrote:
>
> I wasn't following the thread too closely, but I assumed the benefit of
>> using size+alignment instead of type would be that you could reuse the same
>> allocator with different types (as long as they had the same size and
>> alignment). But since a type's size+alignment varies across platforms, you
>> wouldn't be able to portably reuse such an allocator with different types
>> (hence no portable benefit).
>>
>
> The size + alignment wouldn't be part of the type of the allocator, it
> would be part of the arguments it receives to perform a given allocation.
> (i.e., like posix_memalign).
>
>
This is basically what Cloneable does. I'll try to make this as short as
possible: basically, there are four levels. At the bottom (most general),
there is abstract_base<Base>, where Base is the user-supplied base class for
a type hierarchy. abstract_base<> provides an abstract interface. Using that
is mixin<Derived, Base> : abstract_base<Base>, which implements much of the
interface required by abstract_base, excluding what is implemented by
base<Derived,Base,Construction> which deals with types that are not default
constructable. At the top is YourType : base<YourType,YourBase>.

Allocation is performed by an abstract_allocator, which is adapted from a
type that models a std::allocator. This is necessary because the system uses
the one allocator to make objects of different types.

This scheme, with some slight mods to ptr_container to pass the containers'
allocator to the clone site, allows for correct deep cloning of containers
of pointers. The alignment is not incorrect. It works for all types, and it
is portable. Free functions are provided so non-cloneable types can be used
as well. The default clone operation, implemented using copy-construction,
can be overridden by simply providing a `Derived *clone(abstract_allocator
&) const` method in your derived class.

There are some outstanding issues, mostly to do with the containers that are
built using this system and based on ptr_container. These 'heterogenous'
containers entirely use emplace semantics (the containers create the
objects). The main issues are method names, some semantic issues, and
dealing correctly with multiple inheritance. Also, what to do with various
almost-pointers like heterogenous::vector<shared_ptr<Base>> is unresolved.

That said, it is the closest I've seen yet to a general way to make
cloneable objects, and thereby providing true heterogenous containers with
real value semantics. For example:

However, so far I have only implemented map<Key, Base> (map of value-type to
pointer), not iso_map<Base> (map of pointer to pointer). This is due to how
ptr_map<> is implemented, but the implementation of iso_map<Base> is obvious
if technically tedious.