The proposal's points can be divided into 3 main sections.
Points (1) and (2) describe changing the base allocator type.
Points (4)..(12) describe support for propagating allocators.
Points (3),(13),(14) describe support for allocator-swap and swap_value.
Points (1) and (2) can be modified so the new allocator descends from
std::allocator<T>. As pure addition, the classes could be renamed to:
dynamic_allocator_type<T> : public allocator<T>
dynamic_allocator
Propagating allocators could be supported by keeping (4)..(12), perhaps
renaming the traits:
is_propagating_allocator
uses_propagating_allocator (or propagates_allocator)
These aren't tied to (1) and (2), so if user code provided their own new
allocator type, they could make it propagating or not as they needed.
If Point (12) is a concern it could be dropped, as it suggests invasive
changes to iostream, which widens the scope of the proposal greatly.
Points (3),(13),(14) seem a fairly harmless addition - not critical, but
useful for situations where elements are being moved outside their
memory domain.
The end result would be that everything works as it does currently, but
users who need fine control of memory can create and use propagating
polymorphic allocators. By template aliasing the types, user code can
use either the standard or the memory aware versions:
vector<T> - unchanged
set<T,CMP> - unchanged
string - unchanged
mvector<T> - alias to vector<T, dynamic_allocator_type<T> >
mset<T,CMP> - alias to set<T, CMP, dynamic_allocator_type<T> >
mstring - alias to string<char, char_traits<char>,
dynamic_allocator_type<char> >
Of course, it means that the new types are still incompatible with the
std ones (e.g. can't pass a mstring as a std::string&). On the other
hand, it has no impact on existing programs and would allow the stl to
be used in situations where careful memory control is important, such as
embedded systems or game consoles.
Another idea, if this proposal is gone for good, could be to take
stlport and integrated these changes in a forked version, with its own
namespace (e.g. mtl::vector<int>). OTOH, I'm not sure the feasibility
of this, and it sort of defeats the purpose of having a standard library.
Geoff
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
> I saw in the minutes of the October meeting that the allocator proposal
> N1850 was rejected. I'm not sure if rejection means its all over, or
> whether there is any chance of resubmission in future.
There is always room for further discussion and future submissions
within the same subject area.
-Howard
However, the "careful memory control" is not quite realized in
practice. I've actually used the implementation written by the author
of N1850, and the problem is defaults and temporaries. For example,
mstring get(){
return mstring("yoohoo",usefastallocator());
}
are you sure that the returned mstring uses the fastallocator?? It
would take far more that just a modification to the std containers to
make this work without surprises.
I agree that there are some applications where you may want to use this
technique. Apache has the "Pluggable Memory" concept, and Pete Isensee
has a good discussion at
http://www.tantalon.com/pete/customallocators.ppt , for gaming
applications. But this technique hardly calls for changing existing
implementations, much less the standard.
In terms of ease of use of the traits, its a shame these things end up
being so long winded. Macros aside, thats quite a bit of typing to
specify that each user class can propagate allocators.
> However, the "careful memory control" is not quite realized in
> practice. I've actually used the implementation written by the author
> of N1850, and the problem is defaults and temporaries. For example,
> mstring get(){
> return mstring("yoohoo",usefastallocator());
> }
> are you sure that the returned mstring uses the fastallocator?? It
> would take far more that just a modification to the std containers to
> make this work without surprises.
>
I see what you mean. The original article went down the path of having
copy constructors not using the source's allocator, which in your
implementation you seem not to have chosen. That approach deals with
some inconsistancies, with the philosophy that if you don't explicitly
ask, you won't end up binding yourself to an allocator.
Except for that RVO example. It bypasses copy construction and
assignment altogether, placing the allocator directly inside the final
object - but only if the compiler performs the optimisation.
The rule "don't RVO custom allocators" may help avoid trouble, but its
still not a nice situation.
Geoff
mstring a ("Bart", use_fast_allocator());
mstring b ("Homer", use_fast_allocator());
mstring c = a+b; //oops I'm back to the default
//this is a perfectly reasonable implementation of operator+
basic_string operator+(basic_string const& _l,basic_string const& _r){
basic_string _ret;//default allocator
_ret.reserve( _l.size()+_r.size());
_ret=_l;
_ret+=_r;
return _ret; // even if not the default
//allocator gets passed or not
// depending on optimizer
//try to debug THAT one
}
Basically what happens in real life, if strings or containers with
private heaps have to propgate through code that uses containers as
return values, or as const references, is that eventually you just end
up with with most containers using the default anyway.
However, since most libraries don't check for allocator post
conditions, existing libraries appear to work. Until you have a library
that depends on a particular allocator , i.e. shared memory , or no
fail allocators (important in many embedded systems ) . Then it is a
nightmare.
The only way I've kept my sanity using polymorhic allocators is to
disable the default, and force compiler errors everytime it tried to
make a default. You will find that such a container doesn't travel very
far, which is a good thing.
I chatted to Dietmar Kuhl about this recently and encouraged him to
discuss it with John Lakos, who was the originator of the idea (though his
colleague, Pablo Halpern, presented it to USENET and the stds committee).
I understand that Dietmar, John and Pablo had a good talk about how the
proposal could be modified to make it more acceptable to the stds
committee. I hope this means that a new version of the proposal will come
out soon. I would really like to see this fix for allocators ratified.
-Andrew Marlow
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
> On Sat, 11 Feb 2006 19:27:09 -0600, Howard Hinnant wrote:
>>> I saw in the minutes of the October meeting that the allocator proposal
>>> N1850 was rejected. I'm not sure if rejection means its all over, or
>>> whether there is any chance of resubmission in future.
>>
>> There is always room for further discussion and future submissions
>> within the same subject area.
>>
>> -Howard
>
> I chatted to Dietmar Kuhl about this recently and encouraged him to
> discuss it with John Lakos, who was the originator of the idea (though his
> colleague, Pablo Halpern, presented it to USENET and the stds committee).
> I understand that Dietmar, John and Pablo had a good talk about how the
> proposal could be modified to make it more acceptable to the stds
> committee. I hope this means that a new version of the proposal will come
> out soon. I would really like to see this fix for allocators ratified.
Despite the language used by the paper ("a better allocator model"),
it's not a fix; it's a change. N1850 trades off efficiency in some
cases against usability. The current allocator model is not "broken"
in this regard.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
>>> I would really like to see this fix for allocators ratified.
>
> Despite the language used by the paper ("a better allocator model"),
> it's not a fix; it's a change. N1850 trades off efficiency in some
> cases against usability. The current allocator model is not "broken"
> in this regard.
Hmm. The paper gives an example in section 4.4 (Who's got my allocator?)
where during copying the allocator that is used is not specified by the
std. I agree that this is not an official defect but IMO it would only
require filing a defect report to make it so. The problem described seems
pretty serious to me which is why from my perspective the 'better'
allocator model is fixing something, rather than just changing it.
I have heard that a modified version of the proposal is aimed to be out
by October. Hopefully this address the concerned expresssed by the
committee the last time. If not then I think perhaps filing a defect
report would be in order. This would aim to officially place on the
record problems such as the example problem of vector insertion where
objects can get copied either by copy construction or by assignment during
vector expansion and that the choice made affects which allocator is used,
due to an inconsistency in the std.
This stuff might not seem very serious to most people but I suspect that
it because most people do not make much use of custom allocators
for STL objects. But for those that do I think it is important to get
these points cleaned up. In the meantime I tend to recommend (to
newcomers/beginners) that this area of C++ is best avoided.
Regards,
Andrew Marlow
> On Wed, 26 Jul 2006 14:33:37 +0000, David Abrahams wrote:
>
>>>> I would really like to see this fix for allocators ratified.
>>
>> Despite the language used by the paper ("a better allocator model"),
>> it's not a fix; it's a change. N1850 trades off efficiency in some
>> cases against usability. The current allocator model is not "broken"
>> in this regard.
>
> Hmm. The paper gives an example in section 4.4 (Who's got my allocator?)
> where during copying the allocator that is used is not specified by the
> std. I agree that this is not an official defect but IMO it would only
> require filing a defect report to make it so.
No, that's not how it works. The LWG would have to agree with you.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
> use...@marlowa.plus.com (A Marlow) writes:
>
>> On Wed, 26 Jul 2006 14:33:37 +0000, David Abrahams wrote:
>>
>>>>> I would really like to see this fix for allocators ratified.
>>>
>>> Despite the language used by the paper ("a better allocator model"),
>>> it's not a fix; it's a change. N1850 trades off efficiency in some
>>> cases against usability. The current allocator model is not "broken"
>>> in this regard.
>>
>> Hmm. The paper gives an example in section 4.4 (Who's got my allocator?)
>> where during copying the allocator that is used is not specified by the
>> std. I agree that this is not an official defect but IMO it would only
>> require filing a defect report to make it so.
>
> No, that's not how it works. The LWG would have to agree with you.
Yes, I agree, but I think the example is quite compelling. I hope that the
case will again be made during the Portland meeting next month. I wonder
if people have heard anything. Seems very quite on this issue at the
moment.
-Andrew Marlow
N1850::string getstring(){
N1850::string ret("A return
value",N1850::use_shared_memory_allocator());
return ret;
}
std::string _result =getstring();
Is NVO on, and gets the the shared memory, or is it turn off, and gets
the default??
The C++ community just assumes, for some reason, that the way
allocators were specified in 1995 is "broken" somehow. No, it certianly
did not come close to the vision that Dr Stroustrup had of pointers and
such being totally abstracted from the machine memory model, but then
again what was created seems to have worked fine ever since. The C++
community use to think that MI was bad too. and there are even still a
few holdouts who think that exceptions are worthless.
Anybody can scour the C++ literature, as I did, and find virtually no
factual evidence that the way allocators are specified in C++
containers is a major problem to be solved, You CAN find plenty of
people who make noise about how bad they are, but with no examples
illustrating their objections, and no workable suggestion for
improvement . Indeed the real (technical) "reason" for the polymorphic
allocator proposal in the first place, was that the writers of N1850
did not like that operator== and other comparators did not work out of
the box with containers using different alocators, but otherwise
parameterized the same. It was not to correct std::allocator. The
writers of N1850 object to the container interfaces, not the allocation
mechanism as such.
In any case, and Austern writes, "The STL is meant to be extended." I
guess if you dont like the out of the box versions one could just
implement their own containers that, well, work with all the other STL
components -- it almost as if that were the intent of the STL. And
there are about about 5 open sourced STL container implementations out
there to cut and paste and get started with.
In any case, instead of this hit or miss effort at proposing a
standard, the writers should just make their libraries available to the
community, and get plenty of feedback BEFORE making a proposal. I'm
sure the LWG would appreciate this approach as well. :)