|
Boost : |
From: Mathias Gaunard (mathias.gaunard_at_[hidden])
Date: 2008-03-20 15:59:23
I would like to propose some project for the Google SoC 2008, but before
I would like to determine interest.
Smart Objects are like Smart Pointers (the name comes from there, even
though it's not definite), except they don't act like pointers but
rather like objects.
One crucial difference is that Smart Objects do not acquire a pointer to
some already pre-allocated area of memory, but rather they are
responsible for allocating the object themselves ; which fits well with
the value semantics of objects anyway, since it must deep copy.
I first thought of naming that Polymorphic Value Objects, but nothing
forces such objects to provide some kind of polymorphism.
I actually consider a Smart Object to be any container that contains a
single value object, while "masking" it to add other extra features:
dynamic typing, delayed initialization, etc.
Boost.Any, Boost.Variant, Boost.Function, Boost.Optional, Adobe.Poly,
and probably others I cannot think of are Smart Objects.
The first part of what I propose is a policy-based self-containing
non-typed memory allocator framework that would allow pluggable usage of
SBO, and that could provide the never-empty guarantee with one technique
or the other if desired.
Indeed, some Smart Objects can benefit from non-typed memory allocation,
and all of them can benefit from SBO, which brings its own problem when
wanting to replace an object by another.
The standard allocator model cannot allow such things cleanly. Of course
it would be possible to use a standard allocator underlyingly, but it
would allocate arrays of chars.
The second part is the implementation of a few useful Smart Objects
using the framework and thus which allocation is still customizable (the
names are of course not definite):
- pimpl<T>, same as a regular T except that T can be incomplete.
- ipoly<T>, which can contain a T or any object whose type derives from
T, but only if T provides some virtual copy and move constructors of its
own. This provides support for subclassing subtyping.
- maybe poly<T>, same as ipoly<T> but without requiring some virtual
copy constructors. I believe this would not integrate well with the C++
type system though. I think there is some code for that in the vault
already.
- structural<Interface>, with Interface an interface of some sort
(probably defined with helper macros). Would allow to contain any object
which type conforms to the interface, similarly to Adobe.Poly. This
provides support for structural subtyping.
- maybe duck<Sequence of types>, which would be able to contain any type
within the sequence, and provide duck-typing. This basically is the same
as structural subtyping except the interface is verified at runtime. Due
to limitations of the C++ language, it can only work with a finite
sequence of types ; indeed template virtual member functions would be
needed to achieve it otherwise.
It can be noted that boost::function<R (T1, .., Tn)> is nothing but a
structural<Interface> whose Interface is struct { R operator()(T1, ..,
Tn); }
Boost.Overload could have been the same thing with multiple overloads in
the interface, but rather it used a different design (containing
multiple objects).
Access to members for pimpl, ipoly, poly and structural would be done
through -> since . cannot be overloaded. Access to members of duck would
be different though, since that cannot work. Something like
obj.member(<&>(o) (o.the_member)); if we had polymorphic lambdas,
probably. (with optional macros to help)
There would also be optional variants of those utilities because the
never-empty guarantee does not need to be maintained if we allow the
smart object to be empty.
All of these would have support for move semantics and in-place
construction.
Please tell me your thoughs about this, so that I can determine whether
it's worth it or not to submit a GSoC candidature next week.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk