fix bugs in optional implementation

This commit is contained in:
Daniel Larimer 2013-07-05 19:48:59 -04:00
parent 58d950b56f
commit 7e61059806
3 changed files with 94 additions and 87 deletions

View file

@ -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());
};
}

View file

@ -2,6 +2,8 @@
#include <fc/utility.hpp>
#include <assert.h>
#include <stdio.h>
namespace fc {
#ifdef _MSC_VER
# pragma warning(push)
@ -45,17 +47,18 @@ namespace fc {
template<typename U>
optional( U&& u )
:_valid(false)
:_valid(true)
{
new (ptr()) T( fc::forward<U>(u) );
_valid = true;
new ((char*)ptr()) T( fc::forward<U>(u) );
}
template<typename U>
optional& operator=( U&& u )
{
reset();
fprintf( stderr, "optional==(U&&)...\n" );
new (ptr()) T( fc::forward<U>(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(); }

View file

@ -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()
{