
That interface might not prove very convenient in practice though. Although you could, I think, build apply/APPLY upon it.
read_ptr<T> pr;
if( write_ptr<T> pw = pr.write() ) { pw->mutate(); pr = std::move( pw ); }
I don't, however, particularly like the semantics of the case in which pr is already unique. In principle it shouldn't matter because we're writing pr from this thread, so nobody ought to be reading it, but still, it doesn't feel right.
Nice idea though. write_ptr<T> would behave like value_ptr<T> and read_ptr<T> would behave like shared_ptr<T const> with the additional ability to return write_ptrs and being constructible from an rref to write_ptr. The function apply can be implemented as a non-member function: template <typename F> void apply( read_ptr<T> & pr, F f ) { write_ptr<T> pw = pr.write(); assert( pw ); f( pw.get() ); pr = std::move( pw ); } The macro APPLY could be implemented similar to the way I implemented it for cow_ptr. Once you have apply() and/or APPLY the interface isn't so inconvenient anymore. write_ptr might as well just be a value_ptr. Possibly value_ptr<T> and read_ptr<T> need to be friends of each other. The question for this design is: Is it worth it? I guess I need to think about that a little more in order to come to a conclusion. Thanks for the idea. Ralph