diff --git a/modules/juce_audio_basics/midi/juce_MidiMessage.cpp b/modules/juce_audio_basics/midi/juce_MidiMessage.cpp index 19b5bb8780..e1dea01729 100644 --- a/modules/juce_audio_basics/midi/juce_MidiMessage.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiMessage.cpp @@ -79,14 +79,31 @@ int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) noexcept return messageLengths [firstByte & 0x7f]; } +//============================================================================== +inline void MidiMessage::setToUseInternalData() noexcept +{ + data = static_cast (preallocatedData.asBytes); +} + +inline bool MidiMessage::usesAllocatedData() const noexcept +{ + return data != static_cast (preallocatedData.asBytes); +} + +inline void MidiMessage::freeData() noexcept +{ + if (usesAllocatedData()) + delete[] data; +} + //============================================================================== MidiMessage::MidiMessage() noexcept : timeStamp (0), data (static_cast (preallocatedData.asBytes)), size (2) { - data[0] = 0xf0; - data[1] = 0xf7; + preallocatedData.asBytes[0] = 0xf0; + preallocatedData.asBytes[1] = 0xf7; } 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); if (dataSize <= 4) - data = static_cast (preallocatedData.asBytes); + setToUseInternalData(); else data = new uint8 [dataSize]; @@ -111,7 +128,7 @@ MidiMessage::MidiMessage (const int byte1, const double t) noexcept data (static_cast (preallocatedData.asBytes)), size (1) { - data[0] = (uint8) byte1; + preallocatedData.asBytes[0] = (uint8) byte1; // check that the length matches the data.. 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 (preallocatedData.asBytes)), size (2) { - data[0] = (uint8) byte1; - data[1] = (uint8) byte2; + preallocatedData.asBytes[0] = (uint8) byte1; + preallocatedData.asBytes[1] = (uint8) byte2; // check that the length matches the data.. 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 (preallocatedData.asBytes)), size (3) { - data[0] = (uint8) byte1; - data[1] = (uint8) byte2; - data[2] = (uint8) byte3; + preallocatedData.asBytes[0] = (uint8) byte1; + preallocatedData.asBytes[1] = (uint8) byte2; + preallocatedData.asBytes[2] = (uint8) byte3; // check that the length matches the data.. jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 3); @@ -146,14 +163,14 @@ MidiMessage::MidiMessage (const MidiMessage& other) : timeStamp (other.timeStamp), size (other.size) { - if (other.data != static_cast (other.preallocatedData.asBytes)) + if (other.usesAllocatedData()) { data = new uint8 [size]; memcpy (data, other.data, size); } else { - data = static_cast (preallocatedData.asBytes); + setToUseInternalData(); preallocatedData.asInt32 = other.preallocatedData.asInt32; } } @@ -162,14 +179,14 @@ MidiMessage::MidiMessage (const MidiMessage& other, const double newTimeStamp) : timeStamp (newTimeStamp), size (other.size) { - if (other.data != static_cast (other.preallocatedData.asBytes)) + if (other.usesAllocatedData()) { data = new uint8 [size]; memcpy (data, other.data, size); } else { - data = static_cast (preallocatedData.asBytes); + setToUseInternalData(); preallocatedData.asInt32 = other.preallocatedData.asInt32; } } @@ -268,17 +285,16 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other) timeStamp = other.timeStamp; size = other.size; - if (data != static_cast (preallocatedData.asBytes)) - delete[] data; + freeData(); - if (other.data != static_cast (other.preallocatedData.asBytes)) + if (other.usesAllocatedData()) { data = new uint8 [size]; memcpy (data, other.data, size); } else { - data = static_cast (preallocatedData.asBytes); + setToUseInternalData(); preallocatedData.asInt32 = other.preallocatedData.asInt32; } } @@ -286,10 +302,51 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other) 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() { - if (data != static_cast (preallocatedData.asBytes)) - delete[] data; + freeData(); } int MidiMessage::getChannel() const noexcept diff --git a/modules/juce_audio_basics/midi/juce_MidiMessage.h b/modules/juce_audio_basics/midi/juce_MidiMessage.h index de43cc0db3..7813f6fb1f 100644 --- a/modules/juce_audio_basics/midi/juce_MidiMessage.h +++ b/modules/juce_audio_basics/midi/juce_MidiMessage.h @@ -106,6 +106,11 @@ public: /** Copies this message from another one. */ 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. @@ -926,6 +931,10 @@ private: uint32 asInt32; } preallocatedData; #endif + + void freeData() noexcept; + void setToUseInternalData() noexcept; + bool usesAllocatedData() const noexcept; }; #endif // __JUCE_MIDIMESSAGE_JUCEHEADER__ diff --git a/modules/juce_core/containers/juce_Array.h b/modules/juce_core/containers/juce_Array.h index 5da6d47bb0..c23ccca4b8 100644 --- a/modules/juce_core/containers/juce_Array.h +++ b/modules/juce_core/containers/juce_Array.h @@ -83,6 +83,14 @@ public: new (data.elements + i) ElementType (other.data.elements[i]); } + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + Array (Array&& other) noexcept + : data (static_cast &&> (other.data)), + numUsed (other.numUsed) + { + } + #endif + /** Initalises from a null-terminated C array of values. @param values the array to copy from @@ -113,8 +121,7 @@ public: /** Destructor. */ ~Array() { - for (int i = 0; i < numUsed; ++i) - data.elements[i].~ElementType(); + deleteAllElements(); } /** Copies another array. @@ -131,6 +138,21 @@ public: return *this; } + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + Array& operator= (Array&& other) noexcept + { + if (this != &other) + { + deleteAllElements(); + + data = static_cast &&> (other.data); + numUsed = other.numUsed; + } + + return *this; + } + #endif + //============================================================================== /** Compares this array to another one. Two arrays are considered equal if they both contain the same set of @@ -175,10 +197,7 @@ public: void clear() { const ScopedLockType lock (getLock()); - - for (int i = 0; i < numUsed; ++i) - data.elements[i].~ElementType(); - + deleteAllElements(); data.setAllocatedSize (0); numUsed = 0; } @@ -190,10 +209,7 @@ public: void clearQuick() { const ScopedLockType lock (getLock()); - - for (int i = 0; i < numUsed; ++i) - data.elements[i].~ElementType(); - + deleteAllElements(); numUsed = 0; } @@ -1011,6 +1027,12 @@ private: //============================================================================== ArrayAllocationBase data; int numUsed; + + inline void deleteAllElements() + { + for (int i = 0; i < numUsed; ++i) + data.elements[i].~ElementType(); + } }; diff --git a/modules/juce_core/containers/juce_ArrayAllocationBase.h b/modules/juce_core/containers/juce_ArrayAllocationBase.h index e979b121dd..5e34c03b45 100644 --- a/modules/juce_core/containers/juce_ArrayAllocationBase.h +++ b/modules/juce_core/containers/juce_ArrayAllocationBase.h @@ -57,6 +57,21 @@ public: { } + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + ArrayAllocationBase (ArrayAllocationBase&& other) noexcept + : elements (static_cast &&> (other.elements)), + numAllocated (other.numAllocated) + { + } + + ArrayAllocationBase& operator= (ArrayAllocationBase&& other) noexcept + { + elements = static_cast &&> (other.elements); + numAllocated = other.numAllocated; + return *this; + } + #endif + //============================================================================== /** Changes the amount of storage allocated. diff --git a/modules/juce_core/containers/juce_LinkedListPointer.h b/modules/juce_core/containers/juce_LinkedListPointer.h index 826c8c4adf..19b58a4598 100644 --- a/modules/juce_core/containers/juce_LinkedListPointer.h +++ b/modules/juce_core/containers/juce_LinkedListPointer.h @@ -78,6 +78,25 @@ public: 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. */ inline operator ObjectType*() const noexcept diff --git a/modules/juce_core/containers/juce_NamedValueSet.cpp b/modules/juce_core/containers/juce_NamedValueSet.cpp index 51a6827d31..7e7e611218 100644 --- a/modules/juce_core/containers/juce_NamedValueSet.cpp +++ b/modules/juce_core/containers/juce_NamedValueSet.cpp @@ -47,6 +47,23 @@ NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (const NamedValu return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +NamedValueSet::NamedValue::NamedValue (NamedValue&& other) noexcept + : nextListItem (static_cast &&> (other.nextListItem)), + name (static_cast (other.name)), + value (static_cast (other.value)) +{ +} + +NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (NamedValue&& other) noexcept +{ + nextListItem = static_cast &&> (other.nextListItem); + name = static_cast (other.name); + value = static_cast (other.value); + return *this; +} +#endif + bool NamedValueSet::NamedValue::operator== (const NamedValueSet::NamedValue& other) const noexcept { return name == other.name && value == other.value; @@ -69,6 +86,21 @@ NamedValueSet& NamedValueSet::operator= (const NamedValueSet& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +NamedValueSet::NamedValueSet (NamedValueSet&& other) noexcept + : values (static_cast &&> (other.values)) +{ +} + +NamedValueSet& NamedValueSet::operator= (NamedValueSet&& other) noexcept +{ + if (this != &other) + values = static_cast &&> (other.values); + + return *this; +} +#endif + NamedValueSet::~NamedValueSet() { clear(); diff --git a/modules/juce_core/containers/juce_NamedValueSet.h b/modules/juce_core/containers/juce_NamedValueSet.h index f23afd9155..42f8ab849a 100644 --- a/modules/juce_core/containers/juce_NamedValueSet.h +++ b/modules/juce_core/containers/juce_NamedValueSet.h @@ -52,6 +52,11 @@ public: /** Replaces this set with a copy of another set. */ NamedValueSet& operator= (const NamedValueSet& other); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + NamedValueSet (NamedValueSet&& other) noexcept; + NamedValueSet& operator= (NamedValueSet&& other) noexcept; + #endif + /** Destructor. */ ~NamedValueSet(); @@ -128,6 +133,10 @@ private: NamedValue (const NamedValue&); NamedValue (const Identifier& name, const var& value); 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; LinkedListPointer nextListItem; diff --git a/modules/juce_core/containers/juce_Variant.cpp b/modules/juce_core/containers/juce_Variant.cpp index 2181c49447..4487758ee5 100644 --- a/modules/juce_core/containers/juce_Variant.cpp +++ b/modules/juce_core/containers/juce_Variant.cpp @@ -411,6 +411,28 @@ const var& var::operator= (const Array& v) { var v2 (v); swapWith (v 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; } +#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 { diff --git a/modules/juce_core/containers/juce_Variant.h b/modules/juce_core/containers/juce_Variant.h index d173c521ed..d7633e44d2 100644 --- a/modules/juce_core/containers/juce_Variant.h +++ b/modules/juce_core/containers/juce_Variant.h @@ -90,6 +90,11 @@ public: const var& operator= (ReferenceCountedObject* object); 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; operator int() const noexcept; diff --git a/modules/juce_core/files/juce_File.cpp b/modules/juce_core/files/juce_File.cpp index 7daf08129c..362e4acf08 100644 --- a/modules/juce_core/files/juce_File.cpp +++ b/modules/juce_core/files/juce_File.cpp @@ -62,6 +62,19 @@ File& File::operator= (const File& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +File::File (File&& other) noexcept + : fullPath (static_cast (other.fullPath)) +{ +} + +File& File::operator= (File&& other) noexcept +{ + fullPath = static_cast (other.fullPath); + return *this; +} +#endif + const File File::nonexistent; diff --git a/modules/juce_core/files/juce_File.h b/modules/juce_core/files/juce_File.h index b95f059dd6..0ca578ba73 100644 --- a/modules/juce_core/files/juce_File.h +++ b/modules/juce_core/files/juce_File.h @@ -95,6 +95,11 @@ public: /** Copies from another file object. */ 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. */ static const File nonexistent; diff --git a/modules/juce_core/maths/juce_BigInteger.cpp b/modules/juce_core/maths/juce_BigInteger.cpp index 11dc0eaf56..0e5abd7b47 100644 --- a/modules/juce_core/maths/juce_BigInteger.cpp +++ b/modules/juce_core/maths/juce_BigInteger.cpp @@ -78,6 +78,25 @@ BigInteger::BigInteger (const BigInteger& other) memcpy (values, other.values, sizeof (uint32) * (numValues + 1)); } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +BigInteger::BigInteger (BigInteger&& other) noexcept + : values (static_cast &&> (other.values)), + numValues (other.numValues), + highestBit (other.highestBit), + negative (other.negative) +{ +} + +BigInteger& BigInteger::operator= (BigInteger&& other) noexcept +{ + values = static_cast &&> (other.values); + numValues = other.numValues; + highestBit = other.highestBit; + negative = other.negative; + return *this; +} +#endif + BigInteger::~BigInteger() { } @@ -556,7 +575,7 @@ BigInteger& BigInteger::operator&= (const BigInteger& other) // this operation doesn't take into account negative values.. jassert (isNegative() == other.isNegative()); - size_t n = numValues; + int n = (int) numValues; while (n > other.numValues) values[--n] = 0; diff --git a/modules/juce_core/maths/juce_BigInteger.h b/modules/juce_core/maths/juce_BigInteger.h index dff2e286d7..7f88570b6d 100644 --- a/modules/juce_core/maths/juce_BigInteger.h +++ b/modules/juce_core/maths/juce_BigInteger.h @@ -71,6 +71,11 @@ public: /** Creates a copy of another BigInteger. */ BigInteger (const BigInteger& other); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + BigInteger (BigInteger&& other) noexcept; + BigInteger& operator= (BigInteger&& other) noexcept; + #endif + /** Destructor. */ ~BigInteger(); diff --git a/modules/juce_core/maths/juce_Expression.cpp b/modules/juce_core/maths/juce_Expression.cpp index 5f4072d63c..8d9fab04d2 100644 --- a/modules/juce_core/maths/juce_Expression.cpp +++ b/modules/juce_core/maths/juce_Expression.cpp @@ -946,6 +946,19 @@ Expression& Expression::operator= (const Expression& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +Expression::Expression (Expression&& other) noexcept + : term (static_cast &&> (other.term)) +{ +} + +Expression& Expression::operator= (Expression&& other) noexcept +{ + term = static_cast &&> (other.term); + return *this; +} +#endif + Expression::Expression (const String& stringToParse) { String::CharPointerType text (stringToParse.getCharPointer()); diff --git a/modules/juce_core/maths/juce_Expression.h b/modules/juce_core/maths/juce_Expression.h index 7b9043f344..ad1b1c6abc 100644 --- a/modules/juce_core/maths/juce_Expression.h +++ b/modules/juce_core/maths/juce_Expression.h @@ -65,6 +65,11 @@ public: /** Copies another expression. */ 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. If there's a syntax error in the string, this will throw a ParseError exception. @throws ParseError diff --git a/modules/juce_core/memory/juce_Atomic.h b/modules/juce_core/memory/juce_Atomic.h index e83a7f3190..4ab5c947b6 100644 --- a/modules/juce_core/memory/juce_Atomic.h +++ b/modules/juce_core/memory/juce_Atomic.h @@ -164,8 +164,7 @@ private: /* 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))) \ - || (JUCE_MAC && (JUCE_PPC || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))) +#if JUCE_IOS || (JUCE_MAC && (JUCE_PPC || defined (__clang__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))) #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 diff --git a/modules/juce_core/memory/juce_HeapBlock.h b/modules/juce_core/memory/juce_HeapBlock.h index c14f49357b..324b9ef2e6 100644 --- a/modules/juce_core/memory/juce_HeapBlock.h +++ b/modules/juce_core/memory/juce_HeapBlock.h @@ -119,6 +119,20 @@ public: ::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. This may be a null pointer if the data hasn't yet been allocated, or if it has been diff --git a/modules/juce_core/memory/juce_MemoryBlock.cpp b/modules/juce_core/memory/juce_MemoryBlock.cpp index 707998dd45..3edc217f10 100644 --- a/modules/juce_core/memory/juce_MemoryBlock.cpp +++ b/modules/juce_core/memory/juce_MemoryBlock.cpp @@ -88,6 +88,22 @@ MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept + : data (static_cast &&> (other.data)), + size (other.size) +{ +} + +MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept +{ + data = static_cast &&> (other.data); + size = other.size; + return *this; +} +#endif + + //============================================================================== bool MemoryBlock::operator== (const MemoryBlock& other) const noexcept { diff --git a/modules/juce_core/memory/juce_MemoryBlock.h b/modules/juce_core/memory/juce_MemoryBlock.h index 660757a7ee..8db4b5e483 100644 --- a/modules/juce_core/memory/juce_MemoryBlock.h +++ b/modules/juce_core/memory/juce_MemoryBlock.h @@ -69,6 +69,11 @@ public: */ 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. diff --git a/modules/juce_core/memory/juce_ReferenceCountedObject.h b/modules/juce_core/memory/juce_ReferenceCountedObject.h index e4f2f03e9f..faabcdb9d6 100644 --- a/modules/juce_core/memory/juce_ReferenceCountedObject.h +++ b/modules/juce_core/memory/juce_ReferenceCountedObject.h @@ -214,19 +214,27 @@ public: This will increment the object's reference-count (if it is non-null). */ - inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr& other) noexcept + inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr& other) noexcept : referencedObject (other.referencedObject) { if (referencedObject != nullptr) 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. 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. */ - ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr& other) + ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr& other) { ReferenceCountedObjectClass* const newObject = other.referencedObject; @@ -245,12 +253,28 @@ public: 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. 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. */ - ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject) + ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject) { if (referencedObject != newObject) { diff --git a/modules/juce_core/memory/juce_WeakReference.h b/modules/juce_core/memory/juce_WeakReference.h index 5057ed7f1b..030e641bfb 100644 --- a/modules/juce_core/memory/juce_WeakReference.h +++ b/modules/juce_core/memory/juce_WeakReference.h @@ -96,6 +96,11 @@ public: /** Copies another pointer to this one. */ WeakReference& operator= (ObjectType* const newObject) { holder = getRef (newObject); return *this; } + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + WeakReference (WeakReference&& other) noexcept : holder (static_cast (other.holder)) {} + WeakReference& operator= (WeakReference&& other) noexcept { holder = static_cast (other.holder); return *this; } + #endif + /** 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; } diff --git a/modules/juce_core/misc/juce_Result.cpp b/modules/juce_core/misc/juce_Result.cpp index bfeec68d02..f92da69da2 100644 --- a/modules/juce_core/misc/juce_Result.cpp +++ b/modules/juce_core/misc/juce_Result.cpp @@ -42,6 +42,19 @@ Result& Result::operator= (const Result& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +Result::Result (Result&& other) noexcept + : errorMessage (static_cast (other.errorMessage)) +{ +} + +Result& Result::operator= (Result&& other) noexcept +{ + errorMessage = static_cast (other.errorMessage); + return *this; +} +#endif + bool Result::operator== (const Result& other) const noexcept { return errorMessage == other.errorMessage; diff --git a/modules/juce_core/misc/juce_Result.h b/modules/juce_core/misc/juce_Result.h index 70e68f7ea7..107244ddd9 100644 --- a/modules/juce_core/misc/juce_Result.h +++ b/modules/juce_core/misc/juce_Result.h @@ -99,6 +99,11 @@ public: Result (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; diff --git a/modules/juce_core/system/juce_PlatformDefs.h b/modules/juce_core/system/juce_PlatformDefs.h index 175daa6f94..b9b5c88b2d 100644 --- a/modules/juce_core/system/juce_PlatformDefs.h +++ b/modules/juce_core/system/juce_PlatformDefs.h @@ -274,16 +274,22 @@ // 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)) #define JUCE_COMPILER_SUPPORTS_CXX2011 1 + #define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 #endif #if defined (__clang__) && defined (__has_feature) #if __has_feature (cxx_noexcept) // (NB: do not add this test to the previous line) #define JUCE_COMPILER_SUPPORTS_CXX2011 1 #endif + + #if __has_feature (cxx_rvalue_references) + #define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 + #endif #endif #if defined (_MSC_VER) && _MSC_VER >= 1600 //#define JUCE_COMPILER_SUPPORTS_CXX2011 1 + //#define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 #endif #if ! (DOXYGEN || JUCE_COMPILER_SUPPORTS_CXX2011) diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index 5204ae3fb3..34f00ceae2 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -263,6 +263,20 @@ String& String::operator= (const String& other) noexcept 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_) {} String::String (const PreallocationBytes& preallocationSize) diff --git a/modules/juce_core/text/juce_String.h b/modules/juce_core/text/juce_String.h index 5980dedb82..7153b5fce7 100644 --- a/modules/juce_core/text/juce_String.h +++ b/modules/juce_core/text/juce_String.h @@ -71,6 +71,10 @@ public: /** Creates a copy of another string. */ 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. 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. */ 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. */ String& operator+= (const String& stringToAppend); /** Appends another string at the end of this one. */ diff --git a/modules/juce_core/text/juce_StringArray.cpp b/modules/juce_core/text/juce_StringArray.cpp index f1f0dfb9a5..b522329317 100644 --- a/modules/juce_core/text/juce_StringArray.cpp +++ b/modules/juce_core/text/juce_StringArray.cpp @@ -35,6 +35,13 @@ StringArray::StringArray (const StringArray& other) { } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +StringArray::StringArray (StringArray&& other) noexcept + : strings (static_cast &&> (other.strings)) +{ +} +#endif + StringArray::StringArray (const String& firstValue) { strings.add (firstValue); @@ -84,6 +91,14 @@ StringArray& StringArray::operator= (const StringArray& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +StringArray& StringArray::operator= (StringArray&& other) noexcept +{ + strings = static_cast &&> (other.strings); + return *this; +} +#endif + StringArray::~StringArray() { } diff --git a/modules/juce_core/text/juce_StringArray.h b/modules/juce_core/text/juce_StringArray.h index 3051696721..6deb6c1f5b 100644 --- a/modules/juce_core/text/juce_StringArray.h +++ b/modules/juce_core/text/juce_StringArray.h @@ -46,6 +46,10 @@ public: /** Creates a copy of another string array */ StringArray (const StringArray& other); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + StringArray (StringArray&& other) noexcept; + #endif + /** Creates an array containing a single string. */ explicit StringArray (const String& firstValue); @@ -82,6 +86,10 @@ public: /** Copies the contents of another string array into this one */ StringArray& operator= (const StringArray& other); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + StringArray& operator= (StringArray&& other) noexcept; + #endif + //============================================================================== /** Compares two arrays. Comparisons are case-sensitive. diff --git a/modules/juce_core/xml/juce_XmlElement.cpp b/modules/juce_core/xml/juce_XmlElement.cpp index 46e8bde217..e6b2980dcf 100644 --- a/modules/juce_core/xml/juce_XmlElement.cpp +++ b/modules/juce_core/xml/juce_XmlElement.cpp @@ -84,6 +84,32 @@ XmlElement& XmlElement::operator= (const XmlElement& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +XmlElement::XmlElement (XmlElement&& other) noexcept + : nextListItem (static_cast &&> (other.nextListItem)), + firstChildElement (static_cast &&> (other.firstChildElement)), + attributes (static_cast &&> (other.attributes)), + tagName (static_cast (other.tagName)) +{ +} + +XmlElement& XmlElement::operator= (XmlElement&& other) noexcept +{ + if (this != &other) + { + removeAllAttributes(); + deleteAllChildElements(); + + nextListItem = static_cast &&> (other.nextListItem); + firstChildElement = static_cast &&> (other.firstChildElement); + attributes = static_cast &&> (other.attributes); + tagName = static_cast (other.tagName); + } + + return *this; +} +#endif + void XmlElement::copyChildrenAndAttributesFrom (const XmlElement& other) { jassert (firstChildElement.get() == nullptr); diff --git a/modules/juce_core/xml/juce_XmlElement.h b/modules/juce_core/xml/juce_XmlElement.h index e2e4b52c9e..0e1e60df06 100644 --- a/modules/juce_core/xml/juce_XmlElement.h +++ b/modules/juce_core/xml/juce_XmlElement.h @@ -154,6 +154,11 @@ public: /** Creates a (deep) copy of another element. */ 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. */ ~XmlElement() noexcept; diff --git a/modules/juce_data_structures/values/juce_Value.cpp b/modules/juce_data_structures/values/juce_Value.cpp index 8e8134c2ee..1125cfe1c2 100644 --- a/modules/juce_data_structures/values/juce_Value.cpp +++ b/modules/juce_data_structures/values/juce_Value.cpp @@ -122,6 +122,19 @@ Value& Value::operator= (const Value& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +Value::Value (Value&& other) noexcept + : value (static_cast &&> (other.value)) +{ +} + +Value& Value::operator= (Value&& other) noexcept +{ + value = static_cast &&> (other.value); + return *this; +} +#endif + Value::~Value() { if (listeners.size() > 0) diff --git a/modules/juce_data_structures/values/juce_Value.h b/modules/juce_data_structures/values/juce_Value.h index 5515429c4c..2ac8a799b6 100644 --- a/modules/juce_data_structures/values/juce_Value.h +++ b/modules/juce_data_structures/values/juce_Value.h @@ -60,6 +60,11 @@ public: /** Creates a Value that is set to the specified value. */ explicit Value (const var& initialValue); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + Value (Value&& other) noexcept; + Value& operator= (Value&& other) noexcept; + #endif + /** Destructor. */ ~Value(); diff --git a/modules/juce_data_structures/values/juce_ValueTree.cpp b/modules/juce_data_structures/values/juce_ValueTree.cpp index e949748fd8..a7ff1e4926 100644 --- a/modules/juce_data_structures/values/juce_ValueTree.cpp +++ b/modules/juce_data_structures/values/juce_ValueTree.cpp @@ -605,6 +605,19 @@ ValueTree& ValueTree::operator= (const ValueTree& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +ValueTree::ValueTree (ValueTree&& other) noexcept + : object (static_cast (other.object)) +{ +} + +ValueTree& ValueTree::operator= (ValueTree&& other) noexcept +{ + object = static_cast (other.object); + return *this; +} +#endif + ValueTree::~ValueTree() { if (listeners.size() > 0 && object != nullptr) diff --git a/modules/juce_data_structures/values/juce_ValueTree.h b/modules/juce_data_structures/values/juce_ValueTree.h index 77a2f3e751..480f06b635 100644 --- a/modules/juce_data_structures/values/juce_ValueTree.h +++ b/modules/juce_data_structures/values/juce_ValueTree.h @@ -91,6 +91,11 @@ public: /** Makes this object reference another node. */ ValueTree& operator= (const ValueTree& other); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + ValueTree (ValueTree&& other) noexcept; + ValueTree& operator= (ValueTree&& other) noexcept; + #endif + /** Destructor. */ ~ValueTree(); diff --git a/modules/juce_graphics/colour/juce_FillType.cpp b/modules/juce_graphics/colour/juce_FillType.cpp index 0cce767103..84c320eee0 100644 --- a/modules/juce_graphics/colour/juce_FillType.cpp +++ b/modules/juce_graphics/colour/juce_FillType.cpp @@ -48,8 +48,9 @@ FillType::FillType (const Image& image_, const AffineTransform& transform_) noex FillType::FillType (const FillType& other) : colour (other.colour), - gradient (other.gradient != nullptr ? new ColourGradient (*other.gradient) : 0), - image (other.image), transform (other.transform) + gradient (other.gradient != nullptr ? new ColourGradient (*other.gradient) : nullptr), + image (other.image), + transform (other.transform) { } @@ -58,7 +59,7 @@ FillType& FillType::operator= (const FillType& other) if (this != &other) { 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; } @@ -66,6 +67,29 @@ FillType& FillType::operator= (const FillType& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +FillType::FillType (FillType&& other) noexcept + : colour (other.colour), + gradient (other.gradient.release()), + image (static_cast (other.image)), + transform (other.transform) +{ +} + +FillType& FillType::operator= (FillType&& other) noexcept +{ + if (this != &other) + { + colour = other.colour; + gradient = other.gradient.release(); + image = static_cast (other.image); + transform = other.transform; + } + + return *this; +} +#endif + FillType::~FillType() noexcept { } diff --git a/modules/juce_graphics/colour/juce_FillType.h b/modules/juce_graphics/colour/juce_FillType.h index eab40ac890..ce8c09d6c9 100644 --- a/modules/juce_graphics/colour/juce_FillType.h +++ b/modules/juce_graphics/colour/juce_FillType.h @@ -68,6 +68,11 @@ public: /** Makes a copy of another FillType. */ FillType& operator= (const FillType& other); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + FillType (FillType&& other) noexcept; + FillType& operator= (FillType&& other) noexcept; + #endif + /** Destructor. */ ~FillType() noexcept; diff --git a/modules/juce_graphics/fonts/juce_Font.cpp b/modules/juce_graphics/fonts/juce_Font.cpp index fb015ba380..7670bf102d 100644 --- a/modules/juce_graphics/fonts/juce_Font.cpp +++ b/modules/juce_graphics/fonts/juce_Font.cpp @@ -237,6 +237,19 @@ Font& Font::operator= (const Font& other) noexcept return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +Font::Font (Font&& other) noexcept + : font (static_cast &&> (other.font)) +{ +} + +Font& Font::operator= (Font&& other) noexcept +{ + font = static_cast &&> (other.font); + return *this; +} +#endif + Font::~Font() noexcept { } diff --git a/modules/juce_graphics/fonts/juce_Font.h b/modules/juce_graphics/fonts/juce_Font.h index 540e6dfe98..1e716ef1db 100644 --- a/modules/juce_graphics/fonts/juce_Font.h +++ b/modules/juce_graphics/fonts/juce_Font.h @@ -91,6 +91,11 @@ public: */ Font(); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + Font (Font&& other) noexcept; + Font& operator= (Font&& other) noexcept; + #endif + /** Copies this font from another one. */ Font& operator= (const Font& other) noexcept; diff --git a/modules/juce_graphics/geometry/juce_Path.cpp b/modules/juce_graphics/geometry/juce_Path.cpp index a071ec7b7c..3c11bc4b4f 100644 --- a/modules/juce_graphics/geometry/juce_Path.cpp +++ b/modules/juce_graphics/geometry/juce_Path.cpp @@ -114,6 +114,31 @@ Path& Path::operator= (const Path& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +Path::Path (Path&& other) noexcept + : data (static_cast &&> (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 &&> (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 { return ! operator!= (other); diff --git a/modules/juce_graphics/geometry/juce_Path.h b/modules/juce_graphics/geometry/juce_Path.h index 788a0b9fb7..644dc99dce 100644 --- a/modules/juce_graphics/geometry/juce_Path.h +++ b/modules/juce_graphics/geometry/juce_Path.h @@ -84,6 +84,11 @@ public: /** Copies this path from another one. */ 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; diff --git a/modules/juce_graphics/images/juce_Image.cpp b/modules/juce_graphics/images/juce_Image.cpp index 6c2fbcd1d7..cb86d1ac85 100644 --- a/modules/juce_graphics/images/juce_Image.cpp +++ b/modules/juce_graphics/images/juce_Image.cpp @@ -168,6 +168,19 @@ Image& Image::operator= (const Image& other) return *this; } +#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS +Image::Image (Image&& other) noexcept + : image (static_cast &&> (other.image)) +{ +} + +Image& Image::operator= (Image&& other) noexcept +{ + image = static_cast &&> (other.image); + return *this; +} +#endif + Image::~Image() { } diff --git a/modules/juce_graphics/images/juce_Image.h b/modules/juce_graphics/images/juce_Image.h index fe9ec2a121..a81254f81b 100644 --- a/modules/juce_graphics/images/juce_Image.h +++ b/modules/juce_graphics/images/juce_Image.h @@ -113,6 +113,11 @@ public: */ Image& operator= (const Image&); + #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + Image (Image&& other) noexcept; + Image& operator= (Image&&) noexcept; + #endif + /** Destructor. */ ~Image(); diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index cd4bc4ec76..054503003e 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -1169,7 +1169,7 @@ PopupMenu::PopupMenu() PopupMenu::PopupMenu (const PopupMenu& other) : lookAndFeel (other.lookAndFeel), - separatorPending (false) + separatorPending (other.separatorPending) { items.addCopiesOf (other.items); } @@ -1187,6 +1187,28 @@ PopupMenu& PopupMenu::operator= (const PopupMenu& other) 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() { clear(); diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.h b/modules/juce_gui_basics/menus/juce_PopupMenu.h index 7f64af5cbb..7c1e953c75 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.h +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.h @@ -91,6 +91,11 @@ public: /** Copies this menu from another one. */ 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. */ void clear(); diff --git a/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp b/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp index 958d1ee040..83839f743d 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp @@ -148,6 +148,20 @@ MouseCursor& MouseCursor::operator= (const MouseCursor& other) 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 { return getHandle() == other.getHandle(); diff --git a/modules/juce_gui_basics/mouse/juce_MouseCursor.h b/modules/juce_gui_basics/mouse/juce_MouseCursor.h index b7a55cb489..f307a95e80 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseCursor.h +++ b/modules/juce_gui_basics/mouse/juce_MouseCursor.h @@ -99,6 +99,11 @@ public: /** Destructor. */ ~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. For custom cursors, two cursors created from the same image won't be