Re: [boost] Proposal: Monotonic Containers

Stewart, Robert escribió:
joaquin@tid.es wrote: On Tuesday, June 09, 2009 9:34 AM
Stewart, Robert escribió:
There's a problem with using an allocator for the node based containers: they use the allocator to allocate the elements but not the nodes. That implies free store (de)allocations for the nodes which is contrary to the intended purpose of this proposal.
Umm, I beg to differ. If we have a node-based container
xxx<T,...,custom_allocator<T> >
and node<T> is the internal node type, the container is required to do the allocation using an allocator of type
custom_allocator<T>::rebind<node<T> >::other.
The container is not allowed to do any kind of allocation using other means than the custom_allocator<X> family of allocators.
If custom_allocator<node<T> > is not specialized to do the same as custom_allocator<T>, or to use the same memory pool, then it doesn't fit the proposal.
Point conceded, but how would you do otherwise? Specifying a custom allocator is your only way to affect the container's allocation behavior. Seems like you're implying that the container wrapping approach is in some way more powerful than directly specifying the custom allocator, which is not. Your only chance to solve the problem you mention is to make custom_allocator<node_type<T> > use the same memory pool. There's a way to do this. If you construct the container with custom_allocator<T> a; xxx<T,...,custom_allocator<T> > x(a); then xxx will use an object of type custom_allocator<node<T> > for its allocation needs, which perforce will be an object differnt to the allocator a you've passed; but the container is required to construct this internal allocator as a copy of a: // inside xxx implementation custom_allocator<node<T> > internal_a(a); So you can use this knowledge to pass info around, for instance on the memory pool to be used. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

allocator<T>::rebind<U>::type On Wed, Jun 10, 2009 at 2:03 AM, <joaquin@tid.es> wrote:
Stewart, Robert escribió:
joaquin@tid.es wrote: On Tuesday, June 09, 2009 9:34 AM
Stewart, Robert escribió:
There's a problem with using an allocator for the node based containers: they use the allocator to allocate the elements but not the nodes. That implies free store (de)allocations for the nodes which is contrary to the intended purpose of this proposal.
Umm, I beg to differ. If we have a node-based container
xxx<T,...,custom_allocator<T> >
and node<T> is the internal node type, the container is required to do the allocation using an allocator of type
custom_allocator<T>::rebind<node<T> >::other.
The container is not allowed to do any kind of allocation using other means than the custom_allocator<X> family of allocators.
If custom_allocator<node<T> > is not specialized to do the same as custom_allocator<T>, or to use the same memory pool, then it doesn't fit the proposal.
Point conceded, but how would you do otherwise? Specifying a custom allocator is your only way to affect the container's allocation behavior. Seems like you're implying that the container wrapping approach is in some way more powerful than directly specifying the custom allocator, which is not.
Your only chance to solve the problem you mention is to make custom_allocator<node_type<T> > use the same memory pool. There's a way to do this. If you construct the container with
custom_allocator<T> a; xxx<T,...,custom_allocator<T> > x(a);
then xxx will use an object of type custom_allocator<node<T> > for its allocation needs, which perforce will be an object differnt to the allocator a you've passed; but the container is required to construct this internal allocator as a copy of a:
// inside xxx implementation custom_allocator<node<T> > internal_a(a);
So you can use this knowledge to pass info around, for instance on the memory pool to be used.
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

