Using std::unique_ptr<…> to manage CoreFoundation CFType resources

236 Views Asked by At

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?

0

There are 0 best solutions below