Line data Source code
1 : #ifndef FILESYSTEM_H 2 : #define FILESYSTEM_H 3 : 4 : // clang-format off 5 : #if __has_include(<filesystem>) 6 : # include <filesystem> 7 : #elif __has_include(<experimental/filesystem>) 8 : # include <experimental/filesystem> 9 : #else 10 : # error "Compiler does not support <filesystem> or <experimental/filesystem>" 11 : #endif 12 : // clang-format on 13 : 14 : #include <cereal/types/string.hpp> 15 : 16 : #include <memory> 17 : 18 : #include <cstdio> 19 : #include <cstdlib> 20 : #include <cstring> 21 : 22 : namespace fs { 23 : 24 : #if __has_include(<filesystem>) 25 : using namespace std::filesystem; 26 : #elif __has_include(<experimental/filesystem>) 27 : using namespace std::experimental::filesystem; 28 : #endif 29 : 30 : /// \brief Generate temporary directory 31 : /// 32 : /// \returns path to a temporary directory 33 : /// \warning Not thread-safe! 34 1 : inline path create_temp_directory() { 35 : #if defined(__unix__) || defined(__linux__) || defined(__APPLE__) 36 3 : path const p = temp_directory_path() / "tmpXXXXXX"; 37 2 : std::unique_ptr<char, decltype(&std::free)> tmpl{strdup(p.c_str()), &std::free}; 38 1 : char const *const dirname = mkdtemp(tmpl.get()); 39 1 : if (dirname == nullptr) { 40 0 : throw std::runtime_error(std::strerror(errno)); 41 : } 42 : #elif defined(_WIN32) 43 : char const *const dirname = std::tmpnam(nullptr); 44 : if (dirname == nullptr) { 45 : throw std::runtime_error("Could not create temporary directory"); 46 : } 47 : fs::create_directory(dirname); 48 : #else 49 : #error "Compiler does support not mkdtemp()" 50 : #endif 51 2 : return dirname; 52 : } 53 : 54 : template <class Archive> 55 : void CEREAL_LOAD_MINIMAL_FUNCTION_NAME(Archive const & /* unused */, path &p, 56 : std::string const &s) { 57 : p = path(s); 58 : } 59 : 60 : template <class Archive> 61 : std::string CEREAL_SAVE_MINIMAL_FUNCTION_NAME(Archive const & /* unused */, path const &p) { 62 : return p.string(); 63 : } 64 : 65 : } // namespace fs 66 : 67 : #endif // FILESYSTEM_H