joaquin@tid.es wrote On Tuesday, June 09, 2009 10:03 AM
Stewart, Robert escribió:
If custom_allocator<node<T> > is not specialized to do the same as custom_allocator<T>, or to use the same memory pool, then it doesn't fit the proposal.
Point conceded, but how would you do otherwise? Specifying a custom allocator is your only way to affect the container's allocation behavior. Seems like you're implying that the container wrapping approach is in some way more powerful than directly specifying the custom allocator, which is not.
My intention was to point out the deficiency of the allocator approach, but I should also have highlighted the deficiency of simply extending the node based containers via derivation. With knowledge of implementation details, that may be sufficient, but it would require potentially different details for each supported platform. That, of course, implies the need to rewrite the node based containers to have complete control.
Your only chance to solve the problem you mention is to make custom_allocator<node_type<T> > use the same memory pool. There's a way to do this.
If you construct the container with
custom_allocator<T> a; xxx<T,...,custom_allocator<T> > x(a);
then xxx will use an object of type custom_allocator<node<T> for its allocation needs, which perforce will be an object differnt to the allocator a you've passed; but the container is required to construct this internal allocator as a copy of a:
// inside xxx implementation custom_allocator<node<T> > internal_a(a);
So you can use this knowledge to pass info around, for instance on the memory pool to be used.
Interesting. That complicates the allocator, but it seems like it could work. The remaining issue, of course, is how the memory pools are managed since sizeof(node<T>) is not likely sizeof(T). _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Most of the messages here ignore an important detail, quoted from Scott Meyer's Effective STL, item 10: "[T]he Standard says that an implementation of the STL is permitted to assume that all allocator objects of the same type are equivalent and always compare equal... It means that portable allocator objects — allocators that will function correctly under different STL implementations — may not have state. Let's be explicit about this: it means that *portable allocators may not have any nonstatic data members*, at least not any that affect their behavior. None. Nada. That means, for example, you can't have one SpecialAllocator<int> that allocates from one heap and a different SpecialAllocator<int> that allocates from a different heap. Such allocators wouldn't be equivalent, and STL implementations exist where attempts to use both allocators could lead to corrupt runtime data structures." To summarize, std::vector<T, monotonic_allocator<T> > won't work if each vector gets a specific buffer, because another vector could possibly use that buffer instead! Thus a custom version of each container is REQUIRED unless there's a boost.test macro BOOST_STL_ALLOCATOR_EQUIVALENCE or something like that. On Tue, Jun 9, 2009 at 10:03 AM, <joaquin@tid.es> wrote:
Stewart, Robert escribió:
joaquin@tid.es wrote: On Tuesday, June 09, 2009 9:34 AM
Stewart, Robert escribió:
There's a problem with using an allocator for the node based containers: they use the allocator to allocate the elements but not the nodes. That implies free store (de)allocations for the nodes which is contrary to the intended purpose of this proposal.
Umm, I beg to differ. If we have a node-based container
xxx<T,...,custom_allocator<T> >
and node<T> is the internal node type, the container is required to do the allocation using an allocator of type
custom_allocator<T>::rebind<node<T> >::other.
The container is not allowed to do any kind of allocation using other means than the custom_allocator<X> family of allocators.
If custom_allocator<node<T> > is not specialized to do the same as custom_allocator<T>, or to use the same memory pool, then it doesn't fit the proposal.
Point conceded, but how would you do otherwise? Specifying a custom allocator is your only way to affect the container's allocation behavior. Seems like you're implying that the container wrapping approach is in some way more powerful than directly specifying the custom allocator, which is not.
Your only chance to solve the problem you mention is to make custom_allocator<node_type<T> > use the same memory pool. There's a way to do this. If you construct the container with
custom_allocator<T> a; xxx<T,...,custom_allocator<T> > x(a);
then xxx will use an object of type custom_allocator<node<T> > for its allocation needs, which perforce will be an object differnt to the allocator a you've passed; but the container is required to construct this internal allocator as a copy of a:
// inside xxx implementation custom_allocator<node<T> > internal_a(a);
So you can use this knowledge to pass info around, for instance on the memory pool to be used.
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Most of the messages here ignore an important detail, quoted from Scott Meyer's Effective STL, item 10:
<snip> To summarize, std::vector<T, monotonic_allocator<T> > won't work if each Well, sure... if you want to be "effective" :) For some reason, that book isn't sitting on my desk, but that's a really nicely summarized argument. This isn't the first time, however, that somebody has proposed allocators that require non-static members ( http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1850.pdf) - see buffer_allocator. This may be a special class of allocators that requires special attention. Andrew Sutton andrew.n.sutton@gmail.com

Obviously I will try to adress all concerns raised. Equally obviously, I will be unabled to do so. Both statements do not refute the original proposition, which is that we need a way to sometimes allocate from the stack or from a block of given memory. I think that if we can't have either/both, then there is something wrong with STL. Not that I think that I will win over STL; but wasn't the "point" of allocators such that we could do things like this? I am sure it can be done?? Christian.

