| 
							- /*
 -  * Carla Scope-related classes and tools (pointer and setter taken from JUCE v4)
 -  * Copyright (C) 2013 Raw Material Software Ltd.
 -  * Copyright (c) 2016 ROLI Ltd.
 -  * Copyright (C) 2013-2020 Filipe Coelho <falktx@falktx.com>
 -  *
 -  * This program is free software; you can redistribute it and/or
 -  * modify it under the terms of the GNU General Public License as
 -  * published by the Free Software Foundation; either version 2 of
 -  * the License, or any later version.
 -  *
 -  * This program is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 -  * GNU General Public License for more details.
 -  *
 -  * For a full copy of the GNU General Public License see the doc/GPL.txt file.
 -  */
 - 
 - #ifndef CARLA_SCOPE_UTILS_HPP_INCLUDED
 - #define CARLA_SCOPE_UTILS_HPP_INCLUDED
 - 
 - #include "CarlaUtils.hpp"
 - 
 - #include <algorithm>
 - #include <clocale>
 - 
 - #if ! (defined(CARLA_OS_HAIKU) || defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
 - # define CARLA_USE_NEWLOCALE
 - #endif
 - 
 - #if defined(CARLA_OS_WIN) && __MINGW64_VERSION_MAJOR >= 5
 - # define CARLA_USE_CONFIGTHREADLOCALE
 - #endif
 - 
 - // -----------------------------------------------------------------------
 - // CarlaScopedEnvVar class
 - 
 - class CarlaScopedEnvVar {
 - public:
 -     CarlaScopedEnvVar(const char* const envVar, const char* const valueOrNull) noexcept
 -         : key(nullptr),
 -           origValue(nullptr)
 -     {
 -         CARLA_SAFE_ASSERT_RETURN(envVar != nullptr && envVar[0] != '\0',);
 - 
 -         key = carla_strdup_safe(envVar);
 -         CARLA_SAFE_ASSERT_RETURN(key != nullptr,);
 - 
 -         if (const char* const envVarValue = std::getenv(key))
 -         {
 -             origValue = carla_strdup_safe(envVarValue);
 -             CARLA_SAFE_ASSERT_RETURN(origValue != nullptr,);
 -         }
 - 
 -         // change env var if requested
 -         if (valueOrNull != nullptr)
 -             carla_setenv(key, valueOrNull);
 -         // if null, unset. but only if there is in an active env var value
 -         else if (origValue != nullptr)
 -             carla_unsetenv(key);
 -     }
 - 
 -     ~CarlaScopedEnvVar() noexcept
 -     {
 -         bool hasOrigValue = false;
 - 
 -         if (origValue != nullptr)
 -         {
 -             hasOrigValue = true;
 - 
 -             carla_setenv(key, origValue);
 - 
 -             delete[] origValue;
 -             origValue = nullptr;
 -         }
 - 
 -         if (key != nullptr)
 -         {
 -             if (! hasOrigValue)
 -                 carla_unsetenv(key);
 - 
 -             delete[] key;
 -             key = nullptr;
 -         }
 -     }
 - 
 - private:
 -     const char* key;
 -     const char* origValue;
 - 
 -     CARLA_DECLARE_NON_COPYABLE(CarlaScopedEnvVar)
 -     CARLA_PREVENT_HEAP_ALLOCATION
 - };
 - 
 - // -----------------------------------------------------------------------
 - // CarlaScopedLocale class
 - 
 - class CarlaScopedLocale {
 - #ifdef CARLA_USE_NEWLOCALE
 -     static constexpr locale_t kNullLocale = (locale_t)nullptr;
 - #endif
 - 
 - public:
 -     CarlaScopedLocale() noexcept
 - #ifdef CARLA_USE_NEWLOCALE
 -         : newloc(::newlocale(LC_NUMERIC_MASK, "C", kNullLocale)),
 -           oldloc(newloc != kNullLocale ? ::uselocale(newloc) : kNullLocale) {}
 - #else
 - # ifdef CARLA_USE_CONFIGTHREADLOCALE
 -         : oldthreadloc(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)),
 - # else
 -         :
 - # endif
 -           oldloc(carla_strdup_safe(::setlocale(LC_NUMERIC, nullptr)))
 -     {
 -         ::setlocale(LC_NUMERIC, "C");
 -     }
 - #endif
 - 
 -     ~CarlaScopedLocale() noexcept
 -     {
 - #ifdef CARLA_USE_NEWLOCALE
 -         if (oldloc != kNullLocale)
 -             ::uselocale(oldloc);
 -         if (newloc != kNullLocale)
 -             ::freelocale(newloc);
 - #else // CARLA_USE_NEWLOCALE
 -         if (oldloc != nullptr)
 -         {
 -             ::setlocale(LC_NUMERIC, oldloc);
 -             delete[] oldloc;
 -         }
 - 
 - # ifdef CARLA_USE_CONFIGTHREADLOCALE
 -         if (oldthreadloc != -1)
 -             _configthreadlocale(oldthreadloc);
 - # endif
 - #endif // CARLA_USE_NEWLOCALE
 -     }
 - 
 - private:
 - #ifdef CARLA_USE_NEWLOCALE
 -     locale_t newloc, oldloc;
 - #else
 - # ifdef CARLA_USE_CONFIGTHREADLOCALE
 -     const int oldthreadloc;
 - # endif
 -     const char* const oldloc;
 - #endif
 - 
 -     CARLA_DECLARE_NON_COPYABLE(CarlaScopedLocale)
 -     CARLA_PREVENT_HEAP_ALLOCATION
 - };
 - 
 - //=====================================================================================================================
 - /**
 -     This class holds a pointer which is automatically deleted when this object goes
 -     out of scope.
 - 
 -     Once a pointer has been passed to a CarlaScopedPointer, it will make sure that the pointer
 -     gets deleted when the CarlaScopedPointer is deleted. Using the CarlaScopedPointer on the stack or
 -     as member variables is a good way to use RAII to avoid accidentally leaking dynamically
 -     created objects.
 - 
 -     A CarlaScopedPointer can be used in pretty much the same way that you'd use a normal pointer
 -     to an object. If you use the assignment operator to assign a different object to a
 -     CarlaScopedPointer, the old one will be automatically deleted.
 - 
 -     A const CarlaScopedPointer is guaranteed not to lose ownership of its object or change the
 -     object to which it points during its lifetime. This means that making a copy of a const
 -     CarlaScopedPointer is impossible, as that would involve the new copy taking ownership from the
 -     old one.
 - 
 -     If you need to get a pointer out of a CarlaScopedPointer without it being deleted, you
 -     can use the release() method.
 - 
 -     Something to note is the main difference between this class and the std::auto_ptr class,
 -     which is that CarlaScopedPointer provides a cast-to-object operator, whereas std::auto_ptr
 -     requires that you always call get() to retrieve the pointer. The advantages of providing
 -     the cast is that you don't need to call get(), so can use the CarlaScopedPointer in pretty much
 -     exactly the same way as a raw pointer. The disadvantage is that the compiler is free to
 -     use the cast in unexpected and sometimes dangerous ways - in particular, it becomes difficult
 -     to return a CarlaScopedPointer as the result of a function. To avoid this causing errors,
 -     CarlaScopedPointer contains an overloaded constructor that should cause a syntax error in these
 -     circumstances, but it does mean that instead of returning a CarlaScopedPointer from a function,
 -     you'd need to return a raw pointer (or use a std::auto_ptr instead).
 - */
 - template<class ObjectType>
 - class CarlaScopedPointer
 - {
 - public:
 -     //=================================================================================================================
 -     /** Creates a CarlaScopedPointer containing a null pointer. */
 -     CarlaScopedPointer() noexcept
 -         : object(nullptr) {}
 - 
 -     /** Creates a CarlaScopedPointer that owns the specified object. */
 -     CarlaScopedPointer(ObjectType* const objectToTakePossessionOf) noexcept
 -         : object(objectToTakePossessionOf) {}
 - 
 -     /** Creates a CarlaScopedPointer that takes its pointer from another CarlaScopedPointer.
 - 
 -         Because a pointer can only belong to one CarlaScopedPointer, this transfers
 -         the pointer from the other object to this one, and the other object is reset to
 -         be a null pointer.
 -     */
 -     CarlaScopedPointer(CarlaScopedPointer& objectToTransferFrom) noexcept
 -         : object(objectToTransferFrom.object)
 -     {
 -         objectToTransferFrom.object = nullptr;
 -     }
 - 
 -     /** Destructor.
 -         This will delete the object that this CarlaScopedPointer currently refers to.
 -     */
 -     ~CarlaScopedPointer()
 -     {
 -         delete object;
 -     }
 - 
 -     /** Changes this CarlaScopedPointer to point to a new object.
 - 
 -         Because a pointer can only belong to one CarlaScopedPointer, this transfers
 -         the pointer from the other object to this one, and the other object is reset to
 -         be a null pointer.
 - 
 -         If this CarlaScopedPointer already points to an object, that object
 -         will first be deleted.
 -     */
 -     CarlaScopedPointer& operator=(CarlaScopedPointer& objectToTransferFrom)
 -     {
 -         if (this != objectToTransferFrom.getAddress())
 -         {
 -             // Two CarlaScopedPointers should never be able to refer to the same object - if
 -             // this happens, you must have done something dodgy!
 -             CARLA_SAFE_ASSERT_RETURN(object == nullptr || object != objectToTransferFrom.object, *this);
 - 
 -             ObjectType* const oldObject = object;
 -             object = objectToTransferFrom.object;
 -             objectToTransferFrom.object = nullptr;
 -             delete oldObject;
 -         }
 - 
 -         return *this;
 -     }
 - 
 -     /** Changes this CarlaScopedPointer to point to a new object.
 - 
 -         If this CarlaScopedPointer already points to an object, that object
 -         will first be deleted.
 - 
 -         The pointer that you pass in may be a nullptr.
 -     */
 -     CarlaScopedPointer& operator=(ObjectType* const newObjectToTakePossessionOf)
 -     {
 -         if (object != newObjectToTakePossessionOf)
 -         {
 -             ObjectType* const oldObject = object;
 -             object = newObjectToTakePossessionOf;
 -             delete oldObject;
 -         }
 - 
 -         return *this;
 -     }
 - 
 -     //=================================================================================================================
 -     /** Returns the object that this CarlaScopedPointer refers to. */
 -     operator ObjectType*() const noexcept   { return object; }
 - 
 -     /** Returns the object that this CarlaScopedPointer refers to. */
 -     ObjectType* get() const noexcept        { return object; }
 - 
 -     /** Returns the object that this CarlaScopedPointer refers to. */
 -     ObjectType& operator*() const noexcept  { return *object; }
 - 
 -     /** Lets you access methods and properties of the object that this CarlaScopedPointer refers to. */
 -     ObjectType* operator->() const noexcept { return object; }
 - 
 -     //=================================================================================================================
 -     /** Removes the current object from this CarlaScopedPointer without deleting it.
 -         This will return the current object, and set the CarlaScopedPointer to a null pointer.
 -     */
 -     ObjectType* release() noexcept          { ObjectType* const o = object; object = nullptr; return o; }
 - 
 -     //=================================================================================================================
 -     /** Swaps this object with that of another CarlaScopedPointer.
 -         The two objects simply exchange their pointers.
 -     */
 -     void swapWith(CarlaScopedPointer<ObjectType>& other) noexcept
 -     {
 -         // Two CarlaScopedPointers should never be able to refer to the same object - if
 -         // this happens, you must have done something dodgy!
 -         CARLA_SAFE_ASSERT_RETURN(object != other.object || this == other.getAddress() || object == nullptr,);
 - 
 -         std::swap(object, other.object);
 -     }
 - 
 - private:
 -     //=================================================================================================================
 -     ObjectType* object;
 - 
 -     // (Required as an alternative to the overloaded & operator).
 -     const CarlaScopedPointer* getAddress() const noexcept { return this; }
 - 
 - #ifdef CARLA_PROPER_CPP11_SUPPORT
 -     CarlaScopedPointer(const CarlaScopedPointer&) = delete;
 -     CarlaScopedPointer& operator=(const CarlaScopedPointer&) = delete;
 - #else
 -     CarlaScopedPointer(const CarlaScopedPointer&);
 -     CarlaScopedPointer& operator=(const CarlaScopedPointer&);
 - #endif
 - };
 - 
 - //=====================================================================================================================
 - /** Compares a CarlaScopedPointer with another pointer.
 -     This can be handy for checking whether this is a null pointer.
 - */
 - template<class ObjectType>
 - bool operator==(const CarlaScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept
 - {
 -     return static_cast<ObjectType*>(pointer1) == pointer2;
 - }
 - 
 - /** Compares a CarlaScopedPointer with another pointer.
 -     This can be handy for checking whether this is a null pointer.
 - */
 - template<class ObjectType>
 - bool operator!=(const CarlaScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept
 - {
 -     return static_cast<ObjectType*>(pointer1) != pointer2;
 - }
 - 
 - //=====================================================================================================================
 - /**
 -     Helper class providing an RAII-based mechanism for temporarily setting and
 -     then re-setting a value.
 - 
 -     E.g. @code
 -     int x = 1;
 - 
 -     {
 -         CarlaScopedValueSetter setter (x, 2);
 - 
 -         // x is now 2
 -     }
 - 
 -     // x is now 1 again
 - 
 -     {
 -         CarlaScopedValueSetter setter (x, 3, 4);
 - 
 -         // x is now 3
 -     }
 - 
 -     // x is now 4
 -     @endcode
 - */
 - template <typename ValueType>
 - class CarlaScopedValueSetter
 - {
 - public:
 -     /** Creates a CarlaScopedValueSetter that will immediately change the specified value to the
 -         given new value, and will then reset it to its original value when this object is deleted.
 -         Must be used only for 'noexcept' compatible types.
 -     */
 -     CarlaScopedValueSetter(ValueType& valueToSet, ValueType newValue) noexcept
 -         : value(valueToSet),
 -           originalValue(valueToSet)
 -     {
 -         valueToSet = newValue;
 -     }
 - 
 -     /** Creates a CarlaScopedValueSetter that will immediately change the specified value to the
 -         given new value, and will then reset it to be valueWhenDeleted when this object is deleted.
 -     */
 -     CarlaScopedValueSetter(ValueType& valueToSet, ValueType newValue, ValueType valueWhenDeleted) noexcept
 -         : value(valueToSet),
 -           originalValue(valueWhenDeleted)
 -     {
 -         valueToSet = newValue;
 -     }
 - 
 -     ~CarlaScopedValueSetter() noexcept
 -     {
 -         value = originalValue;
 -     }
 - 
 - private:
 -     //=================================================================================================================
 -     ValueType& value;
 -     const ValueType originalValue;
 - 
 -     CARLA_DECLARE_NON_COPYABLE(CarlaScopedValueSetter)
 -     CARLA_PREVENT_HEAP_ALLOCATION
 - };
 - 
 - // -----------------------------------------------------------------------
 - 
 - #endif // CARLA_SCOPE_UTILS_HPP_INCLUDED
 
 
  |