1*6e36587aSZane Shelley #pragma once 2*6e36587aSZane Shelley 3*6e36587aSZane Shelley #include <filesystem> 4*6e36587aSZane Shelley #include <utility> 5*6e36587aSZane Shelley 6*6e36587aSZane Shelley namespace util 7*6e36587aSZane Shelley { 8*6e36587aSZane Shelley 9*6e36587aSZane Shelley namespace fs = std::filesystem; 10*6e36587aSZane Shelley 11*6e36587aSZane Shelley /** 12*6e36587aSZane Shelley * @class TemporaryFile 13*6e36587aSZane Shelley * 14*6e36587aSZane Shelley * A temporary file in the file system. 15*6e36587aSZane Shelley * 16*6e36587aSZane Shelley * The temporary file is created by the constructor. The absolute path to the 17*6e36587aSZane Shelley * file can be obtained using getPath(). 18*6e36587aSZane Shelley * 19*6e36587aSZane Shelley * The temporary file can be deleted by calling remove(). Otherwise the file 20*6e36587aSZane Shelley * will be deleted by the destructor. 21*6e36587aSZane Shelley * 22*6e36587aSZane Shelley * TemporaryFile objects cannot be copied, but they can be moved. This enables 23*6e36587aSZane Shelley * them to be stored in containers like std::vector. 24*6e36587aSZane Shelley */ 25*6e36587aSZane Shelley class TemporaryFile 26*6e36587aSZane Shelley { 27*6e36587aSZane Shelley public: 28*6e36587aSZane Shelley // Specify which compiler-generated methods we want 29*6e36587aSZane Shelley TemporaryFile(const TemporaryFile&) = delete; 30*6e36587aSZane Shelley TemporaryFile& operator=(const TemporaryFile&) = delete; 31*6e36587aSZane Shelley 32*6e36587aSZane Shelley /** 33*6e36587aSZane Shelley * Constructor. 34*6e36587aSZane Shelley * 35*6e36587aSZane Shelley * Creates a temporary file in the temporary directory (normally /tmp). 36*6e36587aSZane Shelley * 37*6e36587aSZane Shelley * Throws an exception if the file cannot be created. 38*6e36587aSZane Shelley */ 39*6e36587aSZane Shelley TemporaryFile(); 40*6e36587aSZane Shelley 41*6e36587aSZane Shelley /** 42*6e36587aSZane Shelley * Move constructor. 43*6e36587aSZane Shelley * 44*6e36587aSZane Shelley * Transfers ownership of a temporary file. 45*6e36587aSZane Shelley * 46*6e36587aSZane Shelley * @param file TemporaryFile object being moved 47*6e36587aSZane Shelley */ TemporaryFile(TemporaryFile && file)48*6e36587aSZane Shelley TemporaryFile(TemporaryFile&& file) : path{std::move(file.path)} 49*6e36587aSZane Shelley { 50*6e36587aSZane Shelley // Clear path in other object; after move path is in unspecified state 51*6e36587aSZane Shelley file.path.clear(); 52*6e36587aSZane Shelley } 53*6e36587aSZane Shelley 54*6e36587aSZane Shelley /** 55*6e36587aSZane Shelley * Move assignment operator. 56*6e36587aSZane Shelley * 57*6e36587aSZane Shelley * Deletes the temporary file owned by this object. Then transfers 58*6e36587aSZane Shelley * ownership of the temporary file owned by the other object. 59*6e36587aSZane Shelley * 60*6e36587aSZane Shelley * Throws an exception if an error occurs during the deletion. 61*6e36587aSZane Shelley * 62*6e36587aSZane Shelley * @param file TemporaryFile object being moved 63*6e36587aSZane Shelley */ 64*6e36587aSZane Shelley TemporaryFile& operator=(TemporaryFile&& file); 65*6e36587aSZane Shelley 66*6e36587aSZane Shelley /** 67*6e36587aSZane Shelley * Destructor. 68*6e36587aSZane Shelley * 69*6e36587aSZane Shelley * Deletes the temporary file if necessary. 70*6e36587aSZane Shelley */ ~TemporaryFile()71*6e36587aSZane Shelley ~TemporaryFile() 72*6e36587aSZane Shelley { 73*6e36587aSZane Shelley try 74*6e36587aSZane Shelley { 75*6e36587aSZane Shelley remove(); 76*6e36587aSZane Shelley } 77*6e36587aSZane Shelley catch (...) 78*6e36587aSZane Shelley { 79*6e36587aSZane Shelley // Destructors should not throw exceptions 80*6e36587aSZane Shelley } 81*6e36587aSZane Shelley } 82*6e36587aSZane Shelley 83*6e36587aSZane Shelley /** 84*6e36587aSZane Shelley * Deletes the temporary file. 85*6e36587aSZane Shelley * 86*6e36587aSZane Shelley * Does nothing if the file has already been deleted. 87*6e36587aSZane Shelley * 88*6e36587aSZane Shelley * Throws an exception if an error occurs during the deletion. 89*6e36587aSZane Shelley */ 90*6e36587aSZane Shelley void remove(); 91*6e36587aSZane Shelley 92*6e36587aSZane Shelley /** 93*6e36587aSZane Shelley * Returns the absolute path to the temporary file. 94*6e36587aSZane Shelley * 95*6e36587aSZane Shelley * Returns an empty path if the file has been deleted. 96*6e36587aSZane Shelley * 97*6e36587aSZane Shelley * @return temporary file path 98*6e36587aSZane Shelley */ getPath() const99*6e36587aSZane Shelley const fs::path& getPath() const 100*6e36587aSZane Shelley { 101*6e36587aSZane Shelley return path; 102*6e36587aSZane Shelley } 103*6e36587aSZane Shelley 104*6e36587aSZane Shelley private: 105*6e36587aSZane Shelley /** 106*6e36587aSZane Shelley * Absolute path to the temporary file. 107*6e36587aSZane Shelley * 108*6e36587aSZane Shelley * Empty when file has been deleted. 109*6e36587aSZane Shelley */ 110*6e36587aSZane Shelley fs::path path{}; 111*6e36587aSZane Shelley }; 112*6e36587aSZane Shelley 113*6e36587aSZane Shelley } // namespace util 114