Boost logo

Boost :

Subject: Re: [boost] [smart ptr] Any interest in copy-on-write pointer for C++11?
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2013-02-11 17:45:16


On Mon, Feb 11, 2013 at 11:00 AM, Ralph Tandetzky <
ralph.tandetzky_at_[hidden]> wrote:

> On 02/11/2013 06:22 PM, Jeffrey Lee Hellrung, Jr. wrote:
>
>> On Sun, Feb 10, 2013 at 2:27 AM, Pyry Jahkola<pyry.jahkola_at_[hidden]>
>> wrote:
>> [...]
>>
>>
>>> The biggest difference and, in my opinion, the most important advantage
>>> in
>>> favour of adobe::copy_on_write is that the copying is explicit; given a
>>>
>>> copy_on_write<T> x;
>>>
>>> you can only use
>>>
>>> x->const_member(); // no refcount overhead even if x is non-const
>>>
>>> to access const members of T. Whenever you need to modify the instance,
>>> you'll need to explicitly tell copy_on_write about it by calling write():
>>>
>>> T & r = x.write(); // write() performs the copy if needed
>>> r.mutating_member();
>>>
>>> or, matching the use case of cow::cow_ptr<T>::apply:
>>>
>>> f(x.write());
>>>
>>> This interface maps very nicely to dealing with value types: as long as
>>> you're treating everything as a value (i.e. read-only), there aren't any
>>> hidden costs of making a copy either. And as soon as you need to make
>>> changes to the data, the overhead of the internal copy will be visible in
>>> the code responsible of the mutations as well. I guess that's enough to
>>> clear most concerns about the thread-safety issues too.
>>>
>>
> It would probably make sense to rename apply and apply_const to modify and
> read. The same with the macro. The get() member function is fine in my
> opinion, but what about operator->()? You can accidently trigger a copy
> with the non-const version. Should I take the non-const version out?
>
> +1 for explicit copy-on-write. At that point, you're basically just
>> dealing
>> with something close to an augmented shared_ptr< T const >.
>>
>> - Jeff
>>
>
> Not quiet, since the guts of shared_ptr<T const> can be changed by someone
> else without you noticing it. That's the thing about shared_ptr. It's
> really "shared". And const doesn't really mean const, but read-only.
>

I'm not sure what you mean, but I didn't literally mean a shared_ptr< T
const >; just some smart pointer to shared objects where the only way to
mutate said objects through the smart pointer is via explicit copy-on-write.

I've notices that cow_ptr actually does three things:
> 1. It implements copy-on-write, similar to copy_on_write.
> 2. It adds value semantics to polymorphic copyable/clonable types like
> value_ptr. This way these polymorphic objects can be put into standard
> containers and get all these nice features value types have.
> 3. It enables one to add cloning non-intrusively to a class hierarchy that
> doesn't support cloning.
> 4. It can be used as a pimpl pointer for value classes.
>
> copy_on_write doesn't do 2, 3 and 4. value_ptr doesn't do 1. Hence cow_ptr
> combines the positive sides of both worlds in an efficient manner. You
> could combine the template classes copy_on_write<T> and value_ptr<T> to do
> the same thing (copy_on_write<value_ptr<T>>), but it would be more verbose
> and not as efficient as cow_ptr<T>. (More indirection, extra allocations,
> more verbose client code, etc.) It would provide a better separation of
> concerns though.
>
> Possibly a bool template argument could change the behaviour between the
> current implementation of cow_ptr and value_ptr. What do you think of that?
>

I haven't taken the time to look at value_ptr or copy_on_write, but I think
the ideal situation is a pair of smart pointers, one like I just described
above (smart pointer to shared object), and one like (or precisely)
unique_ptr. This makes the deep copying and mutation explicit and safe. But
I should note I haven't looked in detail at any of the smart pointers
discussed in this thread yet :/

- Jeff


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