Boost logo

Boost :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2007-06-04 13:17:33


Ion Gaztañaga ha escrito:

> Hi Joaquín,
>
> Joaquín Mª López Muñoz wrote:

[...]

> > b. I've casually inspected the code of B.IP and seems like the
> > allocator construct/destroy interface is *not* actually used, see for
> > instance list_alloc in boost/interprocess/containers/list.hpp
>
> This was recently changed due to the restrictive nature of construct()
> (only copy construction, :-( ). I returned to placement new
> construction. Some committee members kindly requested my opinion when
> Matt's paper appeared and I just said that it was possible to use
> Interprocess without construct and destroy as long as the smart pointer
> is generically convertible (say, using ADL friendly get_pointer or
> requesting smart pointers to have a .get() member function to extract
> the raw pointer. The smart pointer is required to be constructible also
> from pointers to avoid also calling "address()" and other unuseful
> functions. Documentation of Boost.Interprocess is outdated and should
> reflect the new requirements.
>
> > So, if condition 3 is not used, I wonder what the actual requirements
> > are with respect to allocator::pointer. I guess the main assumption B.IP
> > containers work on is that allocator::pointer is implicitly convertible
> > to/from T*.
>
> Well, offset_ptr is not implicitly convertible to T* but is
> constructible (no explicit constructor) from a raw pointer. Implicit
> convertibility to a raw pointer was a major source of problems (you know
> that conversion operators are really tricky). Now the only requirement
> for the container is to use a generic function to extract the raw
> pointer. I've chosen to follow shared_ptr interface:
>
> --> A smart pointer has a function called "get()" to extract the raw
> pointer.
> --> A smart pointer defines a function called "get_pointer()" to do the
> same that can be found with ADL.

Why this hassle? Cannot you just use:

  T* raw=&*p;

?? This looks *far* more generic than requiring compliant smart pointers
to go with get or get_pointer.

> In theory, the ADL option is appropriate, but in practice ADL is quite a
> big nightmare for some compilers. Well, that's because I don't really
> understand ADL ;-)
>
> So the requirements for B.IP allocator::pointer are the same for those
> for B.Intrusive (which are not well explained):
>
> http://tinyurl.com/2cjvr7
>

I guess these should also be corrected, since one of the requirements reads:

  "It must be convertible to a raw pointer and constructible from a raw
  pointer."

which as you just stated is not what's actually assumed. Also, I can't finally
figure out if you're requiring *implicit* or *explicit* construction from T*.

> > Also, what the requirements are when handling (nonraw) pointers to
> > types other than T? Consider the following:
> >
> > struct T
> > {
> > X x;
> > };
> >
> > If I've got an allocator::pointer pt to an object t of type T and want
> > to store a nonraw pointer to x, how should I do? I guess something
> > like:
> >
> > allocator::rebind<X>::other::pointer px=pt->x;
>
> You could use rebind and also request compatibility with Boost
> pointer_to_other<> utility. pointer_to_other is just more convenient to
> write and independent from the allocator.

Both techniques are not equivalent... Nothing prevents one from providing,
for instance, an allocator family whose pointer typedef is raw for some types
an belongs to a class template X<...> for some other, thus breaking
the pointer_to_other<> utility. If I were to standardize what kind of
exotic allocators STL might support, I'd go with rebind.

> Although in theory making the pointer convertible from/to a raw pointer
> might seem restrictive for some theoretical applications of allocators
> (the famous but not yet implemented containers allocating nodes on
> disk), in practice I haven't seen such restrictions. For example, can
> std::vector use std::copy to copy elements pointed by an smart pointer
> when reallocating the buffer? Or it should destroy the elements with
> allocator::destroy and construct them again with allocator::construct?
>
> My choice is to bring allocator::pointer requirements down to the earth.
> Convertibility to raw pointers also offers the advantage of using
> static_cast which are essential when trying to optimize node containers.
>
> > but this is just a guess from my part, as it's not documented. Some
> > clarifications on these issues, and maybe a rewriting of the relevant
> > doc sections, would be welcome for those container writers willing
> > to become B.IP allocator compatible.
>
> I completely agree. I just was not expecting someone to write B.IP
> compatible containers yet and this was on my low priority queue.

If you need a partenaire to discuss the issue with, please consider me
a volunteer. As it currently stands (see N2284), the standard does not provide
any clue as to what kind of allocators other than the regular ones STL
implementors are encouraged to support (it merely states that these
non-regular allocators might "encapsulate more general memory models
and [...] support non-equal instances.") It'd be nice if we can come up
with a concrete proposal to add to this encouragement section --otherwise
it's almost impossible that future STL implementations might ever support
B.IP!!

> Are you trying to make B.MI compatible B.IP? That's going to make
> some programmers really happy ;-)

I'm beginning to survey the terrain :)

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