Both statements do not refute the original proposition, which is that we need a way to sometimes allocate from the stack or from a block of given memory.
I think that if we can't have either/both, then there is something wrong with STL.
I agree that allocating from a specified block is a good use case, but I don't think "wrong with the STL" is an appropriate sentiment. As Ross points out there are some serious gotcha's when attaching an allocator object to existing memory (stack or otherwise), and this is certainly not the run-of-the-mill usage that would be expected by the STL. I think that there is room for both allocator models here. You just have to be very careful about how they work. For example, it may be worthwhile to attach the allocator to its container to help prevent the possibility of multiple containers accidentally drawing from the same memory pool. Not that I think that I will win over STL; but wasn't the "point" of
allocators such that we could do things like this?
Maybe yes, maybe no. My understanding of the allocators was that they were originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then. Andrew Sutton andrew.n.sutton@gmail.com

Hi Andrew: Maybe yes, maybe no. My understanding of the allocators was that they were
originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then.
If STL containers cannot be made by any means to use the stack for storage then we need a new set of containers. Christian.

If STL containers cannot be made by any means to use the stack for storage then we need a new set of containers.
My guess is that they can. I'm just suggesting that to do so requires special consideration. You should actually read this pape and see what these guys did. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1850.pdf It might give you some insights on related techniques. Andrew Sutton andrew.n.sutton@gmail.com

Thanks Andrew,
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1850.pdf
It might give you some insights on related techniques.
Christian

On 9 Jun 2009, at 17:14, Christian Schladetsch wrote:
Hi Andrew:
Maybe yes, maybe no. My understanding of the allocators was that they were
originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then.
If STL containers cannot be made by any means to use the stack for storage then we need a new set of containers.
Please, just slow down your posting slightly, and put some more thought in. There is no issue with using stack storage for containers -- I do it regularly. The problem is that std::allocator doesn't work well in extremely memory-limited environments, due to: a) lack of inline expansion b) inability to return maximum amount of memory available. (a) and (b) actually mainly come from the fact that the C memory interfaces don't well support these things. (b) isn't really available, and while you would think realloc would support (a), it doesn't, as there is no way of telling realloc not to move if it can't extend. There have been attempts to correct this error at the C level, which would then hopefully permeate up to allocators. This problem has been previously discussed and solved, on paper at least, see my earlier e-mail today which referenced: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2045.html Implementing this would solve your problems, so any competing suggestion should either build on, or improve, that plan. As I already spent 20 minutes today looking at code you wrote, which you obviously never tested on any compiler, maybe now you could spend a while, read that paper, and see what you think about it. Chris

