diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index 4de03c5..7cdc96c 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -104,8 +104,8 @@ namespace fc /// @param str - UTF8 string variant( const char* str ); variant( char* str ); - variant( wchar_t* str ); - variant( const wchar_t* str ); + variant( wchar_t* str ); + variant( const wchar_t* str ); variant( int val ); variant( float val ); variant( int64_t val ); @@ -220,6 +220,7 @@ namespace fc template variant( const optional& v ) { + memset( this, 0, sizeof(*this) ); if( v ) *this = variant(*v); } @@ -227,7 +228,9 @@ namespace fc explicit variant( const T& val ); + void clear(); private: + void init(); double _data; ///< Alligned according to double requirements char _type[sizeof(void*)]; ///< pad to void* size }; diff --git a/src/variant.cpp b/src/variant.cpp index 8110c12..86ee07d 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -150,38 +150,7 @@ typedef const variant_object* const_variant_object_ptr; typedef const variants* const_variants_ptr; typedef const string* const_string_ptr; -variant::variant( const variant& v ) -{ - switch( v.get_type() ) - { - case object_type: - *reinterpret_cast(this) = - new variant_object(**reinterpret_cast(&v)); - set_variant_type( this, object_type ); - return; - case array_type: - *reinterpret_cast(this) = - new variants(**reinterpret_cast(&v)); - set_variant_type( this, array_type ); - return; - case string_type: - *reinterpret_cast(this) = - new string(**reinterpret_cast(&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() +void variant::clear() { switch( get_type() ) { @@ -197,65 +166,58 @@ variant::~variant() default: break; } + memset( this, 0, sizeof(*this) ); +} + +variant::variant( const variant& v ) +{ + switch( v.get_type() ) + { + case object_type: + *reinterpret_cast(this) = + new variant_object(**reinterpret_cast(&v)); + set_variant_type( this, object_type ); + return; + case array_type: + *reinterpret_cast(this) = + new variants(**reinterpret_cast(&v)); + set_variant_type( this, array_type ); + return; + case string_type: + *reinterpret_cast(this) = + new string(**reinterpret_cast(&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 ) { - switch( get_type() ) - { - set_variant_type( this, null_type ); - case object_type: - delete *reinterpret_cast(this); - break; - case array_type: - delete *reinterpret_cast(this); - break; - case string_type: - delete *reinterpret_cast(this); - break; - default: - break; - } - switch( v.get_type() ) - { - case object_type: - *reinterpret_cast(this) = new variant_object(fc::move(**reinterpret_cast(&v))); - set_variant_type( this, object_type ); - return *this; - case array_type: - *reinterpret_cast(this) = new variants(fc::move(**reinterpret_cast(&v))); - set_variant_type( this, array_type ); - return *this; - case string_type: - *reinterpret_cast(this) = new string(fc::move(**reinterpret_cast(&v)) ); - set_variant_type( this, string_type ); - return *this; - - default: - memcpy( this, &v, sizeof(v) ); - } - + if( this == &v ) return *this; + memcpy( (char*)this, (char*)&v, sizeof(v) ); + v.clear(); return *this; } + variant& variant::operator=( const variant& v ) { if( this == &v ) return *this; - switch( get_type() ) - { - set_variant_type( this, null_type ); - case object_type: - delete *reinterpret_cast(this); - break; - case array_type: - delete *reinterpret_cast(this); - break; - case string_type: - delete *reinterpret_cast(this); - break; - default: - break; - } + + clear(); switch( v.get_type() ) { case object_type: