#include #include namespace psemek::sdl2 { namespace { struct sdl_initializer { sdl_initializer() { if (SDL_Init(0) != 0) fail("Failed to initialize SDL2: "); } ~sdl_initializer() { SDL_Quit(); } static std::shared_ptr instance() { static std::weak_ptr ptr; if (auto p = ptr.lock(); p) return p; auto p = std::make_shared(); ptr = p; return p; } }; struct subsystem_initializer { std::shared_ptr sdl_init; std::uint32_t subsystems; subsystem_initializer(std::uint32_t subsystems) : sdl_init(sdl_initializer::instance()) , subsystems(subsystems) { if (SDL_InitSubSystem(subsystems) != 0) fail("Failed to initialize SDL2 subsystems: "); } ~subsystem_initializer() { SDL_QuitSubSystem(subsystems); } }; } [[noreturn]] void fail(std::string const & message) { throw std::runtime_error(message + SDL_GetError()); } std::shared_ptr init(std::uint32_t subsystems) { return std::make_shared(subsystems); } }