Thanks for taking the time to do this review.  I appreciate the effort and the
constructive criticism.

== Quote from Christophe (trav...@phare.normalesup.org)'s article
> Concerning the gcallocator API, why is there no template method that
> forwards to new T? Is the user obliged to call allocate, and then
> initialise the object manually?

Several people have asked this and I think it needs to be added.  It's obviously
trivial to implement, but I'm not really sure what to call it yet.

> Would it not be useful if all Allocators use Exceptions that derives
> from the same Exception subtype ?

Hmm, this might get messy in terms of catching other exceptions when forwarding 
to
e.g. std.array.array() and having to throw a new type of exception.  It would be
nice but I'm skeptical about whether it's worth it.

> Now about RegionAllocator... I took me a lot of time to understand how
> it works, and I am not 100% sure about how it works. I had to rewrite my
> review when I understood something new and discovered what I had
> understood before was false.
> This is how I think it works now: Several copies of a RegionAllocator
> works just the same. When the last is destroyed, all the memory
> allocated is cleared. You can build a RegionAllocator that uses the same
> stack as the previous RegionAllocator. This "pauses" all the copies of
> the previous allocator: they can no longer allocate or free memory until
> all the copies of the new RegionAllocator are destroyed.

Right.

> Is this "pause" behavior really a desirable functionnality? This makes
> the whole behavior of RegionAllocator very confusing, because you have
> to make the disctinction between copies of a RegionAllocator and
> RegionAllocator that shares the same Stack. Well... copies of a
> RegionAllocator do share the same Stack, so it is confusing.

It is a little confusing but it has to be this way for efficiency.  If every 
call
to newRegionAllocator() had to allocate a new block from the heap, this would
largely defeat the purpose in cases where you need, e.g., a temporary array or 
two.

> Moreover, it is rather dangerous to use. What if a copy of a
> RegionAllocator sharing the same stack as a previous RegionAllocator is
> kept unexpectedly alive somewhere while the previous RegionAllocator
> goes back into action?

A RegionAllocatorError is thrown.  This gives you a decent diagnostic about what
went wrong.  This is checked for and you won't get stuck spending an entire
afternoon debugging something silly like this.

> What happens if all copies of a RegionAllocator
> dies when a RegionAllocator using the same Stack and created later is
> still alive?

A RegionAllocatorError **should** be thrown here too, though I might have
forgotten about this case.

> Those allocators are supposed to be put in containers or things like
> that, aren't they ? They might really have a life of their own (I would
> rather have them being classes that you eventually make scope classes,
> but that is not the main point). This behavior is IMO too dangerous to
> be desirable in the standard library, especially if users just start to
> make newRegionAllocator and do not realize they prevent each other from
> working fine.

I see your point but this is a fundamental limitation of the design and is
absolutely necessary for efficiency.  If you want to prevent this, give each
container a RegionAllocator with its own RegionAllocatorStack.

> If I admit that the behavior of RegionAllocator sharing the same stack
> but are not direct copies of each other is really what expert users
> want, this is badly documented:
> - regionAllocatorStack.newRegionAllocator does not tell it invalidates
> the use of previously created newRegionAllocators.

I thought this was clear from the documentation of the RegionAllocator struct,
though it may be important enough to beat people over the head with a little 
more
instead of just saying it once or twice.

> - Same for .newRegionAllocator. Moreover, the name of this function is
> very confusing. One could think it is brand new, whereas it reuses the
> same thread-local stack.
> - Introduction of RegionAllocator comment do not tell that copies of a
> RegionAllocator are different from RegionAllocators sharing the same
> stack (but that do not share the same correctRegionIndex).

Again, the semantics are unavoidably somewhat complicated and delicate.  The 
only
good way I could think of to document them was through examples.

> - regionAllocator.allocate do not tell it checks it is the lastly
> created RegionAllocator that shares the same stack (but not the same
> correctRegionIndex).

correctRegionIndex is just a unique identifier for each RegionAllocator instance
within each stack, and is an implementation detail.  I don't understand the
problem here.

> Now, do the users of RegionAllocator really want memory to be
> automatically freed when the RegionAllocator is destructed with no
> explicit request, and no way to prevent this?

This is the whole point of scoped allocators.  I can't think of a less dangerous
way of implementing something like this.  If you want to return
RegionAllocator-allocated memory, take a RegionAllocator as a parameter instead 
of
creating one.

> Important point:
> opAssigns seems not to support self assignment of a unique copy of a
> RegionAllocator.

This is a bug that needs to be fixed.  Thanks for reporting it.

> I am really sorry if I sound too agressive, and make it sound like all
> these functionality are not useful. This RegionAllocator may have
> applications and advantages that I am not aware of. I just tought when I
> started to read the documentation and the code that this allocator would
> bring to the standard library an easy and rather safe way to allocate
> memory on a stack by moving a pointer up and down when memory is
> requested or discarded, whereas this allocator is much more complicated
> than that.

This review contains nothing but perfectly reasonable, constructive criticism.  
I
appreciate it.  My only concern is that I can't think of how to simplify
RegionAllocator without making it less powerful, and since it's an advanced
feature anyhow, I think power needs to be more important than simplicity.

Reply via email to