Boost logo

Boost :

From: Fernando Cacciola \(Office\) (fcacciola_at_[hidden])
Date: 2002-11-07 13:14:18


----- Original Message -----
From: "Gennaro Prota" <gennaro_prota_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Thursday, November 07, 2002 9:26 AM
Subject: [boost] Re: Boost Array: read/write access to entire data

> On Wed, 6 Nov 2002 16:21:34 -0300, "Fernando Cacciola"
> <fernando_cacciola_at_[hidden]> wrote:
>
>
> >OK, my fault.
> >I wasn't thinking of directly using StrongStorage<T>...
> >I was thinking of borrowing its idea, so I meant that using some
variation
> >of the double-buffer technique, you could achieve no-throw. Though I
should
> >have said so explicitely, sorry.
>
>
> Yeah, I understood that (I'm not so 'inelastic'! :-). However your
> insistence on no-throw made me go to the original code to show that
> not even there there's a no-throw guarantee. Of course, I agree with
> you that the technique allows us to have the strong guarantee.
>
OK. I see.

> [...]

> Well, I agreed with you since the beginning that the technique is
> useful for the strong guarantee. I hope that's clear now. My objection
> concerned "no throw".
>
I still 'feel' like it would allow a no-throw swap, but I'll stop insisting
on it until I have a realistic implementation that proves it.

>
>
> >Now, without the double buffer, my only answer to the question above
*would*
> >be the 'traditional' implementation I've shown. However, even that
doesn't
> >work because the restore cannot be made to succeed, AFAICT, in the
presence
> >of throwing copy ctor.
> >
> >So, since *I* do not have a clue about how to implement a swap with at
least
> >strong guarantees without the double buffer, I propose it.
> >However, you or someone else might know how to do the same without this
> >complicated scheme (and without relying on the presence of a no-throw T's
> >swap). In that case, though, I will love to hear about it.
>
>
> I don't know either. However I'm still not convinced that a strongly
> exception-safe swap is really useful for an array-like class like
> that. I'm not saying it isn't, only that I'm not convinced it is. Do
> you have any example that can make me change my mind?
>
Good point.
It is reazonable to try to determine how practically useful it would be.

Personally, I can't think of a swap() which doesn't give at least the strong
guarantee. This is because of the way I use 'swaps' and because most of the
times swaps yield at least the strong guarantee.
For example, I like to swap sequences to instrument transactional semantics
in updating/modifying code: I do the changes in a local sequence and if
everthing went right, I swap the real and the temporary sequences to commit
the state.
This idiom won't work if the sequence swap gives just the basic
guarantee -or less-, because 'preserving the consistency within the final
sequence' is not enough; I also need the changes to be fully commited.
In my typical code, not having the changes fully commited is usually as
disasterous as leaving the sequence inconsistent.

Anyway, no-throw is not really required in this scenario.

>
> >> > if ( storage_initialized_[mirror_idx] )
> >> > lhs_mirror->~T();
> >>
> >> Who says you that you can invoke the destructor on all the N elements?
> >
> >This code is destructing the element which has been previously stored in
the
> >'mirror' storage.
>
> I think you missed my point. You don't know how many Ts have been
> successfully constructed in the storage. Let's say N=8 and the 3rd
> copy constructor fails: you must destroy only the first 2 elements.
> But that was a minor note that I had better left aside considering the
> extemporaneousness of the code. Furthermore that's trivial to fix by
> preserving the value of i and looping backward.
>
OK, I did miss your point.
Now I got it, and you were right :-)

>
> Ok so far. Now that we have understood each other it's time for
> another problem :-) Can you think of a situation where a swap between
> arrays with different values of N is useful?

I think that swaps between arrays of different sizes is quite useful for
transactional updates.

> That adds special cases
> to the code, of course: suppose e.g. you want to swap an array<T, 10>
> that happens to have 12 elements and an array<T, 15> that has 5
> elements. It's easy but you have to stuff the code with several ifs.

Good example. I didn't think of a mixed case like this.

> And that's one of the aspects I was thinking to when saying that a)
> I'm not sure there's a remarkable gain in performance (of course there
> can be for some values of N but... maybe on your platform only, maybe
> for some scenarios only... a complex story IMHO) and b) if a gain
> exists, if it is worth the complexity.
>
>
> Also note that, in the end, the user can only count on the strong
> guarantee for swap. One wants to know in compile-time what are the
> guarantees, of course. Our array<T, N>::swap() instead offers
> different guarantees depending on whether it has more than N elements
> or not. Obviously this means that, generally, the designer of the
> client code will rely on the weakest of the two.
>
Agreed.

Fernando Cacciola


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk