fix bugs in optional implementation
This commit is contained in:
parent
58d950b56f
commit
7e61059806
3 changed files with 94 additions and 87 deletions
|
|
@ -160,13 +160,13 @@ namespace fc {
|
||||||
/**
|
/**
|
||||||
* Class which creates a temporary directory inside an existing temporary directory.
|
* Class which creates a temporary directory inside an existing temporary directory.
|
||||||
*/
|
*/
|
||||||
class temp_directory : public temp_file_base
|
class temp_directory : public temp_file_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
temp_directory(temp_directory&& other);
|
temp_directory(temp_directory&& other);
|
||||||
temp_directory& operator=(temp_directory&& other);
|
temp_directory& operator=(temp_directory&& other);
|
||||||
temp_directory(const fc::path& tempFolder = fc::temp_directory_path());
|
temp_directory(const fc::path& tempFolder = fc::temp_directory_path());
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
#include <fc/utility.hpp>
|
#include <fc/utility.hpp>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace fc {
|
namespace fc {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
|
|
@ -45,17 +47,18 @@ namespace fc {
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
optional( U&& u )
|
optional( U&& u )
|
||||||
:_valid(false)
|
:_valid(true)
|
||||||
{
|
{
|
||||||
new (ptr()) T( fc::forward<U>(u) );
|
new ((char*)ptr()) T( fc::forward<U>(u) );
|
||||||
_valid = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
optional& operator=( U&& u )
|
optional& operator=( U&& u )
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
fprintf( stderr, "optional==(U&&)...\n" );
|
||||||
new (ptr()) T( fc::forward<U>(u) );
|
new (ptr()) T( fc::forward<U>(u) );
|
||||||
|
_valid = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,8 +80,10 @@ namespace fc {
|
||||||
{
|
{
|
||||||
if (this != &o)
|
if (this != &o)
|
||||||
{
|
{
|
||||||
if( _valid && o._valid ) {
|
if( _valid && o._valid )
|
||||||
|
{
|
||||||
ref() = fc::move(*o);
|
ref() = fc::move(*o);
|
||||||
|
o.reset();
|
||||||
} else if ( !_valid && o._valid ) {
|
} else if ( !_valid && o._valid ) {
|
||||||
*this = fc::move(*o);
|
*this = fc::move(*o);
|
||||||
} else if (_valid) {
|
} else if (_valid) {
|
||||||
|
|
@ -110,8 +115,10 @@ namespace fc {
|
||||||
{
|
{
|
||||||
if( _valid )
|
if( _valid )
|
||||||
{
|
{
|
||||||
|
fprintf( stderr, "optiona::reset %p\n", this );
|
||||||
ref().~T(); // cal destructor
|
ref().~T(); // cal destructor
|
||||||
}
|
}
|
||||||
|
_valid = false;
|
||||||
}
|
}
|
||||||
T& ref() { return *ptr(); }
|
T& ref() { return *ptr(); }
|
||||||
const T& ref()const { return *ptr(); }
|
const T& ref()const { return *ptr(); }
|
||||||
|
|
|
||||||
|
|
@ -218,84 +218,84 @@ namespace fc {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_file::temp_file(const fc::path& p, bool create)
|
temp_file::temp_file(const fc::path& p, bool create)
|
||||||
: temp_file_base(p / fc::unique_path())
|
: temp_file_base(p / fc::unique_path())
|
||||||
{
|
{
|
||||||
if (fc::exists(*_path))
|
if (fc::exists(*_path))
|
||||||
{
|
{
|
||||||
FC_THROW( "Name collision: ${path}", ("path", _path->string()) );
|
FC_THROW( "Name collision: ${path}", ("path", _path->string()) );
|
||||||
}
|
}
|
||||||
if (create)
|
if (create)
|
||||||
{
|
{
|
||||||
fc::ofstream ofs(*_path, fc::ofstream::out | fc::ofstream::binary);
|
fc::ofstream ofs(*_path, fc::ofstream::out | fc::ofstream::binary);
|
||||||
ofs.close();
|
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_directory::temp_directory(const fc::path& p)
|
temp_file::temp_file(temp_file&& other)
|
||||||
: temp_file_base(p / fc::unique_path())
|
: temp_file_base(std::move(other._path))
|
||||||
{
|
{
|
||||||
if (fc::exists(*_path))
|
}
|
||||||
{
|
|
||||||
FC_THROW( "Name collision: ${path}", ("path", _path->string()) );
|
temp_file& temp_file::operator=(temp_file&& other)
|
||||||
}
|
{
|
||||||
fc::create_directories(*_path);
|
if (this != &other)
|
||||||
}
|
{
|
||||||
|
remove();
|
||||||
temp_directory::temp_directory(temp_directory&& other)
|
_path = std::move(other._path);
|
||||||
: temp_file_base(std::move(other._path))
|
}
|
||||||
{
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_directory& temp_directory::operator=(temp_directory&& other)
|
temp_directory::temp_directory(const fc::path& p)
|
||||||
{
|
: temp_file_base(p / fc::unique_path())
|
||||||
if (this != &other)
|
{
|
||||||
{
|
if (fc::exists(*_path))
|
||||||
remove();
|
{
|
||||||
_path = std::move(other._path);
|
FC_THROW( "Name collision: ${path}", ("path", _path->string()) );
|
||||||
}
|
}
|
||||||
return *this;
|
fc::create_directories(*_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fc::path& temp_file_base::path() const
|
temp_directory::temp_directory(temp_directory&& other)
|
||||||
{
|
: temp_file_base(std::move(other._path))
|
||||||
if (!_path)
|
{
|
||||||
{
|
}
|
||||||
FC_THROW( "Temporary directory has been released." );
|
|
||||||
}
|
temp_directory& temp_directory::operator=(temp_directory&& other)
|
||||||
return *_path;
|
{
|
||||||
}
|
if (this != &other)
|
||||||
|
{
|
||||||
void temp_file_base::remove()
|
remove();
|
||||||
{
|
_path = std::move(other._path);
|
||||||
if (_path)
|
}
|
||||||
{
|
return *this;
|
||||||
try
|
}
|
||||||
{
|
|
||||||
fc::remove_all(*_path);
|
const fc::path& temp_file_base::path() const
|
||||||
}
|
{
|
||||||
catch (...)
|
if (!_path)
|
||||||
{
|
{
|
||||||
// eat errors on cleanup
|
FC_THROW( "Temporary directory has been released." );
|
||||||
}
|
}
|
||||||
release();
|
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()
|
void temp_file_base::release()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue