Bug 944176: Implement move construction and move assignment for mozilla::Scoped derivatives. r=waldo

This commit is contained in:
Jim Blandy 2014-03-27 09:52:48 -07:00
parent 37ecc02d31
commit 627a216d99

View File

@ -52,8 +52,10 @@
* the scope, graphics contexts, etc. * the scope, graphics contexts, etc.
*/ */
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/GuardObjects.h" #include "mozilla/GuardObjects.h"
#include "mozilla/Move.h"
#include "mozilla/NullPtr.h" #include "mozilla/NullPtr.h"
namespace mozilla { namespace mozilla {
@ -83,12 +85,23 @@ class Scoped
{ {
MOZ_GUARD_OBJECT_NOTIFIER_INIT; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
} }
explicit Scoped(const Resource& v explicit Scoped(const Resource& v
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: value(v) : value(v)
{ {
MOZ_GUARD_OBJECT_NOTIFIER_INIT; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
} }
/* Move constructor. */
explicit Scoped(Scoped&& v
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: value(Move(v.value))
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
v.value = Traits::empty();
}
~Scoped() { ~Scoped() {
Traits::release(value); Traits::release(value);
} }
@ -146,6 +159,14 @@ class Scoped
return *this; return *this;
} }
/* Move assignment operator. */
Scoped& operator=(Scoped&& rhs) {
MOZ_ASSERT(&rhs != this, "self-move-assignment not allowed");
this->~Scoped();
new(this) Scoped(Move(rhs));
return *this;
}
private: private:
explicit Scoped(const Scoped& value) MOZ_DELETE; explicit Scoped(const Scoped& value) MOZ_DELETE;
Scoped& operator=(const Scoped& value) MOZ_DELETE; Scoped& operator=(const Scoped& value) MOZ_DELETE;
@ -169,20 +190,30 @@ struct name : public mozilla::Scoped<Traits<Type> > \
{ \ { \
typedef mozilla::Scoped<Traits<Type> > Super; \ typedef mozilla::Scoped<Traits<Type> > Super; \
typedef typename Super::Resource Resource; \ typedef typename Super::Resource Resource; \
name& operator=(Resource ptr) { \ name& operator=(Resource rhs) { \
Super::operator=(ptr); \ Super::operator=(rhs); \
return *this; \
} \
name& operator=(name&& rhs) { \
Super::operator=(Move(rhs)); \
return *this; \ return *this; \
} \ } \
explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \ explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \
: Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \ : Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \
{} \ {} \
explicit name(Resource ptr \ explicit name(Resource rhs \
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
: Super(ptr MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ : Super(rhs \
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
{} \
explicit name(name&& rhs \
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
: Super(Move(rhs) \
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
{} \ {} \
private: \ private: \
explicit name(name& source) MOZ_DELETE; \ explicit name(name&) MOZ_DELETE; \
name& operator=(name& source) MOZ_DELETE; \ name& operator=(name&) MOZ_DELETE; \
}; };
/* /*