This leads to another interesting question. Right now,
std::allocator still uses the concept of an "underlying"
SGI-style allocator. It's set to be __pool_alloc<true, 0>
by default, with the idea that you can easily modify the
source to make it something else.
Well, there are three problems with that. First, we've
removed every trace of the old SGI-style interface
everywhere else, so why keep it around here? Second,
it's no longer true that you can easily replace
__pool_alloc<true, 0> with another allocator, because
there aren't any alternatives with the same interface.
Third, the second template parameter for __pool_alloc
("inst") is entirely artificial and should be removed.
So given that std::allocator should be fixed, we've got
two alternatives.
I think, for continuity's sake, __pool_alloc should be fixed up to be a
C++-style allocator, regardless of what technology is used for the
default allocator.
Giving people the option of the old behavior in a new, standards-style
look is a wise idea, I think.
(1) Get rid of the notion of an underlying allocator, and
just implement allocator on its own. In principle I like
this idea; it maintains a clear separation between the
standard and extended parts. We'd have to decide
which technology we want to use for the default, of
course: the existing pool allocator, or the bitmpaped
allocator, or whatever.
(2) Continue to use the idea of an underlying allocator,
but use a standard interface instead of the SGI one.
So we'd have to fix pool_allocator.h to provide a
standard interface, and then change allocator.h so
that it uses a standard interface. Mildly ugly, but quite
doable.
I really don't know what to do here.
I'm leaning towards option one, as above. What I'd like are default
allocator options, but really, if you look at it now, the underlying
allocator idea doesn't really give options to people over and beyond
what separate classes without the confusion give. With an underlying
allocator, you still cannot switch the default allocator on the fly and
expect to mix-and-match code, and instead it has to be done on a
per-container basis, and explicitly named as part of the container
type.
So, there's really no benefit that I can see, with the exception that
it
makes the details of the allocator obvious, by pointing to things like
"pool_alloc" as the underlying allocator.
This is nice, but I'm not quite sure it's worth it.
Thoughts? Maybe this clarity is worth it to some people? It does allow
us to ship multiple allocators in an organized fashion. There is
something appealing about that, which is why it was probably done in
the
first place....
Is doing a standards-conformant underlying allocation type thing really
all that much more work? I don't think bits/allocator.h would have to
be
tweaked that much. Or is there something I'm missing?
Anyway.
So maybe the way forward is to:
1) remove all _Alloc_traits
2) convert __pool_alloc to standard-style
3) figure out how to do bits/allocator.h with standard-style allocators
4) set the default allocator to standard-style pool_alloc.
This will bring to the point where we have the same allocation behavior
as 3.2/3.3 libstdc++, but with standard-style allocators.
Then, we could do
5.1) Rename one of the ext/allocators as bits/allocator.h, and
collapse/remove underlying allocator bits.
or
5.2) Keep the underlying allocator idea, and pick the default
underlying
allocator via the performance testsuite numbers. At this point, we have
more data about what works well for a larger number of containers than
the last time we made this decision (I believe allocator was last
switched from malloc_alloc to pool_alloc around gcc-3.0.0).
So I guess I really didn't pick one of the above, and instead advocate
doing both.