diff --git a/include/fc/optional.hpp b/include/fc/optional.hpp index f5b8cdb..d0acd00 100644 --- a/include/fc/optional.hpp +++ b/include/fc/optional.hpp @@ -22,13 +22,6 @@ namespace fc { optional():_valid(false){} ~optional(){ reset(); } - optional( const optional& o ) - :_valid(false) - { - if( o._valid ) new (ptr()) T( *o ); - _valid = o._valid; - } - optional( optional& o ) :_valid(false) { @@ -36,6 +29,13 @@ namespace fc { _valid = o._valid; } + optional( const optional& o ) + :_valid(false) + { + if( o._valid ) new (ptr()) T( *o ); + _valid = o._valid; + } + optional( optional&& o ) :_valid(false) { @@ -44,6 +44,34 @@ namespace fc { o.reset(); } + template + optional( const optional& o ) + :_valid(false) + { + if( o._valid ) new (ptr()) T( *o ); + _valid = o._valid; + } + + template + optional( optional& o ) + :_valid(false) + { + if( o._valid ) + { + new (ptr()) T( *o ); + } + _valid = o._valid; + } + + template + optional( optional&& o ) + :_valid(false) + { + if( o._valid ) new (ptr()) T( fc::move(*o) ); + _valid = o._valid; + o.reset(); + } + template optional( U&& u ) :_valid(true) @@ -60,6 +88,49 @@ namespace fc { return *this; } + template + optional& operator=( optional& o ) { + if (this != &o) { + if( _valid && o._valid ) { + ref() = *o; + } else if( !_valid && o._valid ) { + new (ptr()) T( *o ); + _valid = true; + } else if (_valid) { + reset(); + } + } + return *this; + } + template + optional& operator=( const optional& o ) { + if (this != &o) { + if( _valid && o._valid ) { + ref() = *o; + } else if( !_valid && o._valid ) { + new (ptr()) T( *o ); + _valid = true; + } else if (_valid) { + reset(); + } + } + return *this; + } + + optional& operator=( optional& o ) { + if (this != &o) { + if( _valid && o._valid ) { + ref() = *o; + } else if( !_valid && o._valid ) { + new (ptr()) T( *o ); + _valid = true; + } else if (_valid) { + reset(); + } + } + return *this; + } + optional& operator=( const optional& o ) { if (this != &o) { if( _valid && o._valid ) { @@ -74,6 +145,24 @@ namespace fc { return *this; } + template + optional& operator=( optional&& o ) + { + if (this != &o) + { + if( _valid && o._valid ) + { + ref() = fc::move(*o); + o.reset(); + } else if ( !_valid && o._valid ) { + *this = fc::move(*o); + } else if (_valid) { + reset(); + } + } + return *this; + } + optional& operator=( optional&& o ) { if (this != &o)