1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Created c++11 move constructors and operator= methods for a bunch of classes (only enabled for c++11 compilers, of course)

This commit is contained in:
Julian Storer 2011-08-21 21:20:28 +01:00
parent 2c328dfedc
commit ffc2f5d40e
46 changed files with 629 additions and 39 deletions

View file

@ -79,14 +79,31 @@ int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) noexcept
return messageLengths [firstByte & 0x7f]; return messageLengths [firstByte & 0x7f];
} }
//==============================================================================
inline void MidiMessage::setToUseInternalData() noexcept
{
data = static_cast <uint8*> (preallocatedData.asBytes);
}
inline bool MidiMessage::usesAllocatedData() const noexcept
{
return data != static_cast <const uint8*> (preallocatedData.asBytes);
}
inline void MidiMessage::freeData() noexcept
{
if (usesAllocatedData())
delete[] data;
}
//============================================================================== //==============================================================================
MidiMessage::MidiMessage() noexcept MidiMessage::MidiMessage() noexcept
: timeStamp (0), : timeStamp (0),
data (static_cast<uint8*> (preallocatedData.asBytes)), data (static_cast<uint8*> (preallocatedData.asBytes)),
size (2) size (2)
{ {
data[0] = 0xf0; preallocatedData.asBytes[0] = 0xf0;
data[1] = 0xf7; preallocatedData.asBytes[1] = 0xf7;
} }
MidiMessage::MidiMessage (const void* const d, const int dataSize, const double t) MidiMessage::MidiMessage (const void* const d, const int dataSize, const double t)
@ -96,7 +113,7 @@ MidiMessage::MidiMessage (const void* const d, const int dataSize, const double
jassert (dataSize > 0); jassert (dataSize > 0);
if (dataSize <= 4) if (dataSize <= 4)
data = static_cast<uint8*> (preallocatedData.asBytes); setToUseInternalData();
else else
data = new uint8 [dataSize]; data = new uint8 [dataSize];
@ -111,7 +128,7 @@ MidiMessage::MidiMessage (const int byte1, const double t) noexcept
data (static_cast<uint8*> (preallocatedData.asBytes)), data (static_cast<uint8*> (preallocatedData.asBytes)),
size (1) size (1)
{ {
data[0] = (uint8) byte1; preallocatedData.asBytes[0] = (uint8) byte1;
// check that the length matches the data.. // check that the length matches the data..
jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 1); jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 1);
@ -122,8 +139,8 @@ MidiMessage::MidiMessage (const int byte1, const int byte2, const double t) noex
data (static_cast<uint8*> (preallocatedData.asBytes)), data (static_cast<uint8*> (preallocatedData.asBytes)),
size (2) size (2)
{ {
data[0] = (uint8) byte1; preallocatedData.asBytes[0] = (uint8) byte1;
data[1] = (uint8) byte2; preallocatedData.asBytes[1] = (uint8) byte2;
// check that the length matches the data.. // check that the length matches the data..
jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 2); jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 2);
@ -134,9 +151,9 @@ MidiMessage::MidiMessage (const int byte1, const int byte2, const int byte3, con
data (static_cast<uint8*> (preallocatedData.asBytes)), data (static_cast<uint8*> (preallocatedData.asBytes)),
size (3) size (3)
{ {
data[0] = (uint8) byte1; preallocatedData.asBytes[0] = (uint8) byte1;
data[1] = (uint8) byte2; preallocatedData.asBytes[1] = (uint8) byte2;
data[2] = (uint8) byte3; preallocatedData.asBytes[2] = (uint8) byte3;
// check that the length matches the data.. // check that the length matches the data..
jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 3); jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 3);
@ -146,14 +163,14 @@ MidiMessage::MidiMessage (const MidiMessage& other)
: timeStamp (other.timeStamp), : timeStamp (other.timeStamp),
size (other.size) size (other.size)
{ {
if (other.data != static_cast <const uint8*> (other.preallocatedData.asBytes)) if (other.usesAllocatedData())
{ {
data = new uint8 [size]; data = new uint8 [size];
memcpy (data, other.data, size); memcpy (data, other.data, size);
} }
else else
{ {
data = static_cast<uint8*> (preallocatedData.asBytes); setToUseInternalData();
preallocatedData.asInt32 = other.preallocatedData.asInt32; preallocatedData.asInt32 = other.preallocatedData.asInt32;
} }
} }
@ -162,14 +179,14 @@ MidiMessage::MidiMessage (const MidiMessage& other, const double newTimeStamp)
: timeStamp (newTimeStamp), : timeStamp (newTimeStamp),
size (other.size) size (other.size)
{ {
if (other.data != static_cast <const uint8*> (other.preallocatedData.asBytes)) if (other.usesAllocatedData())
{ {
data = new uint8 [size]; data = new uint8 [size];
memcpy (data, other.data, size); memcpy (data, other.data, size);
} }
else else
{ {
data = static_cast<uint8*> (preallocatedData.asBytes); setToUseInternalData();
preallocatedData.asInt32 = other.preallocatedData.asInt32; preallocatedData.asInt32 = other.preallocatedData.asInt32;
} }
} }
@ -268,17 +285,16 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other)
timeStamp = other.timeStamp; timeStamp = other.timeStamp;
size = other.size; size = other.size;
if (data != static_cast <const uint8*> (preallocatedData.asBytes)) freeData();
delete[] data;
if (other.data != static_cast <const uint8*> (other.preallocatedData.asBytes)) if (other.usesAllocatedData())
{ {
data = new uint8 [size]; data = new uint8 [size];
memcpy (data, other.data, size); memcpy (data, other.data, size);
} }
else else
{ {
data = static_cast<uint8*> (preallocatedData.asBytes); setToUseInternalData();
preallocatedData.asInt32 = other.preallocatedData.asInt32; preallocatedData.asInt32 = other.preallocatedData.asInt32;
} }
} }
@ -286,10 +302,51 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
MidiMessage::MidiMessage (MidiMessage&& other) noexcept
: timeStamp (other.timeStamp),
size (other.size)
{
if (other.usesAllocatedData())
{
data = other.data;
other.setToUseInternalData();
}
else
{
setToUseInternalData();
preallocatedData.asInt32 = other.preallocatedData.asInt32;
}
}
MidiMessage& MidiMessage::operator= (MidiMessage&& other) noexcept
{
if (this != &other)
{
timeStamp = other.timeStamp;
size = other.size;
freeData();
if (other.usesAllocatedData())
{
data = other.data;
other.setToUseInternalData();
}
else
{
setToUseInternalData();
preallocatedData.asInt32 = other.preallocatedData.asInt32;
}
}
return *this;
}
#endif
MidiMessage::~MidiMessage() MidiMessage::~MidiMessage()
{ {
if (data != static_cast <const uint8*> (preallocatedData.asBytes)) freeData();
delete[] data;
} }
int MidiMessage::getChannel() const noexcept int MidiMessage::getChannel() const noexcept

