I've written a RAII wrapper for C function pairs which initialize and release resources and it serves me well for most cases.
#include <GL/glfw.h>
#include <string>
#include <functional>
#include <stdexcept>
template <typename UninitFuncType,
typename SuccessValueType,
SuccessValueType successValue>
class RAIIWrapper
{
public:
template <typename InitFuncType, typename... Args>
RAIIWrapper(InitFuncType initializer,
UninitFuncType uninitializer,
const std::string &errorString,
const Args&... args) :
uninit_func(uninitializer)
{
if (successValue != initializer(args...))
throw std::runtime_error(errorString);
initialized = true;
}
bool isInitialized() const
{
return initalized;
}
~RAIIWrapper()
{
if (initalized)
uninit_func();
}
// non-copyable
RAIIWrapper(const RAIIWrapper &) = delete;
RAIIWrapper& operator=(const RAIIWrapper &) = delete;
private:
bool initalized = false;
std::function<UninitFuncType> uninit_func;
};
using GLFWSystem = RAIIWrapper<decltype(glfwTerminate), decltype(GL_TRUE), GL_TRUE>;
using GLFWWindow = RAIIWrapper<decltype(glfwCloseWindow), decltype(GL_TRUE), GL_TRUE>;
int main()
{
GLFWSystem glfw(glfwInit,
glfwTerminate,
"Failed to initialize GLFW");
}
However, say when a function returns void
like Enter/LeaveCriticalSection
I'm not sure how to go about and do it in this class. Should I specialize the class for SuccessValueType = void
case? Or something with default template parameter should do?