I am using a std::unique_ptr
to manage opaque types from the CoreFoundation framework. CoreFoundation types (aka CFTypes
) must be manually released, so my recipe for the std::unique_ptr
type looks like this:
namespace detail {
template <typename CoreFoundationType>
struct cfreleaser {
constexpr cfreleaser() noexcept = default;
template <typename U> cfreleaser(cfreleaser<U> const&) noexcept {};
void operator()(CoreFoundationType __attribute__((cf_consumed)) cfp) {
if (cfp) { CFRelease(cfp); cfp = nullptr; }
}
};
template <typename CoreFoundationType>
using cfp_t = std::unique_ptr<
typename std::decay_t<
std::remove_pointer_t<CoreFoundationType>>,
cfreleaser<CoreFoundationType>>;
}
… this arrangement lets me go from manually releasing CFType
resources, e.g.:
CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
/// … make use of `deviceRGB`
CGColorSpaceRelease(deviceRGB); /// release `deviceRGB`
… to an automatic-release scheme, like so:
detail::cfp_t<CGColorSpaceRef> deviceRGB(CGColorSpaceCreateDeviceRGB());
/// … make use of `deviceRGB`
/// … `deviceRGB` releases automatically on scope exit
… this means that I end up releasing every one of the CFType
instances I create with CFRelease(…)
– never using whatever specialized release function may exist for that CFType
(CGColorSpaceRelease(…)
in the above example snippet).
In my perusal of the CoreFoundation docs – as well as the docs for CFType
-based frameworks like CoreGraphics – every custom releaser function I have seen has been written up as “the equivalent of CFRelease
” (for example) … my question is, are there any exceptions to this generality? In other words, is it safe to use CFRelease(…)
on any and all CFType
instances, as I am doing in this case with std::unique_ptr
?