An alternative to wrapping every C API you may need in custom classes for the convienence and correctness that Resource Acquisition Is Initialization gives. The idea is similar to std::unique_ptr
but is less opinionated about where the memory comes from.
Typical usage with an API that expects to allocate pointer for you.
auto db = raii::pointer<sqlite3>::with_destructor(sqlite3_close_v2);
sqlite3_open_v2(path, &db, SQLITE_OPEN_CREATE+SQLITE_OPEN_READWRITE, nullptr);
Some APIs need custom destruction for stack allocated container classes.
auto remotes = raii::structure<git_strarray>::with_destructor(git_strarray_free);
git_remote_list(&remotes, repository);
If destruction requires more than a single function, a lambda should be used.
auto stream = raii::pointer<std::iterator_traits<CFReadStreamRef>::value_type>::with_destructor([] (CFReadStreamRef p) { CFReadStreamClose(p); CFRelease(p); });
stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
CFReadStreamOpen(stream);
Core Foundation can be a particularly… persnickety… case. The non-mutable classes require a const in the template and the type being pointed to is private. Which leads to this:
int64_t number = …
auto id = raii::pointer<const std::iterator_traits<CFNumberRef>::value_type>::with_destructor(CFRelease);
id = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &number);