From f4046909ab35ea23deed7244d66d021f7514b3af Mon Sep 17 00:00:00 2001 From: tpoole Date: Wed, 3 May 2017 15:36:25 +0100 Subject: [PATCH] Added an OS X 10.5 compatible std::function replacement --- extras/Projucer/Projucer.jucer | 3 +- .../projucer_CompileEngineClient.cpp | 4 + .../format/juce_AudioPluginFormat.cpp | 2 - .../format/juce_AudioPluginFormat.h | 2 - .../format/juce_AudioPluginFormatManager.cpp | 4 - .../format/juce_AudioPluginFormatManager.h | 2 - .../juce_AudioProcessorValueTreeState.cpp | 4 - .../juce_AudioProcessorValueTreeState.h | 4 - modules/juce_core/containers/juce_Variant.h | 4 - modules/juce_core/juce_core.cpp | 1 + .../juce_core/maths/juce_NormalisableRange.h | 10 - .../juce_core/misc/juce_RuntimePermissions.h | 4 - .../juce_core/misc/juce_StdFunctionCompat.cpp | 228 ++++++++++++++++++ .../juce_core/misc/juce_StdFunctionCompat.h | 225 +++++++++++++++++ .../juce_core/system/juce_CompilerSupport.h | 8 +- .../juce_core/system/juce_StandardHeader.h | 6 + modules/juce_events/timers/juce_Timer.cpp | 2 - modules/juce_events/timers/juce_Timer.h | 2 - .../components/juce_ModalComponentManager.cpp | 2 - .../components/juce_ModalComponentManager.h | 2 - 20 files changed, 472 insertions(+), 47 deletions(-) create mode 100644 modules/juce_core/misc/juce_StdFunctionCompat.cpp create mode 100644 modules/juce_core/misc/juce_StdFunctionCompat.h 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