diff --git a/synfig-core/src/synfig/value.cpp b/synfig-core/src/synfig/value.cpp index 754d106..98acf8f 100644 --- a/synfig-core/src/synfig/value.cpp +++ b/synfig-core/src/synfig/value.cpp @@ -67,7 +67,7 @@ using namespace etl; /* === M E T H O D S ======================================================= */ ValueBase::ValueBase(): - type(&type_nil),data(0),ref_count(0),loop_(0),static_(0),interpolation_(INTERPOLATION_UNDEFINED) + type(&type_nil),data(nullptr),ref_count(0),loop_(0),static_(0),interpolation_(INTERPOLATION_UNDEFINED) { #ifdef INITIALIZE_TYPE_BEFORE_USE type->initialize(); @@ -75,7 +75,7 @@ ValueBase::ValueBase(): } ValueBase::ValueBase(Type &x): - type(&type_nil),data(0),ref_count(0),loop_(0),static_(0),interpolation_(INTERPOLATION_UNDEFINED) + type(&type_nil),data(nullptr),ref_count(0),loop_(0),static_(0),interpolation_(INTERPOLATION_UNDEFINED) { #ifdef INITIALIZE_TYPE_BEFORE_USE type->initialize(); @@ -83,11 +83,48 @@ ValueBase::ValueBase(Type &x): create(x); } +ValueBase::ValueBase(const ValueBase& x) + : ValueBase(*x.type) +{ + if(data != x.data) + { + Operation::CopyFunc copy_func = + Type::get_operation( + Operation::Description::get_copy(type->identifier, type->identifier) ); + if (copy_func) + { + copy_func(data, x.data); + } + else + { + data = x.data; + ref_count = x.ref_count; + } + } + + loop_ = x.loop_; + static_ = x.static_; + interpolation_ = x.interpolation_; +} + +ValueBase::ValueBase(ValueBase&& x) + : ValueBase() +{ + swap(*this, x); +} + ValueBase::~ValueBase() { clear(); } +ValueBase& +ValueBase::operator=(ValueBase x) +{ + swap(*this, x); + return *this; +} + #ifdef _DEBUG String ValueBase::get_string() const @@ -128,7 +165,7 @@ ValueBase::copy(const ValueBase& x) Operation::CopyFunc func = Type::get_operation( Operation::Description::get_copy(type->identifier, x.type->identifier)); - if (func != NULL) + if (func) { if (!ref_count.unique()) create(); func(data, x.data); @@ -138,7 +175,7 @@ ValueBase::copy(const ValueBase& x) Operation::CopyFunc func = Type::get_operation( Operation::Description::get_copy(x.type->identifier, x.type->identifier)); - if (func != NULL) + if (func) { if (!ref_count.unique()) create(*x.type); func(data, x.data); @@ -169,35 +206,6 @@ ValueBase::get_contained_type()const return get_list().front().get_type(); } -ValueBase& -ValueBase::operator=(const ValueBase& x) -{ - if(data!=x.data) - { - Type ¤t_type = *type; - Type &new_type = *x.type; - Operation::CopyFunc func = - Type::get_operation( - Operation::Description::get_copy(current_type.identifier, new_type.identifier) ); - if (func != NULL) - { - create(current_type); - func(data, x.data); - } - else - { - clear(); - type=x.type; - data=x.data; - ref_count=x.ref_count; - } - } - loop_=x.loop_; - static_=x.static_; - interpolation_=x.interpolation_; - return *this; -} - void ValueBase::clear() { @@ -210,16 +218,15 @@ ValueBase::clear() func(data); } ref_count.detach(); - data=0; + data=nullptr; type=&type_nil; } - Type& ValueBase::ident_type(const String &str) { Type *type = Type::try_get_type_by_name(str); - return type == NULL ? type_nil : *type; + return type ? *type : type_nil; } bool @@ -228,7 +235,7 @@ ValueBase::operator==(const ValueBase& rhs)const Operation::EqualFunc func = Type::get_operation( Operation::Description::get_equal(type->identifier, rhs.type->identifier) ); - return func == NULL ? false : func(data, rhs.data); + return !func ? false : func(data, rhs.data); } bool @@ -237,5 +244,5 @@ ValueBase::operator<(const ValueBase& rhs)const Operation::LessFunc func = Type::get_operation( Operation::Description::get_less(type->identifier, rhs.type->identifier) ); - return func == NULL ? false : func(data, rhs.data); + return !func ? false : func(data, rhs.data); } diff --git a/synfig-core/src/synfig/value.h b/synfig-core/src/synfig/value.h index e3a0881..a7b88a8 100644 --- a/synfig-core/src/synfig/value.h +++ b/synfig-core/src/synfig/value.h @@ -103,7 +103,7 @@ public: //! Template constructor for any type template ValueBase(const T &x, bool loop_=false, bool static_=false): - type(&type_nil),data(0),ref_count(0),loop_(loop_), static_(static_), + type(&type_nil),data(nullptr),ref_count(0),loop_(loop_), static_(static_), interpolation_(INTERPOLATION_UNDEFINED) { #ifdef INITIALIZE_TYPE_BEFORE_USE @@ -114,7 +114,7 @@ public: template ValueBase(const std::vector &x, bool loop_=false, bool static_=false): - type(&type_nil),data(0),ref_count(0),loop_(loop_), static_(static_), + type(&type_nil),data(nullptr),ref_count(0),loop_(loop_), static_(static_), interpolation_(INTERPOLATION_UNDEFINED) { #ifdef INITIALIZE_TYPE_BEFORE_USE @@ -123,11 +123,17 @@ public: set_list_of(x); } - //! Copy constructor. The data is not copied, just the type. + //! Constructor with the type set. ValueBase(Type &x); + //! Copy constructor + ValueBase(const ValueBase &x); + + //! Move constructor + ValueBase(ValueBase&& x); + //! Default destructor - ~ValueBase(); + virtual ~ValueBase(); /* -- ** -- O P E R A T O R S --------------------------------------------------- @@ -140,8 +146,8 @@ public: template ValueBase& operator=(const T& x) { set(x); return *this; } - //!Operator asignation for ValueBase classes. Does a exact copy of \x - ValueBase& operator=(const ValueBase& x); + //!Copy/Move assignment operator for ValueBase classes + ValueBase& operator=(ValueBase x); //! Equal than operator. Segment, Gradient and Bline Points cannot be compared. bool operator==(const ValueBase& rhs)const; @@ -172,6 +178,16 @@ public: //! Deletes the data only if the ref count is zero void clear(); + //! Swap object contents + friend void swap(ValueBase& first, ValueBase& second) { + std::swap(first.type, second.type); + std::swap(first.data, second.data); + std::swap(first.ref_count, second.ref_count); + std::swap(first.loop_, second.loop_); + std::swap(first.static_, second.static_); + std::swap(first.interpolation_, second.interpolation_); + } + //! Gets the loop option. bool get_loop()const { return loop_; } @@ -227,7 +243,7 @@ public: template inline static bool can_put(const Type& type, const T &x) { return can_put(type.identifier, x); } inline static bool can_copy(const TypeId dest, const TypeId src) - { return NULL != Type::get_operation(Operation::Description::get_copy(dest, src)); } + { return Type::get_operation(Operation::Description::get_copy(dest, src)); } inline static bool can_copy(const Type& dest, const Type& src) { return can_copy(dest.identifier, src.identifier); } template inline bool can_get(const T &x) const { return is_valid() && can_get(*type, x); }