Chris, it clearly states in your paper that you referenced, in section 4.1, that he is assuming the erasure of the equal-allocator assumption. Checking the C++ standard, section 20.1.6, you will quickly see that the equal-allocator assumption is still in place under the current standard. Thus the techniques mentioned in that paper are non-portable. I will be the first to say that this is stupid and makes lots of problems, but it is there and there's nothing we can do. Perhaps having a boost.config macro could solve the problem. If a particular implementation enforces the equal allocator assumption, a template specialization for std::vector<T, boost::monotonic_allocator<T> > (and list, deque, etc) could be defined. On Tue, Jun 9, 2009 at 12:52 PM, Christopher Jefferson < chris@bubblescope.net> wrote:
On 9 Jun 2009, at 17:14, Christian Schladetsch wrote:
Hi Andrew:
Maybe yes, maybe no. My understanding of the allocators was that they were
originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then.
If STL containers cannot be made by any means to use the stack for storage then we need a new set of containers.
Please, just slow down your posting slightly, and put some more thought in.
There is no issue with using stack storage for containers -- I do it regularly. The problem is that std::allocator doesn't work well in extremely memory-limited environments, due to:
a) lack of inline expansion b) inability to return maximum amount of memory available.
(a) and (b) actually mainly come from the fact that the C memory interfaces don't well support these things. (b) isn't really available, and while you would think realloc would support (a), it doesn't, as there is no way of telling realloc not to move if it can't extend. There have been attempts to correct this error at the C level, which would then hopefully permeate up to allocators.
This problem has been previously discussed and solved, on paper at least, see my earlier e-mail today which referenced:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2045.html
Implementing this would solve your problems, so any competing suggestion should either build on, or improve, that plan.
As I already spent 20 minutes today looking at code you wrote, which you obviously never tested on any compiler, maybe now you could spend a while, read that paper, and see what you think about it.
Chris
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 9 Jun 2009, at 20:40, Ross Levine wrote:
Chris, it clearly states in your paper that you referenced, in section 4.1, that he is assuming the erasure of the equal-allocator assumption. Checking the C++ standard, section 20.1.6, you will quickly see that the equal-allocator assumption is still in place under the current standard. Thus the techniques mentioned in that paper are non-portable. I will be the first to say that this is stupid and makes lots of problems, but it is there and there's nothing we can do.
True, but that paper seriously breaks things anyway -- it adds more methods to allocator (via a versioning method) which must then be used by the containers to get any benefit. By the time you have required those non-standards things, it's probably not unreasonable to also require proper support for stateful allocators. Chris
Perhaps having a boost.config macro could solve the problem. If a particular implementation enforces the equal allocator assumption, a template specialization for std::vector<T, boost::monotonic_allocator<T> > (and list, deque, etc) could be defined.
On Tue, Jun 9, 2009 at 12:52 PM, Christopher Jefferson < chris@bubblescope.net> wrote:
On 9 Jun 2009, at 17:14, Christian Schladetsch wrote:
Hi Andrew:
Maybe yes, maybe no. My understanding of the allocators was that they were
originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then.
If STL containers cannot be made by any means to use the stack for storage then we need a new set of containers.
Please, just slow down your posting slightly, and put some more thought in.
There is no issue with using stack storage for containers -- I do it regularly. The problem is that std::allocator doesn't work well in extremely memory-limited environments, due to:
a) lack of inline expansion b) inability to return maximum amount of memory available.
(a) and (b) actually mainly come from the fact that the C memory interfaces don't well support these things. (b) isn't really available, and while you would think realloc would support (a), it doesn't, as there is no way of telling realloc not to move if it can't extend. There have been attempts to correct this error at the C level, which would then hopefully permeate up to allocators.
This problem has been previously discussed and solved, on paper at least, see my earlier e-mail today which referenced:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2045.html
Implementing this would solve your problems, so any competing suggestion should either build on, or improve, that plan.
As I already spent 20 minutes today looking at code you wrote, which you obviously never tested on any compiler, maybe now you could spend a while, read that paper, and see what you think about it.
Chris
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Chris, it clearly states in your paper that you referenced, in section 4.1,
that he is assuming the erasure of the equal-allocator assumption. Checking the C++ standard, section 20.1.6, you will quickly see that the equal-allocator assumption is still in place under the current standard. Thus the techniques mentioned in that paper are non-portable. I will be the first to say that this is stupid and makes lots of problems, but it is there and there's nothing we can do.
But looking forward, the draft's std:Allocator concept makes no such requirements - only that allocators are equality comparable. There also seems to be a number of questions about what happens when you copy or move an allocator, which implies to me that stateless allocators are no longer required to be the norm. But that's looking forward, not necessarily what's portable now. True, but that paper seriously breaks things anyway -- it adds more methods
to allocator (via a versioning method) which must then be used by the containers to get any benefit. By the time you have required those non-standards things, it's probably not unreasonable to also require proper support for stateful allocators.
Good points. Maybe it's time to start drafting a Boost.Allocator library with advanced allocator concepts :) Andrew Sutton andrew.n.sutton@gmail.com

Christopher Jefferson skrev:
On 9 Jun 2009, at 17:14, Christian Schladetsch wrote:
Hi Andrew:
Maybe yes, maybe no. My understanding of the allocators was that they were
originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then.
If STL containers cannot be made by any means to use the stack for storage then we need a new set of containers.
There is no issue with using stack storage for containers -- I do it regularly.
Do you also do it for non-local containers? -Thorsten

On 10 Jun 2009, at 22:16, Thorsten Ottosen wrote:
Christopher Jefferson skrev:
On 9 Jun 2009, at 17:14, Christian Schladetsch wrote:
Hi Andrew:
Maybe yes, maybe no. My understanding of the allocators was that they were
originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then.
If STL containers cannot be made by any means to use the stack for storage then we need a new set of containers.
There is no issue with using stack storage for containers -- I do it regularly.
Do you also do it for non-local containers?
I should say "In practice, I find it works, as long as I do not copy the container", no issue is too strong a claim, yes! Chris

