fix bugs with variant

This commit is contained in:
Daniel Larimer 2013-08-15 10:56:25 -04:00
parent a080830c54
commit e7075f6b3a
2 changed files with 48 additions and 83 deletions

View file

@ -104,8 +104,8 @@ namespace fc
/// @param str - UTF8 string /// @param str - UTF8 string
variant( const char* str ); variant( const char* str );
variant( char* str ); variant( char* str );
variant( wchar_t* str ); variant( wchar_t* str );
variant( const wchar_t* str ); variant( const wchar_t* str );
variant( int val ); variant( int val );
variant( float val ); variant( float val );
variant( int64_t val ); variant( int64_t val );
@ -220,6 +220,7 @@ namespace fc
template<typename T> template<typename T>
variant( const optional<T>& v ) variant( const optional<T>& v )
{ {
memset( this, 0, sizeof(*this) );
if( v ) *this = variant(*v); if( v ) *this = variant(*v);
} }
@ -227,7 +228,9 @@ namespace fc
explicit variant( const T& val ); explicit variant( const T& val );
void clear();
private: private:
void init();
double _data; ///< Alligned according to double requirements double _data; ///< Alligned according to double requirements
char _type[sizeof(void*)]; ///< pad to void* size char _type[sizeof(void*)]; ///< pad to void* size
}; };

View file

@ -150,38 +150,7 @@ typedef const variant_object* const_variant_object_ptr;
typedef const variants* const_variants_ptr; typedef const variants* const_variants_ptr;
typedef const string* const_string_ptr; typedef const string* const_string_ptr;
variant::variant( const variant& v ) void variant::clear()
{
switch( v.get_type() )
{
case object_type:
*reinterpret_cast<variant_object**>(this) =
new variant_object(**reinterpret_cast<const const_variant_object_ptr*>(&v));
set_variant_type( this, object_type );
return;
case array_type:
*reinterpret_cast<variants**>(this) =
new variants(**reinterpret_cast<const const_variants_ptr*>(&v));
set_variant_type( this, array_type );
return;
case string_type:
*reinterpret_cast<string**>(this) =
new string(**reinterpret_cast<const const_string_ptr*>(&v) );
set_variant_type( this, string_type );
return;
default:
memcpy( this, &v, sizeof(v) );
}
}
variant::variant( variant&& v )
{
memcpy( this, &v, sizeof(v) );
set_variant_type( &v, null_type );
}
variant::~variant()
{ {
switch( get_type() ) switch( get_type() )
{ {
@ -197,65 +166,58 @@ variant::~variant()
default: default:
break; break;
} }
memset( this, 0, sizeof(*this) );
}
variant::variant( const variant& v )
{
switch( v.get_type() )
{
case object_type:
*reinterpret_cast<variant_object**>(this) =
new variant_object(**reinterpret_cast<const const_variant_object_ptr*>(&v));
set_variant_type( this, object_type );
return;
case array_type:
*reinterpret_cast<variants**>(this) =
new variants(**reinterpret_cast<const const_variants_ptr*>(&v));
set_variant_type( this, array_type );
return;
case string_type:
*reinterpret_cast<string**>(this) =
new string(**reinterpret_cast<const const_string_ptr*>(&v) );
set_variant_type( this, string_type );
return;
default:
memcpy( this, &v, sizeof(v) );
}
}
variant::variant( variant&& v )
{
memcpy( this, &v, sizeof(v) );
set_variant_type( &v, null_type );
}
variant::~variant()
{
clear();
} }
variant& variant::operator=( variant&& v ) variant& variant::operator=( variant&& v )
{ {
switch( get_type() ) if( this == &v ) return *this;
{ memcpy( (char*)this, (char*)&v, sizeof(v) );
set_variant_type( this, null_type ); v.clear();
case object_type:
delete *reinterpret_cast<variant_object**>(this);
break;
case array_type:
delete *reinterpret_cast<variants**>(this);
break;
case string_type:
delete *reinterpret_cast<string**>(this);
break;
default:
break;
}
switch( v.get_type() )
{
case object_type:
*reinterpret_cast<variant_object**>(this) = new variant_object(fc::move(**reinterpret_cast<variant_object**>(&v)));
set_variant_type( this, object_type );
return *this;
case array_type:
*reinterpret_cast<variants**>(this) = new variants(fc::move(**reinterpret_cast<variants**>(&v)));
set_variant_type( this, array_type );
return *this;
case string_type:
*reinterpret_cast<string**>(this) = new string(fc::move(**reinterpret_cast<string**>(&v)) );
set_variant_type( this, string_type );
return *this;
default:
memcpy( this, &v, sizeof(v) );
}
return *this; return *this;
} }
variant& variant::operator=( const variant& v ) variant& variant::operator=( const variant& v )
{ {
if( this == &v ) if( this == &v )
return *this; return *this;
switch( get_type() )
{ clear();
set_variant_type( this, null_type );
case object_type:
delete *reinterpret_cast<variant_object**>(this);
break;
case array_type:
delete *reinterpret_cast<variants**>(this);
break;
case string_type:
delete *reinterpret_cast<string**>(this);
break;
default:
break;
}
switch( v.get_type() ) switch( v.get_type() )
{ {
case object_type: case object_type: