From 7e61059806ca02250315a02ab98f95aafb3b52bf Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 5 Jul 2013 19:48:59 -0400 Subject: [PATCH] fix bugs in optional implementation --- include/fc/filesystem.hpp | 14 ++-- include/fc/optional.hpp | 15 +++- src/filesystem.cpp | 152 +++++++++++++++++++------------------- 3 files changed, 94 insertions(+), 87 deletions(-) diff --git a/include/fc/filesystem.hpp b/include/fc/filesystem.hpp index 988d11c..f7eb868 100644 --- a/include/fc/filesystem.hpp +++ b/include/fc/filesystem.hpp @@ -160,13 +160,13 @@ namespace fc { /** * Class which creates a temporary directory inside an existing temporary directory. */ - class temp_directory : public temp_file_base - { - public: - temp_directory(temp_directory&& other); - temp_directory& operator=(temp_directory&& other); - temp_directory(const fc::path& tempFolder = fc::temp_directory_path()); - }; + class temp_directory : public temp_file_base + { + public: + temp_directory(temp_directory&& other); + temp_directory& operator=(temp_directory&& other); + temp_directory(const fc::path& tempFolder = fc::temp_directory_path()); + }; } diff --git a/include/fc/optional.hpp b/include/fc/optional.hpp index 102b238..b851c40 100644 --- a/include/fc/optional.hpp +++ b/include/fc/optional.hpp @@ -2,6 +2,8 @@ #include #include +#include + namespace fc { #ifdef _MSC_VER # pragma warning(push) @@ -45,17 +47,18 @@ namespace fc { template optional( U&& u ) - :_valid(false) + :_valid(true) { - new (ptr()) T( fc::forward(u) ); - _valid = true; + new ((char*)ptr()) T( fc::forward(u) ); } template optional& operator=( U&& u ) { reset(); + fprintf( stderr, "optional==(U&&)...\n" ); new (ptr()) T( fc::forward(u) ); + _valid = true; return *this; } @@ -77,8 +80,10 @@ namespace fc { { if (this != &o) { - if( _valid && o._valid ) { + if( _valid && o._valid ) + { ref() = fc::move(*o); + o.reset(); } else if ( !_valid && o._valid ) { *this = fc::move(*o); } else if (_valid) { @@ -110,8 +115,10 @@ namespace fc { { if( _valid ) { + fprintf( stderr, "optiona::reset %p\n", this ); ref().~T(); // cal destructor } + _valid = false; } T& ref() { return *ptr(); } const T& ref()const { return *ptr(); } diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 972b66a..5a40007 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -218,84 +218,84 @@ namespace fc { return ret; } - temp_file::temp_file(const fc::path& p, bool create) - : temp_file_base(p / fc::unique_path()) - { - if (fc::exists(*_path)) - { - FC_THROW( "Name collision: ${path}", ("path", _path->string()) ); - } - if (create) - { - fc::ofstream ofs(*_path, fc::ofstream::out | fc::ofstream::binary); - ofs.close(); - } - } - - temp_file::temp_file(temp_file&& other) - : temp_file_base(std::move(other._path)) - { - } - - temp_file& temp_file::operator=(temp_file&& other) - { - if (this != &other) - { - remove(); - _path = std::move(other._path); - } - return *this; + temp_file::temp_file(const fc::path& p, bool create) + : temp_file_base(p / fc::unique_path()) + { + if (fc::exists(*_path)) + { + FC_THROW( "Name collision: ${path}", ("path", _path->string()) ); + } + if (create) + { + fc::ofstream ofs(*_path, fc::ofstream::out | fc::ofstream::binary); + ofs.close(); + } } - temp_directory::temp_directory(const fc::path& p) - : temp_file_base(p / fc::unique_path()) - { - if (fc::exists(*_path)) - { - FC_THROW( "Name collision: ${path}", ("path", _path->string()) ); - } - fc::create_directories(*_path); - } - - temp_directory::temp_directory(temp_directory&& other) - : temp_file_base(std::move(other._path)) - { - } - - temp_directory& temp_directory::operator=(temp_directory&& other) - { - if (this != &other) - { - remove(); - _path = std::move(other._path); - } - return *this; - } - - const fc::path& temp_file_base::path() const - { - if (!_path) - { - FC_THROW( "Temporary directory has been released." ); - } - return *_path; - } - - void temp_file_base::remove() - { - if (_path) - { - try - { - fc::remove_all(*_path); - } - catch (...) - { - // eat errors on cleanup - } - release(); - } - } + temp_file::temp_file(temp_file&& other) + : temp_file_base(std::move(other._path)) + { + } + + temp_file& temp_file::operator=(temp_file&& other) + { + if (this != &other) + { + remove(); + _path = std::move(other._path); + } + return *this; + } + + temp_directory::temp_directory(const fc::path& p) + : temp_file_base(p / fc::unique_path()) + { + if (fc::exists(*_path)) + { + FC_THROW( "Name collision: ${path}", ("path", _path->string()) ); + } + fc::create_directories(*_path); + } + + temp_directory::temp_directory(temp_directory&& other) + : temp_file_base(std::move(other._path)) + { + } + + temp_directory& temp_directory::operator=(temp_directory&& other) + { + if (this != &other) + { + remove(); + _path = std::move(other._path); + } + return *this; + } + + const fc::path& temp_file_base::path() const + { + if (!_path) + { + FC_THROW( "Temporary directory has been released." ); + } + return *_path; + } + + void temp_file_base::remove() + { + if (_path) + { + try + { + fc::remove_all(*_path); + } + catch (...) + { + // eat errors on cleanup + } + release(); + } + } void temp_file_base::release() {