diff --git a/fs/scoped.cpp b/fs/scoped.cpp index f4f12c36..db796a9f 100644 --- a/fs/scoped.cpp +++ b/fs/scoped.cpp @@ -11,6 +11,55 @@ #include using cruft::fs::scoped_dir; +using cruft::fs::scoped_path; + + +/////////////////////////////////////////////////////////////////////////////// +scoped_path::scoped_path (std::filesystem::path &&_path) + : m_path (std::move (_path)) +{ + CHECK (std::filesystem::exists (*m_path)); +} + + +//----------------------------------------------------------------------------- +scoped_path::scoped_path (std::filesystem::path const &_path) + : scoped_path (std::filesystem::path (_path)) +{ ; } + + +//----------------------------------------------------------------------------- +std::filesystem::path const& +scoped_path::get () const& +{ + return *m_path; +} + + +//----------------------------------------------------------------------------- +std::filesystem::path +scoped_path::release () +{ + auto res = std::move (*m_path); + m_path.reset (); + return res; +} + + +//----------------------------------------------------------------------------- +void +scoped_path::reset (void) +{ + return m_path.reset (); +} + + +//----------------------------------------------------------------------------- +scoped_path::~scoped_path () +{ + if (m_path) + std::filesystem::remove_all (*m_path); +} /////////////////////////////////////////////////////////////////////////////// @@ -21,25 +70,17 @@ scoped_dir::scoped_dir (std::filesystem::path const &_path) //----------------------------------------------------------------------------- scoped_dir::scoped_dir (std::filesystem::path &&_path) - : m_path (std::move (_path)) + : scoped_path (std::move (_path)) { - CHECK (std::filesystem::is_directory (*m_path)); + CHECK (std::filesystem::is_directory (get ())); } -/////////////////////////////////////////////////////////////////////////////// -scoped_dir::~scoped_dir () -{ - if (m_path) - std::filesystem::remove_all (*m_path); -} - - -/////////////////////////////////////////////////////////////////////////////// +//----------------------------------------------------------------------------- std::filesystem::path const & scoped_dir::operator* () const & { - return *m_path; + return get (); } @@ -47,5 +88,5 @@ scoped_dir::operator* () const & std::filesystem::path const* scoped_dir::operator-> () const & { - return &*m_path; + return &get(); } diff --git a/fs/scoped.hpp b/fs/scoped.hpp index dcccad2c..f936969b 100644 --- a/fs/scoped.hpp +++ b/fs/scoped.hpp @@ -12,26 +12,42 @@ /////////////////////////////////////////////////////////////////////////////// namespace cruft::fs { - ///------------------------------------------------------------------------ - /// Holds the path to a directory that will be deleted (along with all - /// contents) when the object goes out of scope. - class scoped_dir { + /// Holds a path and deletes the path (and it any contents if it's a + /// directory) at destruction. + class scoped_path { public: - explicit scoped_dir (std::filesystem::path const&); - explicit scoped_dir (std::filesystem::path &&); + explicit scoped_path (std::filesystem::path const&); + explicit scoped_path (std::filesystem::path &&); - scoped_dir (scoped_dir const&) = delete; - scoped_dir& operator= (scoped_dir const&) = delete; + scoped_path (scoped_path const&) = delete; + scoped_path& operator= (scoped_path const&) = delete; - scoped_dir (scoped_dir&&) noexcept = default; - scoped_dir& operator= (scoped_dir&&) noexcept = default; + scoped_path (scoped_path&&) noexcept = default; + scoped_path& operator= (scoped_path&&) noexcept = default; - ~scoped_dir (); + ~scoped_path (); - std::filesystem::path const& operator* () const&; - std::filesystem::path const* operator-> () const&; + std::filesystem::path const& get (void) const&; + + std::filesystem::path release (void); + void reset (void); private: std::optional m_path; }; + + + ///------------------------------------------------------------------------ + /// Holds the path to a directory that will be deleted (along with all + /// contents) when the object goes out of scope. + class scoped_dir : public scoped_path { + public: + explicit scoped_dir (std::filesystem::path const&); + explicit scoped_dir (std::filesystem::path &&); + + using scoped_path::scoped_path; + + std::filesystem::path const& operator* () const&; + std::filesystem::path const* operator-> () const&; + }; } \ No newline at end of file diff --git a/test/fs/scoped.cpp b/test/fs/scoped.cpp index 35f6a16c..33c5c421 100644 --- a/test/fs/scoped.cpp +++ b/test/fs/scoped.cpp @@ -22,5 +22,19 @@ main (int, char**) tap.expect (success, "scoped_dir removes directory after scope"); } + { + bool success = true; + + auto const path = cruft::fs::mktmpdir (); + + cruft::fs::scoped_path dir (path); + success = success && std::filesystem::exists (path); + + dir.reset (); + success = success && !std::filesystem::exists (path); + + tap.expect (true, "scoped_path"); + } + return tap.status (); } \ No newline at end of file