Christian Schladetsch wrote:
Hi Andrew:
Maybe yes, maybe no. My understanding of the allocators was that they were
originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then.
If STL containers cannot be made by any means to use the stack for storage then we need a new set of containers.
<advertisement> Just a note. The proposed move-aware containers in Boost.Sandbox move library are standard-compatible containers that support both stateful allocators and (a modified version of) N1850. They have been also used to implement a modified malloc that takes advantage of these new functions: http://www.drivehq.com/web/igaztanaga/allocplus/ </advertisement> Best, Ion

Hello, The initial (and only, AFAIK) problem with the given proposal was that the following code asserted: boost::monotonic::inline_storage<100*sizeof(int)> storage1; // create local storage on the stack boost::monotonic::vector<int> deathrow(storage1); // create a std::vector that uses this storage for(int i = 0; i < 100; ++i) deathrow.push_back(i); I offered to get back to the list when I had looked at it. I am doing so now. The `problem` is that std::vector allocates more than it needs, as you add to it. So while it may seem fine to allocate space for 100 ints, then make a monotonic::vector<int> and add 100 ints to it, it will fail to allocate the required excessively sized buffer. The `fix` in this case is to simply give it a larger buffer. This has no impact on the utility of the proposed librrary. Regards, Christian.

AMDG Christian Schladetsch wrote:
The initial (and only, AFAIK) problem with the given proposal was that the following code asserted:
boost::monotonic::inline_storage<100*sizeof(int)> storage1; // create local storage on the stack boost::monotonic::vector<int> deathrow(storage1); // create a std::vector that uses this storage
for(int i = 0; i < 100; ++i) deathrow.push_back(i);
I offered to get back to the list when I had looked at it. I am doing so now. The `problem` is that std::vector allocates more than it needs, as you add to it. So while it may seem fine to allocate space for 100 ints, then make a monotonic::vector<int> and add 100 ints to it, it will fail to allocate the required excessively sized buffer.
The `fix` in this case is to simply give it a larger buffer. This has no impact on the utility of the proposed librrary.
It worries me that there is no guaranteed way to know how large a buffer is large enough. In Christ, Steven Watanabe

On 9 Jun 2009, at 23:05, Ion Gaztañaga wrote:
Christian Schladetsch wrote:
originally used to abstract differences in pointer types like __far and __huge pointers. Their usage has become substantially more complex and varied since then. If STL containers cannot be made by any means to use the stack for storage
Hi Andrew: Maybe yes, maybe no. My understanding of the allocators was that they were then we need a new set of containers.
<advertisement>
Just a note. The proposed move-aware containers in Boost.Sandbox move library are standard-compatible containers that support both stateful allocators and (a modified version of) N1850. They have been also used to implement a modified malloc that takes advantage of these new functions:
Oh, cool! It's my intention to try to push these "realloc without moving" functions into some standard libraries if I can manage it, then hopefully they'll be around for use in C++ later (I suspect boost::malloc might well be out of our reach ;) ) My hope is that some of the current interest in mallocs will mean they'll be enthusiastic about the idea of adding functionality that allows better performance in C++. Out of interest, which set of extensions did you add to DLmalloc? Would be nice to try to come up with a small, consistant working set, to then try to sell to some mallocs. Chris

Christopher Jefferson wrote:
Out of interest, which set of extensions did you add to DLmalloc? Would be nice to try to come up with a small, consistant working set, to then try to sell to some mallocs.
See http://www.drivehq.com/web/igaztanaga/allocplus/#NewFunctionsForExpansion Code is here: http://www.drivehq.com/web/igaztanaga/allocplus.zip Best, Ion

On 10 Jun 2009, at 15:21, Ion Gaztañaga wrote:
Christopher Jefferson wrote:
Out of interest, which set of extensions did you add to DLmalloc? Would be nice to try to come up with a small, consistant working set, to then try to sell to some mallocs.
See http://www.drivehq.com/web/igaztanaga/allocplus/#NewFunctionsForExpansion
Code is here:
Thanks! No offence, but while that method is good as it is as general as possible, it perhaps doesn't look very "C-like", and is maybe too complex to try to pursade them to add. How important is backward expansion, and try_shrink_in_place? While obviously these things are useful, do you think they are "vital"? I'm interested as you have clearly written a lot of code which uses these mechanisms. My thought is that adding a function which is exactly "realloc, except don't move, just return", with the option to try to get as much memory as possible, say: int realloc_try(void* ptr, size_t size, size_t* new_size) With the same semantics as relloc except it doesn't move, and if it can do a partial expansion (or shrink) tries to do as much as it can and returns the new size in new_size, is (from looking at source) a very easy addition to many mallocs, and less invasive. Chris

