| 
							- /*
 -  * Carla misc utils imported from Juce source code
 -  * Copyright (C) 2004-11 Raw Material Software Ltd.
 -  * Copyright (C) 2013 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 GPL.txt file
 -  */
 - 
 - #ifndef __CARLA_JUCE_UTILS_HPP__
 - #define __CARLA_JUCE_UTILS_HPP__
 - 
 - #include "CarlaUtils.hpp"
 - 
 - #include <algorithm>
 - 
 - #define CARLA_DECLARE_NON_COPYABLE(className) \
 - private:                                      \
 -     className (const className&);             \
 -     className& operator= (const className&);
 - 
 - /** This is a shorthand way of writing both a CARLA_DECLARE_NON_COPYABLE and
 -     CARLA_LEAK_DETECTOR macro for a class.
 - */
 - #define CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className) \
 -     CARLA_DECLARE_NON_COPYABLE(className)                        \
 -     CARLA_LEAK_DETECTOR(className)
 - 
 - /** struct versions of the above. */
 - #define CARLA_DECLARE_NON_COPY_STRUCT(structName) \
 -     structName(structName&) = delete;             \
 -     structName(const structName&) = delete;
 - 
 - #define CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(structName) \
 -     CARLA_DECLARE_NON_COPY_STRUCT(structName)                        \
 -     CARLA_LEAK_DETECTOR(structName)
 - 
 - /** This macro can be added to class definitions to disable the use of new/delete to
 -     allocate the object on the heap, forcing it to only be used as a stack or member variable.
 - */
 - #define CARLA_PREVENT_HEAP_ALLOCATION   \
 - private:                                \
 -     static void* operator new (size_t); \
 -     static void operator delete (void*);
 - 
 - /** A good old-fashioned C macro concatenation helper.
 -    This combines two items (which may themselves be macros) into a single string,
 -    avoiding the pitfalls of the ## macro operator.
 - */
 - #define CARLA_JOIN_MACRO_HELPER(a, b) a ## b
 - #define CARLA_JOIN_MACRO(item1, item2)  CARLA_JOIN_MACRO_HELPER (item1, item2)
 - 
 - 
 - //==============================================================================
 - /**
 -     Embedding an instance of this class inside another class can be used as a low-overhead
 -     way of detecting leaked instances.
 - 
 -     This class keeps an internal static count of the number of instances that are
 -     active, so that when the app is shutdown and the static destructors are called,
 -     it can check whether there are any left-over instances that may have been leaked.
 - 
 -     To use it, use the CARLA_LEAK_DETECTOR macro as a simple way to put one in your
 -     class declaration. Have a look through the juce codebase for examples, it's used
 -     in most of the classes.
 - */
 - template <class OwnerClass>
 - class LeakedObjectDetector
 - {
 - public:
 -     //==============================================================================
 -     LeakedObjectDetector()
 -     {
 -         ++(getCounter().numObjects);
 -     }
 - 
 -     LeakedObjectDetector(const LeakedObjectDetector&)
 -     {
 -         ++(getCounter().numObjects);
 -     }
 - 
 -     ~LeakedObjectDetector()
 -     {
 -         if (--(getCounter().numObjects) < 0)
 -         {
 -             carla_stderr("*** Dangling pointer deletion! Class: '%s'", getLeakedObjectClassName());
 - 
 -             /** If you hit this, then you've managed to delete more instances of this class than you've
 -                 created.. That indicates that you're deleting some dangling pointers.
 - 
 -                 Note that although this assertion will have been triggered during a destructor, it might
 -                 not be this particular deletion that's at fault - the incorrect one may have happened
 -                 at an earlier point in the program, and simply not been detected until now.
 - 
 -                 Most errors like this are caused by using old-fashioned, non-RAII techniques for
 -                 your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays,
 -                 ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs!
 -             */
 -             //assert(false);
 -         }
 -     }
 - 
 - private:
 -     //==============================================================================
 -     class LeakCounter
 -     {
 -     public:
 -         LeakCounter()
 -         {
 -             numObjects = 0;
 -         }
 - 
 -         ~LeakCounter()
 -         {
 -             if (numObjects > 0)
 -             {
 -                 carla_stderr("*** Leaked objects detected: %i instance(s) of class '%s'", numObjects, getLeakedObjectClassName());
 - 
 -                 /** If you hit this, then you've leaked one or more objects of the type specified by
 -                     the 'OwnerClass' template parameter - the name should have been printed by the line above.
 - 
 -                     If you're leaking, it's probably because you're using old-fashioned, non-RAII techniques for
 -                     your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays,
 -                     ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs!
 -                 */
 -                 //assert(false);
 -             }
 -         }
 - 
 -         int numObjects;
 -     };
 - 
 -     static const char* getLeakedObjectClassName()
 -     {
 -         return OwnerClass::getLeakedObjectClassName();
 -     }
 - 
 -     static LeakCounter& getCounter()
 -     {
 -         static LeakCounter counter;
 -         return counter;
 -     }
 - };
 - 
 - #define CARLA_LEAK_DETECTOR(OwnerClass) \
 -     friend class LeakedObjectDetector<OwnerClass>; \
 -     static const char* getLeakedObjectClassName() { return #OwnerClass; } \
 -     LeakedObjectDetector<OwnerClass> CARLA_JOIN_MACRO (leakDetector, __LINE__);
 - 
 - 
 - //==============================================================================
 - /**
 -     This class holds a pointer which is automatically deleted when this object goes
 -     out of scope.
 - 
 -     Once a pointer has been passed to a ScopedPointer, it will make sure that the pointer
 -     gets deleted when the ScopedPointer is deleted. Using the ScopedPointer on the stack or
 -     as member variables is a good way to use RAII to avoid accidentally leaking dynamically
 -     created objects.
 - 
 -     A ScopedPointer 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
 -     ScopedPointer, the old one will be automatically deleted.
 - 
 -     Important note: The class is designed to hold a pointer to an object, NOT to an array!
 -     It calls delete on its payload, not delete[], so do not give it an array to hold! For
 -     that kind of purpose, you should be using HeapBlock or Array instead.
 - 
 -     A const ScopedPointer 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
 -     ScopedPointer 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 ScopedPointer 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 ScopedPointer provides a cast-to-object operator, wheras 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 ScopedPointer 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 ScopedPointer as the result of a function. To avoid this causing errors,
 -     ScopedPointer contains an overloaded constructor that should cause a syntax error in these
 -     circumstances, but it does mean that instead of returning a ScopedPointer from a function,
 -     you'd need to return a raw pointer (or use a std::auto_ptr instead).
 - */
 - template <class ObjectType>
 - class ScopedPointer
 - {
 - public:
 -     //==============================================================================
 -     /** Creates a ScopedPointer containing a null pointer. */
 -     ScopedPointer()
 -         : object(nullptr)
 -     {
 -     }
 - 
 -     /** Creates a ScopedPointer that owns the specified object. */
 -     ScopedPointer(ObjectType* const objectToTakePossessionOf)
 -         : object(objectToTakePossessionOf)
 -     {
 -     }
 - 
 -     /** Creates a ScopedPointer that takes its pointer from another ScopedPointer.
 - 
 -         Because a pointer can only belong to one ScopedPointer, this transfers
 -         the pointer from the other object to this one, and the other object is reset to
 -         be a null pointer.
 -     */
 -     ScopedPointer(ScopedPointer& objectToTransferFrom)
 -         : object(objectToTransferFrom.object)
 -     {
 -         objectToTransferFrom.object = nullptr;
 -     }
 - 
 -     /** Destructor.
 -         This will delete the object that this ScopedPointer currently refers to.
 -     */
 -     ~ScopedPointer()
 -     {
 -         delete object;
 -     }
 - 
 -     /** Changes this ScopedPointer to point to a new object.
 - 
 -         Because a pointer can only belong to one ScopedPointer, this transfers
 -         the pointer from the other object to this one, and the other object is reset to
 -         be a null pointer.
 - 
 -         If this ScopedPointer already points to an object, that object
 -         will first be deleted.
 -     */
 -     ScopedPointer& operator=(ScopedPointer& objectToTransferFrom)
 -     {
 -         if (this != objectToTransferFrom.getAddress())
 -         {
 -             // Two ScopedPointers should never be able to refer to the same object - if
 -             // this happens, you must have done something dodgy!
 -             assert(object == nullptr || object != objectToTransferFrom.object);
 - 
 -             ObjectType* const oldObject = object;
 -             object = objectToTransferFrom.object;
 -             objectToTransferFrom.object = nullptr;
 -             delete oldObject;
 -         }
 - 
 -         return *this;
 -     }
 - 
 -     /** Changes this ScopedPointer to point to a new object.
 - 
 -         If this ScopedPointer already points to an object, that object
 -         will first be deleted.
 - 
 -         The pointer that you pass in may be a nullptr.
 -     */
 -     ScopedPointer& operator=(ObjectType* const newObjectToTakePossessionOf)
 -     {
 -         if (object != newObjectToTakePossessionOf)
 -         {
 -             ObjectType* const oldObject = object;
 -             object = newObjectToTakePossessionOf;
 -             delete oldObject;
 -         }
 - 
 -         return *this;
 -     }
 - 
 -     //==============================================================================
 -     /** Returns the object that this ScopedPointer refers to. */
 -     operator ObjectType*() const   { return object; }
 - 
 -     /** Returns the object that this ScopedPointer refers to. */
 -     ObjectType* get() const        { return object; }
 - 
 -     /** Returns the object that this ScopedPointer refers to. */
 -     ObjectType& operator*() const  { return *object; }
 - 
 -     /** Lets you access methods and properties of the object that this ScopedPointer refers to. */
 -     ObjectType* operator->() const { return object; }
 - 
 -     //==============================================================================
 -     /** Removes the current object from this ScopedPointer without deleting it.
 -         This will return the current object, and set the ScopedPointer to a null pointer.
 -     */
 -     ObjectType* release()
 -     {
 -         ObjectType* const o = object;
 -         object = nullptr;
 -         return o;
 -     }
 - 
 -     //==============================================================================
 -     /** Swaps this object with that of another ScopedPointer.
 -         The two objects simply exchange their pointers.
 -     */
 -     void swapWith(ScopedPointer<ObjectType>& other)
 -     {
 -         // Two ScopedPointers should never be able to refer to the same object - if
 -         // this happens, you must have done something dodgy!
 -         assert(object != other.object || this == other.getAddress());
 - 
 -         std::swap(object, other.object);
 -     }
 - 
 - private:
 -     //==============================================================================
 -     ObjectType* object;
 - 
 -     // (Required as an alternative to the overloaded & operator).
 -     const ScopedPointer* getAddress() const
 -     {
 -         return this;
 -     }
 - 
 - #if ! defined(CARLA_CC_MSVC)  // (MSVC can't deal with multiple copy constructors)
 -     /* These are private to stop people accidentally copying a const ScopedPointer (the compiler
 -        would let you do so by implicitly casting the source to its raw object pointer).
 - 
 -        A side effect of this is that you may hit a puzzling compiler error when you write something
 -        like this:
 - 
 -           ScopedPointer<MyClass> m = new MyClass();  // Compile error: copy constructor is private.
 - 
 -        Even though the compiler would normally ignore the assignment here, it can't do so when the
 -        copy constructor is private. It's very easy to fix though - just write it like this:
 - 
 -           ScopedPointer<MyClass> m (new MyClass());  // Compiles OK
 - 
 -        It's good practice to always use the latter form when writing your object declarations anyway,
 -        rather than writing them as assignments and assuming (or hoping) that the compiler will be
 -        smart enough to replace your construction + assignment with a single constructor.
 -     */
 -     ScopedPointer(const ScopedPointer&);
 -     ScopedPointer& operator=(const ScopedPointer&);
 - #endif
 - };
 - 
 - //==============================================================================
 - /** Compares a ScopedPointer with another pointer.
 -     This can be handy for checking whether this is a null pointer.
 - */
 - template <class ObjectType>
 - bool operator==(const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept
 - {
 -     return static_cast<ObjectType*>(pointer1) == pointer2;
 - }
 - 
 - /** Compares a ScopedPointer with another pointer.
 -     This can be handy for checking whether this is a null pointer.
 - */
 - template <class ObjectType>
 - bool operator!=(const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept
 - {
 -     return static_cast<ObjectType*>(pointer1) != pointer2;
 - }
 - 
 - #endif // __CARLA_JUCE_UTILS_HPP__
 
 
  |