#pragma once #include #include #include "misc.h" static void try_close(FILE* file); class File { public: // https://stackoverflow.com/a/2173764 File(const File&) = delete; File& operator=(const File&) = delete; inline File(File&& other) { try_close(this->_file); this->_file = other._file; other._file = nullptr; } inline File& operator=(File&& other) { if (this == &other) { return *this; } try_close(this->_file); this->_file = other._file; other._file = nullptr; return *this; } File(const char* __restrict path, const char* __restrict mode) { using namespace std::string_literals; this->_file = fopen(path, mode); if (!this->_file) { throw_system_error("fopen("s + quote(path) + ')'); } } ~File() { try_close(this->_file); } void write(const char* data, size_t length) { if (fwrite(data, 1, length, this->_file) != length) { throw_system_error("fwrite()"); } } inline void write(const std::string& str) { this->write(str.data(), str.size()); } inline constexpr FILE* get() const noexcept { return this->_file; } protected: FILE* _file = nullptr; }; static void try_close(FILE* file) { if (file && fclose(file)) { perror("Failed to close a file: fclose()"); } }