From: David B. Held (dheld_at_[hidden])
Date: 2004-07-14 20:26:06


David B. Held wrote:
> [...]
> template< typename ContainerT >
> inline ContainerT to_lower_copy(
> const ContainerT& Input,
> const std::locale& Loc=std::locale() )
> {
> ContainerT Output;
> std::transform(
> string_algo::begin(Input),
> string_algo::end(Input),
> std::back_inserter<ContainerT>( Output ),
> string_algo::detail::to_lowerF(Loc) );
>
> return Output;
> }
> [...]
> So this function can give the strong guarantee if it has the signature
>
> { pure, strong, pure* }
> [...]

And here is where my analysis goes horribly wrong. First, this is not
the signature of a strong function. This is:

    { pure*, strong!, nothrow* }

But std::back_inserter() almost certainly does not give the nothrow
guarantee, so something is wrong. Second, in order for to_lower_copy()
to give the strong guarantee, ContainerT() must be a pure function
w.r.t. to_lower_copy(). And it is, as long as it does not modify
non-local data (global state). Once we add that condition, we get a
function that is a sequence of pure operations, which *does* give the
strong guarantee. So in the notes, you should really say:

    Notes: If SequenceT(void) does not modify global state, then
    the second variant of this function provides the strong
    exception safety guarantee.

Dave