Scoped File Example¶
The Scoped File example demonstrates how to use arrp::resource_pool to manage C file handles (std::FILE*) safely using RAII and move semantics.
Source directory in repository: examples/scoped_file/
Source file: examples/scoped_file/src/scoped_file.cpp
Overview¶
Working with raw C file handles (FILE*) directly in C++ can lead to resource leaks if files are not closed explicitly when exceptions or early returns occur.
By wrapping FILE* inside a custom RAII move-only wrapper class (ScopedFile) and placing instances into an arrp::resource_pool<ScopedFile>, file handles are safely borrowed and automatically returned or closed upon scope exit.
The RAII Wrapper (ScopedFile)¶
class ScopedFile
{
std::FILE* m_filehandle {nullptr};
std::string m_filename {};
public:
ScopedFile() = default;
ScopedFile(const char* filename, const char* mode)
: m_filename(filename)
, m_filehandle(std::fopen(filename, mode))
{
}
// Move semantics: transfer ownership of the file handle
ScopedFile(ScopedFile&& other) noexcept
: m_filehandle(other.m_filehandle)
, m_filename(std::move(other.m_filename))
{
other.m_filehandle = nullptr;
}
ScopedFile& operator=(ScopedFile&& other) noexcept
{
if (this != &other) {
if (m_filehandle != nullptr) {
std::fflush(m_filehandle);
fclose(m_filehandle);
}
m_filehandle = other.m_filehandle;
m_filename = std::move(other.m_filename);
other.m_filehandle = nullptr;
}
return *this;
}
// Explicit conversion operator for raw FILE* access
operator FILE*() const noexcept { return m_filehandle; }
~ScopedFile()
{
if (m_filehandle != nullptr) {
std::fflush(m_filehandle);
fclose(m_filehandle);
m_filehandle = nullptr;
}
}
};
Using ScopedFile with arrp::resource_pool¶
#include <siddiqsoft/arrp.hpp>
#include <print>
int main()
{
using Pool = siddiqsoft::arrp::resource_pool<ScopedFile>;
Pool pool {};
// Seed the pool with an open file handle
pool.seed("/tmp/example_scoped_file.txt", "w+");
// Borrow the file handle from the pool
auto myfile = pool.try_borrow();
if (myfile.has_value()) {
fputs("Hello, World!\n", myfile);
fflush(myfile);
} // myfile guard goes out of scope; ScopedFile returns to the pool automatically.
return 0;
}
Building and Running¶
Navigating to the example directory in the repository: