namespace ocl
{
-/*! \brief RAII helper to use with unique_cptr
- *
- * Can't use fclose because the template requires a function that
- * returns void.
- *
- * \todo Either generalise unique_cptr somehow, or (better) make
- * general infrastructure for reading and writing binary lumps.
- * Neither of these is a priority while JIT caching is inactive.
- */
-static void fclose_wrapper(FILE *fp)
-{
- assert(fp != NULL);
- fclose(fp);
-}
-
std::string makeBinaryCacheFilename(const std::string &kernelFilename,
cl_device_id deviceId)
{
cl_device_id deviceId)
{
// TODO all this file reading stuff should become gmx::BinaryReader
- FILE *f = fopen(filename.c_str(), "rb");
- const unique_cptr<FILE, fclose_wrapper> fileGuard(f);
+ const auto f = create_unique_with_deleter(fopen(filename.c_str(), "rb"), fclose);
if (!f)
{
GMX_THROW(FileIOError("Failed to open binary cache file " + filename));
}
// TODO more stdio error handling
- fseek(f, 0, SEEK_END);
+ fseek(f.get(), 0, SEEK_END);
unsigned char *binary;
unique_cptr<unsigned char> binaryGuard;
- size_t fileSize = ftell(f);
+ size_t fileSize = ftell(f.get());
snew(binary, fileSize);
binaryGuard.reset(binary);
- fseek(f, 0, SEEK_SET);
- size_t readCount = fread(binary, 1, fileSize, f);
+ fseek(f.get(), 0, SEEK_SET);
+ size_t readCount = fread(binary, 1, fileSize, f.get());
if (readCount != fileSize)
{
GMX_THROW(InternalError("Could not get OpenCL program binary, error was " + ocl_get_error_string(cl_error)));
}
- FILE *f = fopen(filename.c_str(), "wb");
- const unique_cptr<FILE, fclose_wrapper> fileGuard(f);
+ const auto f = create_unique_with_deleter(fopen(filename.c_str(), "wb"), fclose);
if (!f)
{
GMX_THROW(FileIOError("Failed to open binary cache file " + filename));
}
- fwrite(binary, 1, fileSize, f);
+ fwrite(binary, 1, fileSize, f.get());
}
} // namespace
void operator()(T* t) { D(t); }
};
-//! unique_ptr which takes function pointer as template argument
+//! unique_ptr which takes function pointer (has to return void) as template argument
template<typename T, void D(T *) = sfree_wrapper>
using unique_cptr = std::unique_ptr<T, functor_wrapper<T, D> >;
//! Simple guard which calls sfree. See unique_cptr for details.
typedef unique_cptr<void> sfree_guard;
+
+//! Create unique_ptr with any deleter function or lambda
+template<typename T, typename D>
+std::unique_ptr<T, D> create_unique_with_deleter(T *t, D d) { return std::unique_ptr<T, D>(t, d); }
+
} // namespace gmx
#endif