Christopher Jefferson wrote:
Thanks!
No offence, but while that method is good as it is as general as possible, it perhaps doesn't look very "C-like", and is maybe too complex to try to pursade them to add.
Yes, it's not a proposal, it was just what I needed to add to implement C++ features.
How important is backward expansion, and try_shrink_in_place? While obviously these things are useful, do you think they are "vital"? I'm interested as you have clearly written a lot of code which uses these mechanisms.
Shrink in place is quite useful, because it offers no-throw trimming for containers like vector.
My thought is that adding a function which is exactly "realloc, except don't move, just return", with the option to try to get as much memory as possible, say:
int realloc_try(void* ptr, size_t size, size_t* new_size)
With the same semantics as relloc except it doesn't move, and if it can do a partial expansion (or shrink) tries to do as much as it can and returns the new size in new_size, is (from looking at source) a very easy addition to many mallocs, and less invasive.
It's an alternative, the advantage of a possible allocation is that the internal mutex and memory algorithm security checks are performed only once.
Chris
Another note: containers that implement this also support stateful allocators so they can be used also for your proposed arena-like allocators. Best, Ion

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Tuesday 09 June 2009, Christian Schladetsch wrote:
Both statements do not refute the original proposition, which is that we need a way to sometimes allocate from the stack or from a block of given memory.
Just in case it hasn't already been mentioned, there is an auto_buffer in the boost review queue which provides a container that can use stack allocated memory. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkounl4ACgkQ5vihyNWuA4WXegCg1vHlUklMMzedCT9wJzKFO7zC MzkAoM3GUT9nSigKH3ricZ8quh5MoVnW =1PjA -----END PGP SIGNATURE-----

Frank Mori Hess skrev:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Tuesday 09 June 2009, Christian Schladetsch wrote:
Both statements do not refute the original proposition, which is that we need a way to sometimes allocate from the stack or from a block of given memory.
Just in case it hasn't already been mentioned, there is an auto_buffer in the boost review queue which provides a container that can use stack allocated memory.
And online here: http://www.cs.aau.dk/~nesotto/boost/trunk/boost/auto_buffer/ http://www.cs.aau.dk/~nesotto/boost/trunk/libs/auto_buffer/doc/html/ -Thorsten

Frank Mori Hess skrev:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Tuesday 09 June 2009, Christian Schladetsch wrote:
Both statements do not refute the original proposition, which is that we need a way to sometimes allocate from the stack or from a block of given memory.
Just in case it hasn't already been mentioned, there is an auto_buffer in the boost review queue which provides a container that can use stack allocated memory.
And online here: http://www.cs.aau.dk/~nesotto/boost/trunk/boost/auto_buffer/ http://www.cs.aau.dk/~nesotto/boost/trunk/libs/auto_buffer/doc/html/ -Thorsten

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Tuesday 09 June 2009, Ross Levine wrote:
To summarize, std::vector<T, monotonic_allocator<T> > won't work if each vector gets a specific buffer, because another vector could possibly use that buffer instead! Thus a custom version of each container is REQUIRED unless there's a boost.test macro BOOST_STL_ALLOCATOR_EQUIVALENCE or something like that.
It seems like you could make a stack-backed vector work in c++03 by building it on top of something like std::vector<object_wrapper<T>, monotonic_allocator<T> > where object_wrapper<T> contains the T value plus a pointer to an object that holds the needed per-container allocator state. That gets you around the stateless allocator problem at the expense of having to store an extra pointer for each object in your container. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkourLEACgkQ5vihyNWuA4UCCQCgtSRCUzbA3ufAJKEBdyHSRYN2 t6wAoNvX1FgdVCA5Myk03m0HTX9LbIMl =gk43 -----END PGP SIGNATURE-----
participants (10)
-
Andrew Sutton
-
Christian Schladetsch
-
Christopher Jefferson
-
Frank Mori Hess
-
Ion Gaztañaga
-
joaquin@tid.es
-
Ross Levine
-
Steven Watanabe
-
Stewart, Robert
-
Thorsten Ottosen