Why a unique_ptr specifically? This forces the
concept of a singular owner onto users of OIIO. A
shared_ptr would work just as well, wouldn't it? It would
trade a bit of reference counting overhead for not
imposing a strict single owner.
Here's my case for unique_ptr / single owner:
ImageOutput is absolutely, completely a one-owner
conceptual model, because you're appending to and altering the
file as you make write() calls. It can't get any more stateful
and single-owner than that.
ImageInput is more subtle because the file itself is not
mutable, but the ImageInput itself is very stateful and
intended to be single owner. Until very recently, absolutely
nothing about ImageInput was safe for multiple owners (most
basically, you don't want one co-owner to close the file and
the other co-owner to still need to read from it; more
subtlety, it gets even more complicated with seek_subimage for
multi-subimage or mip-mapped images). Very recently, we added
some new API calls (read and spec calls that take explicit
subimage & miplevel parameters) that have guaranteed
thread safety, but ONLY AGAINST EACH OTHER. So shared
ownership of an ImageInput is still unsafe for legacy code
that uses the old methods, or basically any time that the app
isn't being extremely careful about only doing those
thread-safe reads concurrently but nothing else. The
ImageCache/TextureSystem is careful to do it right with
concurrency in mind, but I don't expect other apps to be safe,
so it's better for them to think of it in terms of single
ownership.
I thought about shared_ptr, and it would certainly work.
Note also that you CAN convert a unique_ptr to a shared_ptr
if you need shared usage, and in fact we do so internal to
the ImageCache, in this very review. But you can't go the
other direction easily, so if we return a shared_ptr, it's
takes a lot more care on the caller's part to try to enforce
single ownership on the app side.