View file

@ -106,6 +106,11 @@ public:
/** Copies this message from another one. */ /** Copies this message from another one. */
MidiMessage& operator= (const MidiMessage& other); MidiMessage& operator= (const MidiMessage& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
MidiMessage (MidiMessage&& other) noexcept;
MidiMessage& operator= (MidiMessage&& other) noexcept;
#endif
//============================================================================== //==============================================================================
/** Returns a pointer to the raw midi data. /** Returns a pointer to the raw midi data.
@ -926,6 +931,10 @@ private:
uint32 asInt32; uint32 asInt32;
} preallocatedData; } preallocatedData;
#endif #endif
void freeData() noexcept;
void setToUseInternalData() noexcept;
bool usesAllocatedData() const noexcept;
}; };
#endif // __JUCE_MIDIMESSAGE_JUCEHEADER__ #endif // __JUCE_MIDIMESSAGE_JUCEHEADER__

View file

@ -83,6 +83,14 @@ public:
new (data.elements + i) ElementType (other.data.elements[i]); new (data.elements + i) ElementType (other.data.elements[i]);
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Array (Array<ElementType, TypeOfCriticalSectionToUse>&& other) noexcept
: data (static_cast <ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&&> (other.data)),
numUsed (other.numUsed)
{
}
#endif
/** Initalises from a null-terminated C array of values. /** Initalises from a null-terminated C array of values.
@param values the array to copy from @param values the array to copy from
@ -113,8 +121,7 @@ public:
/** Destructor. */ /** Destructor. */
~Array() ~Array()
{ {
for (int i = 0; i < numUsed; ++i) deleteAllElements();
data.elements[i].~ElementType();
} }
/** Copies another array. /** Copies another array.
@ -131,6 +138,21 @@ public:
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Array& operator= (Array&& other) noexcept
{
if (this != &other)
{
deleteAllElements();
data = static_cast <ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&&> (other.data);
numUsed = other.numUsed;
}
return *this;
}
#endif
//============================================================================== //==============================================================================
/** Compares this array to another one. /** Compares this array to another one.
Two arrays are considered equal if they both contain the same set of Two arrays are considered equal if they both contain the same set of
@ -175,10 +197,7 @@ public:
void clear() void clear()
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
deleteAllElements();
for (int i = 0; i < numUsed; ++i)
data.elements[i].~ElementType();
data.setAllocatedSize (0); data.setAllocatedSize (0);
numUsed = 0; numUsed = 0;
} }
@ -190,10 +209,7 @@ public:
void clearQuick() void clearQuick()
{ {
const ScopedLockType lock (getLock()); const ScopedLockType lock (getLock());
deleteAllElements();
for (int i = 0; i < numUsed; ++i)
data.elements[i].~ElementType();
numUsed = 0; numUsed = 0;
} }
@ -1011,6 +1027,12 @@ private:
//============================================================================== //==============================================================================
ArrayAllocationBase <ElementType, TypeOfCriticalSectionToUse> data; ArrayAllocationBase <ElementType, TypeOfCriticalSectionToUse> data;
int numUsed; int numUsed;
inline void deleteAllElements()
{
for (int i = 0; i < numUsed; ++i)
data.elements[i].~ElementType();
}
}; };

View file

@ -57,6 +57,21 @@ public:
{ {
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
ArrayAllocationBase (ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&& other) noexcept
: elements (static_cast <HeapBlock <ElementType>&&> (other.elements)),
numAllocated (other.numAllocated)
{
}
ArrayAllocationBase& operator= (ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&& other) noexcept
{
elements = static_cast <HeapBlock <ElementType>&&> (other.elements);
numAllocated = other.numAllocated;
return *this;
}
#endif
//============================================================================== //==============================================================================
/** Changes the amount of storage allocated. /** Changes the amount of storage allocated.

View file

@ -78,6 +78,25 @@ public:
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
LinkedListPointer (LinkedListPointer&& other) noexcept
: item (other.item)
{
other.item = nullptr;
}
LinkedListPointer& operator= (LinkedListPointer&& other) noexcept
{
if (this != &other)
{
item = other.item;
other.item = nullptr;
}
return *this;
}
#endif
//============================================================================== //==============================================================================
/** Returns the item which this pointer points to. */ /** Returns the item which this pointer points to. */
inline operator ObjectType*() const noexcept inline operator ObjectType*() const noexcept

View file

@ -47,6 +47,23 @@ NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (const NamedValu
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValueSet::NamedValue::NamedValue (NamedValue&& other) noexcept
: nextListItem (static_cast <LinkedListPointer<NamedValue>&&> (other.nextListItem)),
name (static_cast <Identifier&&> (other.name)),
value (static_cast <var&&> (other.value))
{
}
NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (NamedValue&& other) noexcept
{
nextListItem = static_cast <LinkedListPointer<NamedValue>&&> (other.nextListItem);
name = static_cast <Identifier&&> (other.name);
value = static_cast <var&&> (other.value);
return *this;
}
#endif
bool NamedValueSet::NamedValue::operator== (const NamedValueSet::NamedValue& other) const noexcept bool NamedValueSet::NamedValue::operator== (const NamedValueSet::NamedValue& other) const noexcept
{ {
return name == other.name && value == other.value; return name == other.name && value == other.value;
@ -69,6 +86,21 @@ NamedValueSet& NamedValueSet::operator= (const NamedValueSet& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValueSet::NamedValueSet (NamedValueSet&& other) noexcept
: values (static_cast <LinkedListPointer<NamedValue>&&> (other.values))
{
}
NamedValueSet& NamedValueSet::operator= (NamedValueSet&& other) noexcept
{
if (this != &other)
values = static_cast <LinkedListPointer<NamedValue>&&> (other.values);
return *this;
}
#endif
NamedValueSet::~NamedValueSet() NamedValueSet::~NamedValueSet()
{ {
clear(); clear();

View file

@ -52,6 +52,11 @@ public:
/** Replaces this set with a copy of another set. */ /** Replaces this set with a copy of another set. */
NamedValueSet& operator= (const NamedValueSet& other); NamedValueSet& operator= (const NamedValueSet& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValueSet (NamedValueSet&& other) noexcept;
NamedValueSet& operator= (NamedValueSet&& other) noexcept;
#endif
/** Destructor. */ /** Destructor. */
~NamedValueSet(); ~NamedValueSet();
@ -128,6 +133,10 @@ private:
NamedValue (const NamedValue&); NamedValue (const NamedValue&);
NamedValue (const Identifier& name, const var& value); NamedValue (const Identifier& name, const var& value);
NamedValue& operator= (const NamedValue&); NamedValue& operator= (const NamedValue&);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValue (NamedValue&&) noexcept;
NamedValue& operator= (NamedValue&&) noexcept;
#endif
bool operator== (const NamedValue& other) const noexcept; bool operator== (const NamedValue& other) const noexcept;
LinkedListPointer<NamedValue> nextListItem; LinkedListPointer<NamedValue> nextListItem;

View file

@ -411,6 +411,28 @@ const var& var::operator= (const Array<var>& v) { var v2 (v); swapWith (v
const var& var::operator= (ReferenceCountedObject* v) { var v2 (v); swapWith (v2); return *this; } const var& var::operator= (ReferenceCountedObject* v) { var v2 (v); swapWith (v2); return *this; }
const var& var::operator= (MethodFunction v) { var v2 (v); swapWith (v2); return *this; } const var& var::operator= (MethodFunction v) { var v2 (v); swapWith (v2); return *this; }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
var::var (var&& other) noexcept
: type (other.type),
value (other.value)
{
other.type = &VariantType_Void::instance;
}
var& var::operator= (var&& other) noexcept
{
if (this != &other)
{
type->cleanUp (value);
type = other.type;
value = other.value;
other.type = &VariantType_Void::instance;
}
return *this;
}
#endif
//============================================================================== //==============================================================================
bool var::equals (const var& other) const noexcept bool var::equals (const var& other) const noexcept
{ {

View file

@ -90,6 +90,11 @@ public:
const var& operator= (ReferenceCountedObject* object); const var& operator= (ReferenceCountedObject* object);
const var& operator= (MethodFunction method); const var& operator= (MethodFunction method);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
var (var&& other) noexcept;
var& operator= (var&& other) noexcept;
#endif
void swapWith (var& other) noexcept; void swapWith (var& other) noexcept;
operator int() const noexcept; operator int() const noexcept;

View file

@ -62,6 +62,19 @@ File& File::operator= (const File& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
File::File (File&& other) noexcept
: fullPath (static_cast <String&&> (other.fullPath))
{
}
File& File::operator= (File&& other) noexcept
{
fullPath = static_cast <String&&> (other.fullPath);
return *this;
}
#endif
const File File::nonexistent; const File File::nonexistent;

View file

@ -95,6 +95,11 @@ public:
/** Copies from another file object. */ /** Copies from another file object. */
File& operator= (const File& otherFile); File& operator= (const File& otherFile);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
File (File&& otherFile) noexcept;
File& operator= (File&& otherFile) noexcept;
#endif
//============================================================================== //==============================================================================
/** This static constant is used for referring to an 'invalid' file. */ /** This static constant is used for referring to an 'invalid' file. */
static const File nonexistent; static const File nonexistent;

View file

@ -78,6 +78,25 @@ BigInteger::BigInteger (const BigInteger& other)
memcpy (values, other.values, sizeof (uint32) * (numValues + 1)); memcpy (values, other.values, sizeof (uint32) * (numValues + 1));
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
BigInteger::BigInteger (BigInteger&& other) noexcept
: values (static_cast <HeapBlock <uint32>&&> (other.values)),
numValues (other.numValues),
highestBit (other.highestBit),
negative (other.negative)
{
}
BigInteger& BigInteger::operator= (BigInteger&& other) noexcept
{
values = static_cast <HeapBlock <uint32>&&> (other.values);
numValues = other.numValues;
highestBit = other.highestBit;
negative = other.negative;
return *this;
}
#endif
BigInteger::~BigInteger() BigInteger::~BigInteger()
{ {
} }
@ -556,7 +575,7 @@ BigInteger& BigInteger::operator&= (const BigInteger& other)
// this operation doesn't take into account negative values.. // this operation doesn't take into account negative values..
jassert (isNegative() == other.isNegative()); jassert (isNegative() == other.isNegative());
size_t n = numValues; int n = (int) numValues;
while (n > other.numValues) while (n > other.numValues)
values[--n] = 0; values[--n] = 0;

View file

@ -71,6 +71,11 @@ public:
/** Creates a copy of another BigInteger. */ /** Creates a copy of another BigInteger. */
BigInteger (const BigInteger& other); BigInteger (const BigInteger& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
BigInteger (BigInteger&& other) noexcept;
BigInteger& operator= (BigInteger&& other) noexcept;
#endif
/** Destructor. */ /** Destructor. */
~BigInteger(); ~BigInteger();

View file

@ -946,6 +946,19 @@ Expression& Expression::operator= (const Expression& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Expression::Expression (Expression&& other) noexcept
: term (static_cast <ReferenceCountedObjectPtr<Term>&&> (other.term))
{
}
Expression& Expression::operator= (Expression&& other) noexcept
{
term = static_cast <ReferenceCountedObjectPtr<Term>&&> (other.term);
return *this;
}
#endif
Expression::Expression (const String& stringToParse) Expression::Expression (const String& stringToParse)
{ {
String::CharPointerType text (stringToParse.getCharPointer()); String::CharPointerType text (stringToParse.getCharPointer());

View file

@ -65,6 +65,11 @@ public:
/** Copies another expression. */ /** Copies another expression. */
Expression& operator= (const Expression& other); Expression& operator= (const Expression& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Expression (Expression&& other) noexcept;
Expression& operator= (Expression&& other) noexcept;
#endif
/** Creates an expression by parsing a string. /** Creates an expression by parsing a string.
If there's a syntax error in the string, this will throw a ParseError exception. If there's a syntax error in the string, this will throw a ParseError exception.
@throws ParseError @throws ParseError

View file

@ -164,8 +164,7 @@ private:
/* /*
The following code is in the header so that the atomics can be inlined where possible... The following code is in the header so that the atomics can be inlined where possible...
*/ */
#if (JUCE_IOS && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 || ! defined (__IPHONE_3_2))) \ #if JUCE_IOS || (JUCE_MAC && (JUCE_PPC || defined (__clang__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)))
|| (JUCE_MAC && (JUCE_PPC || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)))
#define JUCE_ATOMICS_MAC 1 // Older OSX builds using gcc4.1 or earlier #define JUCE_ATOMICS_MAC 1 // Older OSX builds using gcc4.1 or earlier
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5

View file

@ -119,6 +119,20 @@ public:
::free (data); ::free (data);
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
HeapBlock (HeapBlock&& other) noexcept
: data (other.data)
{
other.data = nullptr;
}
HeapBlock& operator= (HeapBlock&& other) noexcept
{
std::swap (data, other.data);
return *this;
}
#endif
//============================================================================== //==============================================================================
/** Returns a raw pointer to the allocated data. /** Returns a raw pointer to the allocated data.
This may be a null pointer if the data hasn't yet been allocated, or if it has been This may be a null pointer if the data hasn't yet been allocated, or if it has been

View file

@ -88,6 +88,22 @@ MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept
: data (static_cast <HeapBlock <char>&&> (other.data)),
size (other.size)
{
}
MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept
{
data = static_cast <HeapBlock <char>&&> (other.data);
size = other.size;
return *this;
}
#endif
//============================================================================== //==============================================================================
bool MemoryBlock::operator== (const MemoryBlock& other) const noexcept bool MemoryBlock::operator== (const MemoryBlock& other) const noexcept
{ {

View file

@ -69,6 +69,11 @@ public:
*/ */
MemoryBlock& operator= (const MemoryBlock& other); MemoryBlock& operator= (const MemoryBlock& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
MemoryBlock (MemoryBlock&& other) noexcept;
MemoryBlock& operator= (MemoryBlock&& other) noexcept;
#endif
//============================================================================== //==============================================================================
/** Compares two memory blocks. /** Compares two memory blocks.

View file

@ -214,19 +214,27 @@ public:
This will increment the object's reference-count (if it is non-null). This will increment the object's reference-count (if it is non-null).
*/ */
inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& other) noexcept inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr& other) noexcept
: referencedObject (other.referencedObject) : referencedObject (other.referencedObject)
{ {
if (referencedObject != nullptr) if (referencedObject != nullptr)
referencedObject->incReferenceCount(); referencedObject->incReferenceCount();
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
inline ReferenceCountedObjectPtr (ReferenceCountedObjectPtr&& other) noexcept
: referencedObject (other.referencedObject)
{
other.referencedObject = nullptr;
}
#endif
/** Changes this pointer to point at a different object. /** Changes this pointer to point at a different object.
The reference count of the old object is decremented, and it might be The reference count of the old object is decremented, and it might be
deleted if it hits zero. The new object's count is incremented. deleted if it hits zero. The new object's count is incremented.
*/ */
ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& operator= (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& other) ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr& other)
{ {
ReferenceCountedObjectClass* const newObject = other.referencedObject; ReferenceCountedObjectClass* const newObject = other.referencedObject;
@ -245,12 +253,28 @@ public:
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectPtr&& other)
{
if (this != &other)
{
if (referencedObject != nullptr)
referencedObject->decReferenceCount();
referencedObject = other.referencedObject;
other.referencedObject = nullptr;
}
return *this;
}
#endif
/** Changes this pointer to point at a different object. /** Changes this pointer to point at a different object.
The reference count of the old object is decremented, and it might be The reference count of the old object is decremented, and it might be
deleted if it hits zero. The new object's count is incremented. deleted if it hits zero. The new object's count is incremented.
*/ */
ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& operator= (ReferenceCountedObjectClass* const newObject) ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject)
{ {
if (referencedObject != newObject) if (referencedObject != newObject)
{ {

View file

@ -96,6 +96,11 @@ public:
/** Copies another pointer to this one. */ /** Copies another pointer to this one. */
WeakReference& operator= (ObjectType* const newObject) { holder = getRef (newObject); return *this; } WeakReference& operator= (ObjectType* const newObject) { holder = getRef (newObject); return *this; }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
WeakReference (WeakReference&& other) noexcept : holder (static_cast <SharedRef&&> (other.holder)) {}
WeakReference& operator= (WeakReference&& other) noexcept { holder = static_cast <SharedRef&&> (other.holder); return *this; }
#endif
/** Returns the object that this pointer refers to, or null if the object no longer exists. */ /** Returns the object that this pointer refers to, or null if the object no longer exists. */
ObjectType* get() const noexcept { return holder != nullptr ? holder->get() : nullptr; } ObjectType* get() const noexcept { return holder != nullptr ? holder->get() : nullptr; }

View file

@ -42,6 +42,19 @@ Result& Result::operator= (const Result& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Result::Result (Result&& other) noexcept
: errorMessage (static_cast <String&&> (other.errorMessage))
{
}
Result& Result::operator= (Result&& other) noexcept
{
errorMessage = static_cast <String&&> (other.errorMessage);
return *this;
}
#endif
bool Result::operator== (const Result& other) const noexcept bool Result::operator== (const Result& other) const noexcept
{ {
return errorMessage == other.errorMessage; return errorMessage == other.errorMessage;

View file

@ -99,6 +99,11 @@ public:
Result (const Result& other); Result (const Result& other);
Result& operator= (const Result& other); Result& operator= (const Result& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Result (Result&& other) noexcept;
Result& operator= (Result&& other) noexcept;
#endif
bool operator== (const Result& other) const noexcept; bool operator== (const Result& other) const noexcept;
bool operator!= (const Result& other) const noexcept; bool operator!= (const Result& other) const noexcept;

View file

@ -274,16 +274,22 @@
// a few workarounds, so that we can still use a few of the newer language features. // a few workarounds, so that we can still use a few of the newer language features.
#if defined (__GXX_EXPERIMENTAL_CXX0X__) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) #if defined (__GXX_EXPERIMENTAL_CXX0X__) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JUCE_COMPILER_SUPPORTS_CXX2011 1 #define JUCE_COMPILER_SUPPORTS_CXX2011 1
#define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
#endif #endif
#if defined (__clang__) && defined (__has_feature) #if defined (__clang__) && defined (__has_feature)
#if __has_feature (cxx_noexcept) // (NB: do not add this test to the previous line) #if __has_feature (cxx_noexcept) // (NB: do not add this test to the previous line)
#define JUCE_COMPILER_SUPPORTS_CXX2011 1 #define JUCE_COMPILER_SUPPORTS_CXX2011 1
#endif #endif
#if __has_feature (cxx_rvalue_references)
#define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
#endif
#endif #endif
#if defined (_MSC_VER) && _MSC_VER >= 1600 #if defined (_MSC_VER) && _MSC_VER >= 1600
//#define JUCE_COMPILER_SUPPORTS_CXX2011 1 //#define JUCE_COMPILER_SUPPORTS_CXX2011 1
//#define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
#endif #endif
#if ! (DOXYGEN || JUCE_COMPILER_SUPPORTS_CXX2011) #if ! (DOXYGEN || JUCE_COMPILER_SUPPORTS_CXX2011)

View file

@ -263,6 +263,20 @@ String& String::operator= (const String& other) noexcept
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
String::String (String&& other) noexcept
: text (other.text)
{
other.text = StringHolder::getEmpty();
}
String& String::operator= (String&& other) noexcept
{
std::swap (text, other.text);
return *this;
}
#endif
inline String::PreallocationBytes::PreallocationBytes (const size_t numBytes_) : numBytes (numBytes_) {} inline String::PreallocationBytes::PreallocationBytes (const size_t numBytes_) : numBytes (numBytes_) {}
String::String (const PreallocationBytes& preallocationSize) String::String (const PreallocationBytes& preallocationSize)

View file

@ -71,6 +71,10 @@ public:
/** Creates a copy of another string. */ /** Creates a copy of another string. */
String (const String& other) noexcept; String (const String& other) noexcept;
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
String (String&& other) noexcept;
#endif
/** Creates a string from a zero-terminated ascii text string. /** Creates a string from a zero-terminated ascii text string.
The string passed-in must not contain any characters with a value above 127, because The string passed-in must not contain any characters with a value above 127, because
@ -201,6 +205,10 @@ public:
/** Replaces this string's contents with another string. */ /** Replaces this string's contents with another string. */
String& operator= (const String& other) noexcept; String& operator= (const String& other) noexcept;
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
String& operator= (String&& other) noexcept;
#endif
/** Appends another string at the end of this one. */ /** Appends another string at the end of this one. */
String& operator+= (const String& stringToAppend); String& operator+= (const String& stringToAppend);
/** Appends another string at the end of this one. */ /** Appends another string at the end of this one. */

View file

@ -35,6 +35,13 @@ StringArray::StringArray (const StringArray& other)
{ {
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
StringArray::StringArray (StringArray&& other) noexcept
: strings (static_cast <Array <String>&&> (other.strings))
{
}
#endif
StringArray::StringArray (const String& firstValue) StringArray::StringArray (const String& firstValue)
{ {
strings.add (firstValue); strings.add (firstValue);
@ -84,6 +91,14 @@ StringArray& StringArray::operator= (const StringArray& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
StringArray& StringArray::operator= (StringArray&& other) noexcept
{
strings = static_cast <Array<String>&&> (other.strings);
return *this;
}
#endif
StringArray::~StringArray() StringArray::~StringArray()
{ {
} }

View file

@ -46,6 +46,10 @@ public:
/** Creates a copy of another string array */ /** Creates a copy of another string array */
StringArray (const StringArray& other); StringArray (const StringArray& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
StringArray (StringArray&& other) noexcept;
#endif
/** Creates an array containing a single string. */ /** Creates an array containing a single string. */
explicit StringArray (const String& firstValue); explicit StringArray (const String& firstValue);
@ -82,6 +86,10 @@ public:
/** Copies the contents of another string array into this one */ /** Copies the contents of another string array into this one */
StringArray& operator= (const StringArray& other); StringArray& operator= (const StringArray& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
StringArray& operator= (StringArray&& other) noexcept;
#endif
//============================================================================== //==============================================================================
/** Compares two arrays. /** Compares two arrays.
Comparisons are case-sensitive. Comparisons are case-sensitive.

View file

@ -84,6 +84,32 @@ XmlElement& XmlElement::operator= (const XmlElement& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
XmlElement::XmlElement (XmlElement&& other) noexcept
: nextListItem (static_cast <LinkedListPointer <XmlElement>&&> (other.nextListItem)),
firstChildElement (static_cast <LinkedListPointer <XmlElement>&&> (other.firstChildElement)),
attributes (static_cast <LinkedListPointer <XmlAttributeNode>&&> (other.attributes)),
tagName (static_cast <String&&> (other.tagName))
{
}
XmlElement& XmlElement::operator= (XmlElement&& other) noexcept
{
if (this != &other)
{
removeAllAttributes();
deleteAllChildElements();
nextListItem = static_cast <LinkedListPointer <XmlElement>&&> (other.nextListItem);
firstChildElement = static_cast <LinkedListPointer <XmlElement>&&> (other.firstChildElement);
attributes = static_cast <LinkedListPointer <XmlAttributeNode>&&> (other.attributes);
tagName = static_cast <String&&> (other.tagName);
}
return *this;
}
#endif
void XmlElement::copyChildrenAndAttributesFrom (const XmlElement& other) void XmlElement::copyChildrenAndAttributesFrom (const XmlElement& other)
{ {
jassert (firstChildElement.get() == nullptr); jassert (firstChildElement.get() == nullptr);

View file

@ -154,6 +154,11 @@ public:
/** Creates a (deep) copy of another element. */ /** Creates a (deep) copy of another element. */
XmlElement& operator= (const XmlElement& other); XmlElement& operator= (const XmlElement& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
XmlElement (XmlElement&& other) noexcept;
XmlElement& operator= (XmlElement&& other) noexcept;
#endif
/** Deleting an XmlElement will also delete all its child elements. */ /** Deleting an XmlElement will also delete all its child elements. */
~XmlElement() noexcept; ~XmlElement() noexcept;

View file

@ -122,6 +122,19 @@ Value& Value::operator= (const Value& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Value::Value (Value&& other) noexcept
: value (static_cast <ReferenceCountedObjectPtr <ValueSource>&&> (other.value))
{
}
Value& Value::operator= (Value&& other) noexcept
{
value = static_cast <ReferenceCountedObjectPtr <ValueSource>&&> (other.value);
return *this;
}
#endif
Value::~Value() Value::~Value()
{ {
if (listeners.size() > 0) if (listeners.size() > 0)

View file

@ -60,6 +60,11 @@ public:
/** Creates a Value that is set to the specified value. */ /** Creates a Value that is set to the specified value. */
explicit Value (const var& initialValue); explicit Value (const var& initialValue);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Value (Value&& other) noexcept;
Value& operator= (Value&& other) noexcept;
#endif
/** Destructor. */ /** Destructor. */
~Value(); ~Value();

View file

@ -605,6 +605,19 @@ ValueTree& ValueTree::operator= (const ValueTree& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
ValueTree::ValueTree (ValueTree&& other) noexcept
: object (static_cast <SharedObjectPtr&&> (other.object))
{
}
ValueTree& ValueTree::operator= (ValueTree&& other) noexcept
{
object = static_cast <SharedObjectPtr&&> (other.object);
return *this;
}
#endif
ValueTree::~ValueTree() ValueTree::~ValueTree()
{ {
if (listeners.size() > 0 && object != nullptr) if (listeners.size() > 0 && object != nullptr)

View file

@ -91,6 +91,11 @@ public:
/** Makes this object reference another node. */ /** Makes this object reference another node. */
ValueTree& operator= (const ValueTree& other); ValueTree& operator= (const ValueTree& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
ValueTree (ValueTree&& other) noexcept;
ValueTree& operator= (ValueTree&& other) noexcept;
#endif
/** Destructor. */ /** Destructor. */
~ValueTree(); ~ValueTree();

View file

@ -48,8 +48,9 @@ FillType::FillType (const Image& image_, const AffineTransform& transform_) noex
FillType::FillType (const FillType& other) FillType::FillType (const FillType& other)
: colour (other.colour), : colour (other.colour),
gradient (other.gradient != nullptr ? new ColourGradient (*other.gradient) : 0), gradient (other.gradient != nullptr ? new ColourGradient (*other.gradient) : nullptr),
image (other.image), transform (other.transform) image (other.image),
transform (other.transform)
{ {
} }
@ -58,7 +59,7 @@ FillType& FillType::operator= (const FillType& other)
if (this != &other) if (this != &other)
{ {
colour = other.colour; colour = other.colour;
gradient = (other.gradient != nullptr ? new ColourGradient (*other.gradient) : 0); gradient = (other.gradient != nullptr ? new ColourGradient (*other.gradient) : nullptr);
image = other.image; image = other.image;
transform = other.transform; transform = other.transform;
} }
@ -66,6 +67,29 @@ FillType& FillType::operator= (const FillType& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
FillType::FillType (FillType&& other) noexcept
: colour (other.colour),
gradient (other.gradient.release()),
image (static_cast <Image&&> (other.image)),
transform (other.transform)
{
}
FillType& FillType::operator= (FillType&& other) noexcept
{
if (this != &other)
{
colour = other.colour;
gradient = other.gradient.release();
image = static_cast <Image&&> (other.image);
transform = other.transform;
}
return *this;
}
#endif
FillType::~FillType() noexcept FillType::~FillType() noexcept
{ {
} }

View file

@ -68,6 +68,11 @@ public:
/** Makes a copy of another FillType. */ /** Makes a copy of another FillType. */
FillType& operator= (const FillType& other); FillType& operator= (const FillType& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
FillType (FillType&& other) noexcept;
FillType& operator= (FillType&& other) noexcept;
#endif
/** Destructor. */ /** Destructor. */
~FillType() noexcept; ~FillType() noexcept;

View file

@ -237,6 +237,19 @@ Font& Font::operator= (const Font& other) noexcept
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Font::Font (Font&& other) noexcept
: font (static_cast <ReferenceCountedObjectPtr <SharedFontInternal>&&> (other.font))
{
}
Font& Font::operator= (Font&& other) noexcept
{
font = static_cast <ReferenceCountedObjectPtr <SharedFontInternal>&&> (other.font);
return *this;
}
#endif
Font::~Font() noexcept Font::~Font() noexcept
{ {
} }

View file

@ -91,6 +91,11 @@ public:
*/ */
Font(); Font();
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Font (Font&& other) noexcept;
Font& operator= (Font&& other) noexcept;
#endif
/** Copies this font from another one. */ /** Copies this font from another one. */
Font& operator= (const Font& other) noexcept; Font& operator= (const Font& other) noexcept;

View file

@ -114,6 +114,31 @@ Path& Path::operator= (const Path& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Path::Path (Path&& other) noexcept
: data (static_cast <ArrayAllocationBase <float, DummyCriticalSection>&&> (other.data)),
numElements (other.numElements),
pathXMin (other.pathXMin),
pathXMax (other.pathXMax),
pathYMin (other.pathYMin),
pathYMax (other.pathYMax),
useNonZeroWinding (other.useNonZeroWinding)
{
}
Path& Path::operator= (Path&& other) noexcept
{
data = static_cast <ArrayAllocationBase <float, DummyCriticalSection>&&> (other.data);
numElements = other.numElements;
pathXMin = other.pathXMin;
pathXMax = other.pathXMax;
pathYMin = other.pathYMin;
pathYMax = other.pathYMax;
useNonZeroWinding = other.useNonZeroWinding;
return *this;
}
#endif
bool Path::operator== (const Path& other) const noexcept bool Path::operator== (const Path& other) const noexcept
{ {
return ! operator!= (other); return ! operator!= (other);

View file

@ -84,6 +84,11 @@ public:
/** Copies this path from another one. */ /** Copies this path from another one. */
Path& operator= (const Path& other); Path& operator= (const Path& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Path (Path&& other) noexcept;
Path& operator= (Path&& other) noexcept;
#endif
bool operator== (const Path& other) const noexcept; bool operator== (const Path& other) const noexcept;
bool operator!= (const Path& other) const noexcept; bool operator!= (const Path& other) const noexcept;

View file

@ -168,6 +168,19 @@ Image& Image::operator= (const Image& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Image::Image (Image&& other) noexcept
: image (static_cast <ReferenceCountedObjectPtr<SharedImage>&&> (other.image))
{
}
Image& Image::operator= (Image&& other) noexcept
{
image = static_cast <ReferenceCountedObjectPtr<SharedImage>&&> (other.image);
return *this;
}
#endif
Image::~Image() Image::~Image()
{ {
} }

View file

@ -113,6 +113,11 @@ public:
*/ */
Image& operator= (const Image&); Image& operator= (const Image&);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Image (Image&& other) noexcept;
Image& operator= (Image&&) noexcept;
#endif
/** Destructor. */ /** Destructor. */
~Image(); ~Image();

View file

@ -1169,7 +1169,7 @@ PopupMenu::PopupMenu()
PopupMenu::PopupMenu (const PopupMenu& other) PopupMenu::PopupMenu (const PopupMenu& other)
: lookAndFeel (other.lookAndFeel), : lookAndFeel (other.lookAndFeel),
separatorPending (false) separatorPending (other.separatorPending)
{ {
items.addCopiesOf (other.items); items.addCopiesOf (other.items);
} }
@ -1187,6 +1187,28 @@ PopupMenu& PopupMenu::operator= (const PopupMenu& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
PopupMenu::PopupMenu (PopupMenu&& other) noexcept
: lookAndFeel (other.lookAndFeel),
separatorPending (other.separatorPending)
{
items.swapWithArray (other.items);
}
PopupMenu& PopupMenu::operator= (PopupMenu&& other) noexcept
{
if (this != &other)
{
items.swapWithArray (other.items);
lookAndFeel = other.lookAndFeel;
separatorPending = other.separatorPending;
}
return *this;
}
#endif
PopupMenu::~PopupMenu() PopupMenu::~PopupMenu()
{ {
clear(); clear();

View file

@ -91,6 +91,11 @@ public:
/** Copies this menu from another one. */ /** Copies this menu from another one. */
PopupMenu& operator= (const PopupMenu& other); PopupMenu& operator= (const PopupMenu& other);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
PopupMenu (PopupMenu&& other) noexcept;
PopupMenu& operator= (PopupMenu&& other) noexcept;
#endif
//============================================================================== //==============================================================================
/** Resets the menu, removing all its items. */ /** Resets the menu, removing all its items. */
void clear(); void clear();

View file

@ -148,6 +148,20 @@ MouseCursor& MouseCursor::operator= (const MouseCursor& other)
return *this; return *this;
} }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
MouseCursor::MouseCursor (MouseCursor&& other) noexcept
: cursorHandle (other.cursorHandle)
{
other.cursorHandle = nullptr;
}
MouseCursor& MouseCursor::operator= (MouseCursor&& other) noexcept
{
std::swap (cursorHandle, other.cursorHandle);
return *this;
}
#endif
bool MouseCursor::operator== (const MouseCursor& other) const noexcept bool MouseCursor::operator== (const MouseCursor& other) const noexcept
{ {
return getHandle() == other.getHandle(); return getHandle() == other.getHandle();

View file

@ -99,6 +99,11 @@ public:
/** Destructor. */ /** Destructor. */
~MouseCursor(); ~MouseCursor();
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
MouseCursor (MouseCursor&& other) noexcept;
MouseCursor& operator= (MouseCursor&& other) noexcept;
#endif
/** Checks whether two mouse cursors are the same. /** Checks whether two mouse cursors are the same.
For custom cursors, two cursors created from the same image won't be For custom cursors, two cursors created from the same image won't be