$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] variant2 never empty guarantees
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-06-08 23:05:47
On 9/06/2017 01:22, Andrzej Krzemienski wrote:
> 2017-06-08 15:01 GMT+02:00 Peter Dimov:
>>> I'm not sure I understand this fully; could you please explain from what
>>> expressions, and under what conditions, you expect the strong guarantee?
>>>
>>>      variant<X, Y> v1, v2;
>>>      X x;
>>>
>>>      v1= v2; // do you expect strong guarantee here?
>>>      v1 = std::move(v2); // here?
>>>      v1 = x; // here?
>>>      v1 = std::move(x); // here?
>>>      v1.emplace<X>(); // here?
>>>
>>
>> Anyone? This is a genuine inquiry. How can I give you strong guarantee if
>> you don't tell me when and where you want it?
>>
> 
> Maybe nobody needs the strong guarantee? This is definitely the case for my
> programs. I put variants in different containers. But if exception is
> thrown while modifying them I am destroying the entire data structure. I do
> not need the previous state. If I cannot put the new one, I cannot proceed
> anyway.
> 
> (I am not saying such guarantee is useless. I just observe that the need
> occurred in my programs.)
The only case that I can think of at the moment is for something like a 
state machine, where each type in the variant is a possible state and 
the current value is the current state.  If a transition fails via 
throwing from the new state constructor then presumably the state 
machine should remain in the previous state.
Having said that, the proposed implementations of strong guarantee 
wouldn't work for that case anyway, since that sort of state machine 
also generally assumes that the current state destructor is run strictly 
before the new state constructor, and that wouldn't be the case if you 
stacked a backup in case of exception.  (Mind you, it also wouldn't be 
the case even for basic assignment; they'd have to explicitly assign a 
none_t or something first to make that happen.)  So the right place to 
handle that guarantee is in the state machine transition machinery, not 
in variant itself.
People generally require that for x = f() then if f() throws x should be 
unmodified (which is automatic based on how the language works); if it's 
the assignment itself that throws then things are usually beyond 
recovery anyway, since assignment is not really expected to throw for 
any reason other than out of memory.