diff --git a/extras/Projucer/Projucer.jucer b/extras/Projucer/Projucer.jucer
index 85a4f844be..103cf4bac2 100644
--- a/extras/Projucer/Projucer.jucer
+++ b/extras/Projucer/Projucer.jucer
@@ -664,8 +664,7 @@
-
+
diff --git a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp
index 88826ef5ca..2f4aee7619 100644
--- a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp
+++ b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp
@@ -383,6 +383,10 @@ private:
if (exporter->canLaunchProject())
defs << " " << exporter->getExporterIdentifierMacro() << "=1";
+ // Use the JUCE implementation of std::function until the live build
+ // engine can compile the one from the standard library
+ defs << " _LIBCPP_FUNCTIONAL=1";
+
return defs;
}
diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp b/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp
index 9385da6ec7..720260de4c 100644
--- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp
+++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp
@@ -168,7 +168,6 @@ void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& desc
(new InvokeOnMessageThread (this, description, initialSampleRate, initialBufferSize, callback))->post();
}
-#if JUCE_COMPILER_SUPPORTS_LAMBDAS
void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description,
double initialSampleRate,
int initialBufferSize,
@@ -190,7 +189,6 @@ void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& desc
createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, new CallbackInvoker (f));
}
-#endif
void AudioPluginFormat::createPluginInstanceOnMessageThread (const PluginDescription& description,
double initialSampleRate,
diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h
index 302faaad01..f820257898 100644
--- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h
+++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h
@@ -92,12 +92,10 @@ public:
int initialBufferSize,
InstantiationCompletionCallback* completionCallback);
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
void createPluginInstanceAsync (const PluginDescription& description,
double initialSampleRate,
int initialBufferSize,
std::function completionCallback);
- #endif
/** Should do a quick check to see if this file or directory might be a plugin of
this format.
diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp
index 9afd881218..d9e5551ce1 100644
--- a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp
+++ b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp
@@ -40,7 +40,6 @@ namespace PluginFormatManagerHelpers
ScopedPointer callback;
};
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
struct ErrorLambdaOnMessageThread : public CallbackMessage
{
ErrorLambdaOnMessageThread (const String& inError,
@@ -54,7 +53,6 @@ namespace PluginFormatManagerHelpers
String error;
std::function lambda;
};
- #endif
}
AudioPluginFormatManager::AudioPluginFormatManager() {}
@@ -139,7 +137,6 @@ void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescriptio
(new PluginFormatManagerHelpers::ErrorCallbackOnMessageThread (error, callback))->post();
}
-#if JUCE_COMPILER_SUPPORTS_LAMBDAS
void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description,
double initialSampleRate,
int initialBufferSize,
@@ -152,7 +149,6 @@ void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescriptio
(new PluginFormatManagerHelpers::ErrorLambdaOnMessageThread (error, f))->post();
}
-#endif
AudioPluginFormat* AudioPluginFormatManager::findFormatForDescription (const PluginDescription& description, String& errorMessage) const
{
diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h
index 431d32ad3e..0be2c06b54 100644
--- a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h
+++ b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h
@@ -114,12 +114,10 @@ public:
int initialBufferSize,
AudioPluginFormat::InstantiationCompletionCallback* callback);
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
void createPluginInstanceAsync (const PluginDescription& description,
double initialSampleRate,
int initialBufferSize,
std::function completionCallback);
- #endif
/** Checks that the file or component for this plugin actually still exists.
diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
index c85252d8f0..c47602b02c 100644
--- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
+++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
@@ -24,8 +24,6 @@
==============================================================================
*/
-#if JUCE_COMPILER_SUPPORTS_LAMBDAS
-
//==============================================================================
struct AudioProcessorValueTreeState::Parameter : public AudioProcessorParameterWithID,
private ValueTree::Listener
@@ -556,5 +554,3 @@ AudioProcessorValueTreeState::ButtonAttachment::ButtonAttachment (AudioProcessor
}
AudioProcessorValueTreeState::ButtonAttachment::~ButtonAttachment() {}
-
-#endif
diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
index 8a851d1b7c..481e821b23 100644
--- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
+++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
@@ -26,8 +26,6 @@
#pragma once
-#if JUCE_COMPILER_SUPPORTS_LAMBDAS
-
/**
This class contains a ValueTree which is used to manage an AudioProcessor's entire state.
@@ -227,5 +225,3 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorValueTreeState)
};
-
-#endif
diff --git a/modules/juce_core/containers/juce_Variant.h b/modules/juce_core/containers/juce_Variant.h
index 24a384d1c3..eeb20f0252 100644
--- a/modules/juce_core/containers/juce_Variant.h
+++ b/modules/juce_core/containers/juce_Variant.h
@@ -52,11 +52,7 @@ public:
int numArguments;
};
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
using NativeFunction = std::function;
- #else
- typedef var (*NativeFunction) (const NativeFunctionArgs&);
- #endif
//==============================================================================
/** Creates a void variant. */
diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp
index d4a94c70fe..6a4fa7547a 100644
--- a/modules/juce_core/juce_core.cpp
+++ b/modules/juce_core/juce_core.cpp
@@ -140,6 +140,7 @@ namespace juce
#include "misc/juce_RuntimePermissions.cpp"
#include "misc/juce_Result.cpp"
#include "misc/juce_Uuid.cpp"
+#include "misc/juce_StdFunctionCompat.cpp"
#include "network/juce_MACAddress.cpp"
#include "network/juce_NamedPipe.cpp"
#include "network/juce_Socket.cpp"
diff --git a/modules/juce_core/maths/juce_NormalisableRange.h b/modules/juce_core/maths/juce_NormalisableRange.h
index 6ea582c9f7..22a41c3c8d 100644
--- a/modules/juce_core/maths/juce_NormalisableRange.h
+++ b/modules/juce_core/maths/juce_NormalisableRange.h
@@ -107,7 +107,6 @@ public:
checkInvariants();
}
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
/** Creates a NormalisableRange with a given range and an injective mapping function.
@param rangeStart The minimum value in the range.
@@ -135,17 +134,14 @@ public:
{
checkInvariants();
}
- #endif
/** Uses the properties of this mapping to convert a non-normalised value to
its 0->1 representation.
*/
ValueType convertTo0to1 (ValueType v) const noexcept
{
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
if (convertTo0To1Function != nullptr)
return convertTo0To1Function (start, end, v);
- #endif
ValueType proportion = (v - start) / (end - start);
@@ -168,10 +164,8 @@ public:
*/
ValueType convertFrom0to1 (ValueType proportion) const noexcept
{
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
if (convertFrom0To1Function != nullptr)
return convertFrom0To1Function (start, end, proportion);
- #endif
if (! symmetricSkew)
{
@@ -196,10 +190,8 @@ public:
*/
ValueType snapToLegalValue (ValueType v) const noexcept
{
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
if (snapToLegalValueFunction != nullptr)
return snapToLegalValueFunction (start, end, v);
- #endif
if (interval > ValueType())
v = start + interval * std::floor ((v - start) / interval + static_cast (0.5));
@@ -274,9 +266,7 @@ private:
jassert (skew > ValueType());
}
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
std::function convertFrom0To1Function = nullptr,
convertTo0To1Function = nullptr,
snapToLegalValueFunction = nullptr;
- #endif
};
diff --git a/modules/juce_core/misc/juce_RuntimePermissions.h b/modules/juce_core/misc/juce_RuntimePermissions.h
index 338ab3f1af..06ebb415a4 100644
--- a/modules/juce_core/misc/juce_RuntimePermissions.h
+++ b/modules/juce_core/misc/juce_RuntimePermissions.h
@@ -79,11 +79,7 @@ public:
//==============================================================================
/** Function type of runtime permission request callbacks. */
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
typedef std::function Callback;
- #else
- typedef void (*Callback) (bool);
- #endif
//==============================================================================
/** Call this method to request a runtime permission.
diff --git a/modules/juce_core/misc/juce_StdFunctionCompat.cpp b/modules/juce_core/misc/juce_StdFunctionCompat.cpp
new file mode 100644
index 0000000000..a4d85c671d
--- /dev/null
+++ b/modules/juce_core/misc/juce_StdFunctionCompat.cpp
@@ -0,0 +1,228 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE library.
+ Copyright (c) 2017 - ROLI Ltd.
+
+ Permission is granted to use this software under the terms of the ISC license
+ http://www.isc.org/downloads/software-support-policy/isc-license/
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
+ TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
+ OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ OF THIS SOFTWARE.
+
+ -----------------------------------------------------------------------------
+
+ To release a closed-source product which uses other parts of JUCE not
+ licensed under the ISC terms, commercial licenses are available: visit
+ www.juce.com for more information.
+
+ ==============================================================================
+*/
+
+#if JUCE_UNIT_TESTS
+
+namespace FunctionTestsHelpers
+{
+ void incrementArgument (int& x) { x++; };
+ double multiply (double x, double a) noexcept { return a * x; };
+
+ struct AddOne
+ {
+ int operator()(int i) const { return i + 1; }
+ };
+}
+
+class FunctionTests : public UnitTest
+{
+public:
+ FunctionTests() : UnitTest ("Function") {}
+
+ void runTest() override
+ {
+ struct BigData
+ {
+ int content[32];
+ };
+ BigData bigData;
+ bigData.content[0] = 8;
+
+ {
+ beginTest ("Functions");
+
+ std::function f1 (FunctionTestsHelpers::incrementArgument);
+
+ auto x = 0;
+ f1 (x);
+ expectEquals (x, 1);
+
+ std::function f2 (FunctionTestsHelpers::multiply);
+ expectEquals (6.0, f2 (2.0, 3.0));
+
+ }
+
+ {
+ beginTest ("Function objects");
+ std::function f1 = FunctionTestsHelpers::AddOne();
+ expectEquals (f1 (5), 6);
+ }
+
+ {
+ beginTest ("Lambdas");
+
+ std::function fStack ([]() { return 3; });
+ expectEquals (fStack(), 3);
+
+ std::function fHeap ([=]() { return bigData.content[0]; });
+ expectEquals (fHeap(), 8);
+ }
+
+ {
+ beginTest ("Boolean");
+
+ std::function f1;
+
+ if (f1)
+ expect (false);
+
+ std::function f2 ([]() { return 3; });
+
+ if (! f2)
+ expect (false);
+ }
+
+ std::function fEmpty;
+
+ std::function fStack ([]() { return 3; });
+
+ std::function fHeap ([=]() { return bigData.content[0]; });
+
+ {
+ beginTest ("copy constructor");
+
+ std::function f1 (fStack);
+ expectEquals (f1(), 3);
+
+ std::function f2 (fHeap);
+ expectEquals (f2(), 8);
+
+ std::function f3 (fEmpty);
+ if (f3)
+ expect (false);
+ }
+
+ {
+ beginTest ("assignment");
+
+ std::function f1;
+ f1 = fStack;
+ expectEquals (f1(), 3);
+
+ std::function f2;
+ f2 = fHeap;
+ expectEquals (f2(), 8);
+
+ f1 = fHeap;
+ expectEquals (f1(), 8);
+
+ f2 = fStack;
+ expectEquals (f2(), 3);
+
+ f1 = fEmpty;
+ if (f1)
+ expect (false);
+ }
+
+ {
+ beginTest ("move constructor");
+
+ ScopedPointer> fStackTmp = new std::function (fStack);
+ std::function f1 (static_cast&&> (*fStackTmp));
+
+ fStackTmp = nullptr;
+ expectEquals (f1(), 3);
+
+ ScopedPointer> fHeapTmp = new std::function (fHeap);
+ std::function f2 (static_cast&&> (*fHeapTmp));
+ if (*fHeapTmp)
+ expect (false);
+
+ fHeapTmp = nullptr;
+ expectEquals (f2(), 8);
+
+ ScopedPointer> fEmptyTmp = new std::function();
+ std::function f3 (static_cast&&> (*fEmptyTmp));
+ fEmptyTmp = nullptr;
+ if (f3)
+ expect (false);
+ }
+
+ {
+ beginTest ("move assignment");
+
+ std::function f1 (fHeap);
+ ScopedPointer> fStackTmp = new std::function (fStack);
+ f1 = static_cast&&> (*fStackTmp);
+
+ fStackTmp = nullptr;
+ expectEquals (f1(), 3);
+
+ std::function f2 (fStack);
+ ScopedPointer> fHeapTmp = new std::function (fHeap);
+ f2 = static_cast&&> (*fHeapTmp);
+ if (*fHeapTmp)
+ expect (false);
+
+ fHeapTmp = nullptr;
+ expectEquals (f2(), 8);
+
+ std::function f3 (fHeap);
+ ScopedPointer> fEmptyTmp = new std::function ();
+ f3 = static_cast&&> (*fEmptyTmp);
+ fEmptyTmp = nullptr;
+ if (f3)
+ expect (false);
+ }
+
+ {
+ beginTest ("nullptr");
+
+ std::function f1 (nullptr);
+ if (f1)
+ expect (false);
+
+ std::function f2 ([]() { return 11; });
+ f2 = nullptr;
+ if (f2)
+ expect (false);
+ }
+
+ {
+ beginTest ("Swap");
+
+ std::function f1;
+ std::function f2 (fStack);
+ f2.swap (f1);
+ expectEquals (f1(), 3);
+ if (f2)
+ expect (false);
+
+ std::function f3 (fHeap);
+ f3.swap (f1);
+ expectEquals (f3(), 3);
+ expectEquals (f1(), 8);
+ }
+ }
+};
+
+static FunctionTests functionTests;
+
+#endif
diff --git a/modules/juce_core/misc/juce_StdFunctionCompat.h b/modules/juce_core/misc/juce_StdFunctionCompat.h
new file mode 100644
index 0000000000..9fcde88a94
--- /dev/null
+++ b/modules/juce_core/misc/juce_StdFunctionCompat.h
@@ -0,0 +1,225 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE library.
+ Copyright (c) 2017 - ROLI Ltd.
+
+ Permission is granted to use this software under the terms of the ISC license
+ http://www.isc.org/downloads/software-support-policy/isc-license/
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
+ TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
+ OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ OF THIS SOFTWARE.
+
+ -----------------------------------------------------------------------------
+
+ To release a closed-source product which uses other parts of JUCE not
+ licensed under the ISC terms, commercial licenses are available: visit
+ www.juce.com for more information.
+
+ ==============================================================================
+*/
+
+#pragma once
+
+namespace std
+{
+ /**
+ This class provides an alternative to std::function that is compatible
+ with OS X 10.6 and earlier. This will only be used in OS X versions 10.6
+ and earlier and the Projucer live build.
+ */
+
+ template
+ class function;
+
+ template
+ class function
+ {
+ public:
+ /** Creates an empty function. */
+ function() noexcept {}
+
+ /** Creates an empty function. */
+ function (decltype (nullptr)) noexcept {}
+
+ /** Creates a function targetting the provided Functor. */
+ template
+ function (Functor f)
+ {
+ functorHolderHelper = createFunctorStorage (sizeof (FunctorHolder));
+ new (functorHolderHelper) FunctorHolder (f);
+ }
+
+ /** Copy constructor. */
+ function (function const& other)
+ {
+ copy (other);
+ }
+
+ /** Move constructor */
+ function (function&& other)
+ {
+ move (other);
+ }
+
+ /** Destructor. */
+ ~function()
+ {
+ release();
+ }
+
+ /** Replaces the contents of this function with the contents of another. */
+ function& operator= (function const& other)
+ {
+ release();
+ copy (other);
+
+ return *this;
+ }
+
+ /** Moves the contents of another function into this one. */
+ function& operator= (function&& other)
+ {
+ release();
+ move (other);
+
+ return *this;
+ }
+
+ /** Allows conditional expressions to test if this function is empty. */
+ explicit operator bool() const noexcept
+ {
+ return functorHolderHelper != nullptr;
+ }
+
+ /** Swaps the contents of this function with another. After this operation the
+ two functions will be pointing at each other's targets. */
+ void swap (function& other)
+ {
+ function tmp (*this);
+ *this = other;
+ other = tmp;
+ }
+
+ /** Invokes the target of this function. */
+ Result operator() (Arguments... args) const
+ {
+ return (*functorHolderHelper) (args...);
+ }
+
+ bool operator== (decltype (nullptr)) const noexcept { return (functorHolderHelper == nullptr); }
+ bool operator!= (decltype (nullptr)) const noexcept { return (functorHolderHelper != nullptr); }
+
+ private:
+ //==============================================================================
+ template
+ struct FunctorHolderBase
+ {
+ virtual ~FunctorHolderBase() {};
+ virtual size_t getSize() const noexcept = 0;
+ virtual FunctorHolderBase* copy (void*) const = 0;
+ virtual ReturnType operator()(Args...) = 0;
+ };
+
+ template
+ struct FunctorHolder : FunctorHolderBase
+ {
+ FunctorHolder (Functor func) : f (func) {}
+
+ size_t getSize() const noexcept override final
+ {
+ return sizeof (*this);
+ }
+
+ FunctorHolder* copy (void* destination) const override final
+ {
+ return new (destination) FunctorHolder (f);
+ }
+
+ ReturnType operator()(Args... args) override final
+ {
+ return f (args...);
+ }
+
+ Functor f;
+ };
+
+ FunctorHolderBase* createFunctorStorage (size_t size)
+ {
+ void* storagePointer;
+
+ if (size > functorHolderStackSize)
+ {
+ if (heapFunctorStorage != nullptr)
+ {
+ delete [] heapFunctorStorage;
+ heapFunctorStorage = nullptr;
+ }
+
+ heapFunctorStorage = new char [size];
+ storagePointer = heapFunctorStorage;
+ }
+ else
+ {
+ storagePointer = &(stackFunctorStorage[0]);
+ }
+
+ return reinterpret_cast*> (storagePointer);
+ }
+
+ void copy (function const& other)
+ {
+ if (other.functorHolderHelper != nullptr)
+ {
+ functorHolderHelper = createFunctorStorage (other.functorHolderHelper->getSize());
+ other.functorHolderHelper->copy (functorHolderHelper);
+ }
+ }
+
+ void move (function& other)
+ {
+ functorHolderHelper = other.functorHolderHelper;
+
+ if (functorHolderHelper != nullptr)
+ {
+ if (functorHolderHelper->getSize() > functorHolderStackSize)
+ {
+ heapFunctorStorage = other.heapFunctorStorage;
+ other.heapFunctorStorage = nullptr;
+ }
+ else
+ {
+ std::copy (other.stackFunctorStorage, other.stackFunctorStorage + functorHolderStackSize,
+ stackFunctorStorage);
+ functorHolderHelper = reinterpret_cast*> (&(stackFunctorStorage[0]));
+ }
+
+ other.functorHolderHelper = nullptr;
+ }
+ }
+
+ void release()
+ {
+ if (functorHolderHelper != nullptr)
+ {
+ functorHolderHelper->~FunctorHolderBase();
+ functorHolderHelper = nullptr;
+ }
+ }
+
+ static const int functorHolderStackSize = 24;
+ char stackFunctorStorage[functorHolderStackSize];
+ char* heapFunctorStorage = nullptr;
+
+ FunctorHolderBase* functorHolderHelper = nullptr;
+ };
+}
diff --git a/modules/juce_core/system/juce_CompilerSupport.h b/modules/juce_core/system/juce_CompilerSupport.h
index 00e4bc7c72..6195e99e40 100644
--- a/modules/juce_core/system/juce_CompilerSupport.h
+++ b/modules/juce_core/system/juce_CompilerSupport.h
@@ -44,6 +44,7 @@
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && ! defined (JUCE_COMPILER_SUPPORTS_LAMBDAS)
#define JUCE_COMPILER_SUPPORTS_LAMBDAS 1
+ #define JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT 1
#endif
#ifndef JUCE_EXCEPTIONS_DISABLED
@@ -65,10 +66,14 @@
#define JUCE_DELETED_FUNCTION = delete
#endif
- #if __has_feature (cxx_lambdas) && (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS))
+ #if __has_feature (cxx_lambdas)
#define JUCE_COMPILER_SUPPORTS_LAMBDAS 1
#endif
+ #if (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS))
+ #define JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT 1
+ #endif
+
#if __has_feature (cxx_generalized_initializers) && (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS))
#define JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS 1
#endif
@@ -106,6 +111,7 @@
#define JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS 1
#define JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES 1
#define JUCE_DELETED_FUNCTION = delete
+ #define JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT 1
#endif
#if _MSC_VER >= 1900
diff --git a/modules/juce_core/system/juce_StandardHeader.h b/modules/juce_core/system/juce_StandardHeader.h
index 7e574301e7..981457fe44 100644
--- a/modules/juce_core/system/juce_StandardHeader.h
+++ b/modules/juce_core/system/juce_StandardHeader.h
@@ -107,6 +107,12 @@
#undef minor
#undef KeyPress
+// Include a replacement for std::function on older platforms and the live
+// build
+#if JUCE_PROJUCER_LIVE_BUILD || ! defined (JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT)
+ #include "../misc/juce_StdFunctionCompat.h"
+#endif
+
//==============================================================================
// DLL building settings on Windows
#if JUCE_MSVC
diff --git a/modules/juce_events/timers/juce_Timer.cpp b/modules/juce_events/timers/juce_Timer.cpp
index d74adaa3a2..da2ea738ee 100644
--- a/modules/juce_events/timers/juce_Timer.cpp
+++ b/modules/juce_events/timers/juce_Timer.cpp
@@ -341,7 +341,6 @@ void JUCE_CALLTYPE Timer::callPendingTimersSynchronously()
TimerThread::instance->callTimersSynchronously();
}
-#if JUCE_COMPILER_SUPPORTS_LAMBDAS
struct LambdaInvoker : private Timer
{
LambdaInvoker (int milliseconds, std::function f) : function (f)
@@ -365,4 +364,3 @@ void JUCE_CALLTYPE Timer::callAfterDelay (int milliseconds, std::function functionToCall);
- #endif
//==============================================================================
/** For internal use only: invokes any timers that need callbacks.
diff --git a/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp b/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp
index 9cfc75940d..d0cbb13f5b 100644
--- a/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp
+++ b/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp
@@ -297,7 +297,6 @@ int ModalComponentManager::runEventLoopForCurrentComponent()
#endif
//==============================================================================
-#if JUCE_COMPILER_SUPPORTS_LAMBDAS
struct LambdaCallback : public ModalComponentManager::Callback
{
LambdaCallback (std::function fn) noexcept : function (fn) {}
@@ -312,4 +311,3 @@ ModalComponentManager::Callback* ModalCallbackFunction::create (std::function (functionToCall, parameterValue);
}
- #if JUCE_COMPILER_SUPPORTS_LAMBDAS
/** This is a utility function to create a ModalComponentManager::Callback that will
call a lambda function.
The lambda that you supply must take an integer parameter, which is the result code that
@@ -197,7 +196,6 @@ public:
@see ModalComponentManager::Callback
*/
static ModalComponentManager::Callback* create (std::function);
- #endif
//==============================================================================
/** This is a utility function to create a ModalComponentManager::Callback that will