mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-07 04:10:08 +00:00
Added Value support to the Button's toggle state and TextEditor content. Refactored the atomic operation functions to live inside a class called Atomic, and the byte order functions into a class called ByteOrder.
This commit is contained in:
parent
3ddbc82f9f
commit
18ffeba9da
64 changed files with 3721 additions and 3609 deletions
|
|
@ -26,186 +26,183 @@
|
|||
#ifndef __JUCE_ATOMIC_JUCEHEADER__
|
||||
#define __JUCE_ATOMIC_JUCEHEADER__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// Atomic increment/decrement operations..
|
||||
/** Contains static functions for thread-safe atomic operations.
|
||||
*/
|
||||
class JUCE_API Atomic
|
||||
{
|
||||
public:
|
||||
/** Increments an integer in a thread-safe way. */
|
||||
static void increment (int& variable);
|
||||
|
||||
/** Increments an integer in a thread-safe way and returns its new value. */
|
||||
static int incrementAndReturn (int& variable);
|
||||
|
||||
/** Decrements an integer in a thread-safe way. */
|
||||
static void decrement (int& variable);
|
||||
|
||||
/** Decrements an integer in a thread-safe way and returns its new value. */
|
||||
static int decrementAndReturn (int& variable);
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if (JUCE_MAC || JUCE_IPHONE) && ! DOXYGEN
|
||||
#if (JUCE_MAC || JUCE_IPHONE) // Mac and iPhone...
|
||||
|
||||
//==============================================================================
|
||||
#include <libkern/OSAtomic.h>
|
||||
static forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); }
|
||||
static forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); }
|
||||
static forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); }
|
||||
static forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); }
|
||||
#include <libkern/OSAtomic.h>
|
||||
inline void Atomic::increment (int& variable) { OSAtomicIncrement32 ((int32_t*) &variable); }
|
||||
inline int Atomic::incrementAndReturn (int& variable) { return OSAtomicIncrement32 ((int32_t*) &variable); }
|
||||
inline void Atomic::decrement (int& variable) { OSAtomicDecrement32 ((int32_t*) &variable); }
|
||||
inline int Atomic::decrementAndReturn (int& variable) { return OSAtomicDecrement32 ((int32_t*) &variable); }
|
||||
|
||||
#elif JUCE_GCC
|
||||
//==============================================================================
|
||||
#if JUCE_USE_GCC_ATOMIC_INTRINSICS
|
||||
forcedinline void atomicIncrement (int& variable) throw() { __sync_add_and_fetch (&variable, 1); }
|
||||
forcedinline int atomicIncrementAndReturn (int& variable) throw() { return __sync_add_and_fetch (&variable, 1); }
|
||||
forcedinline void atomicDecrement (int& variable) throw() { __sync_add_and_fetch (&variable, -1); }
|
||||
forcedinline int atomicDecrementAndReturn (int& variable) throw() { return __sync_add_and_fetch (&variable, -1); }
|
||||
#else
|
||||
//==============================================================================
|
||||
/** Increments an integer in a thread-safe way. */
|
||||
forcedinline void atomicIncrement (int& variable) throw()
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
#if JUCE_64BIT
|
||||
"lock incl (%%rax)"
|
||||
:
|
||||
: "a" (&variable)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock incl %0"
|
||||
: "=m" (variable)
|
||||
: "m" (variable));
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_USE_GCC_ATOMIC_INTRINSICS // Linux with intrinsics...
|
||||
|
||||
inline void Atomic::increment (int& variable) { __sync_add_and_fetch (&variable, 1); }
|
||||
inline int Atomic::incrementAndReturn (int& variable) { return __sync_add_and_fetch (&variable, 1); }
|
||||
inline void Atomic::decrement (int& variable) { __sync_add_and_fetch (&variable, -1); }
|
||||
inline int Atomic::decrementAndReturn (int& variable) { return __sync_add_and_fetch (&variable, -1); }
|
||||
|
||||
//==============================================================================
|
||||
#else // Linux without intrinsics...
|
||||
|
||||
inline void Atomic::increment (int& variable)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
#if JUCE_64BIT
|
||||
"lock incl (%%rax)"
|
||||
:
|
||||
: "a" (&variable)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock incl %0"
|
||||
: "=m" (variable)
|
||||
: "m" (variable));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int Atomic::incrementAndReturn (int& variable)
|
||||
{
|
||||
int result;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
#if JUCE_64BIT
|
||||
"lock xaddl %%ebx, (%%rax) \n\
|
||||
incl %%ebx"
|
||||
: "=b" (result)
|
||||
: "a" (&variable), "b" (1)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock xaddl %%eax, (%%ecx) \n\
|
||||
incl %%eax"
|
||||
: "=a" (result)
|
||||
: "c" (&variable), "a" (1)
|
||||
: "memory");
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void Atomic::decrement (int& variable)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
#if JUCE_64BIT
|
||||
"lock decl (%%rax)"
|
||||
:
|
||||
: "a" (&variable)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock decl %0"
|
||||
: "=m" (variable)
|
||||
: "m" (variable));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int Atomic::decrementAndReturn (int& variable)
|
||||
{
|
||||
int result;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
#if JUCE_64BIT
|
||||
"lock xaddl %%ebx, (%%rax) \n\
|
||||
decl %%ebx"
|
||||
: "=b" (result)
|
||||
: "a" (&variable), "b" (-1)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock xaddl %%eax, (%%ecx) \n\
|
||||
decl %%eax"
|
||||
: "=a" (result)
|
||||
: "c" (&variable), "a" (-1)
|
||||
: "memory");
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
#elif JUCE_USE_INTRINSICS // Windows with intrinsics...
|
||||
|
||||
#pragma intrinsic (_InterlockedIncrement)
|
||||
#pragma intrinsic (_InterlockedDecrement)
|
||||
|
||||
inline void Atomic::increment (int& variable) { _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
|
||||
inline int Atomic::incrementAndReturn (int& variable) { return _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
|
||||
inline void Atomic::decrement (int& variable) { _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
|
||||
inline int Atomic::decrementAndReturn (int& variable) { return _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
|
||||
|
||||
//==============================================================================
|
||||
#else // Windows without intrinsics...
|
||||
|
||||
inline void Atomic::increment (int& variable)
|
||||
{
|
||||
__asm {
|
||||
mov ecx, dword ptr [variable]
|
||||
lock inc dword ptr [ecx]
|
||||
}
|
||||
}
|
||||
|
||||
inline int Atomic::incrementAndReturn (int& variable)
|
||||
{
|
||||
int result;
|
||||
|
||||
__asm {
|
||||
mov ecx, dword ptr [variable]
|
||||
mov eax, 1
|
||||
lock xadd dword ptr [ecx], eax
|
||||
inc eax
|
||||
mov result, eax
|
||||
}
|
||||
|
||||
/** Increments an integer in a thread-safe way and returns the incremented value. */
|
||||
forcedinline int atomicIncrementAndReturn (int& variable) throw()
|
||||
{
|
||||
int result;
|
||||
return result;
|
||||
}
|
||||
|
||||
__asm__ __volatile__ (
|
||||
#if JUCE_64BIT
|
||||
"lock xaddl %%ebx, (%%rax) \n\
|
||||
incl %%ebx"
|
||||
: "=b" (result)
|
||||
: "a" (&variable), "b" (1)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock xaddl %%eax, (%%ecx) \n\
|
||||
incl %%eax"
|
||||
: "=a" (result)
|
||||
: "c" (&variable), "a" (1)
|
||||
: "memory");
|
||||
#endif
|
||||
inline void Atomic::decrement (int& variable)
|
||||
{
|
||||
__asm {
|
||||
mov ecx, dword ptr [variable]
|
||||
lock dec dword ptr [ecx]
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
inline int Atomic::decrementAndReturn (int& variable)
|
||||
{
|
||||
int result;
|
||||
|
||||
__asm {
|
||||
mov ecx, dword ptr [variable]
|
||||
mov eax, -1
|
||||
lock xadd dword ptr [ecx], eax
|
||||
dec eax
|
||||
mov result, eax
|
||||
}
|
||||
|
||||
/** Decrememts an integer in a thread-safe way. */
|
||||
forcedinline void atomicDecrement (int& variable) throw()
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
#if JUCE_64BIT
|
||||
"lock decl (%%rax)"
|
||||
:
|
||||
: "a" (&variable)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock decl %0"
|
||||
: "=m" (variable)
|
||||
: "m" (variable));
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Decrememts an integer in a thread-safe way and returns the incremented value. */
|
||||
forcedinline int atomicDecrementAndReturn (int& variable) throw()
|
||||
{
|
||||
int result;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
#if JUCE_64BIT
|
||||
"lock xaddl %%ebx, (%%rax) \n\
|
||||
decl %%ebx"
|
||||
: "=b" (result)
|
||||
: "a" (&variable), "b" (-1)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock xaddl %%eax, (%%ecx) \n\
|
||||
decl %%eax"
|
||||
: "=a" (result)
|
||||
: "c" (&variable), "a" (-1)
|
||||
: "memory");
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif JUCE_USE_INTRINSICS
|
||||
//==============================================================================
|
||||
#pragma intrinsic (_InterlockedIncrement)
|
||||
#pragma intrinsic (_InterlockedDecrement)
|
||||
|
||||
/** Increments an integer in a thread-safe way. */
|
||||
forcedinline void __fastcall atomicIncrement (int& variable) throw()
|
||||
{
|
||||
_InterlockedIncrement (reinterpret_cast <volatile long*> (&variable));
|
||||
}
|
||||
|
||||
/** Increments an integer in a thread-safe way and returns the incremented value. */
|
||||
forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw()
|
||||
{
|
||||
return _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable));
|
||||
}
|
||||
|
||||
/** Decrememts an integer in a thread-safe way. */
|
||||
forcedinline void __fastcall atomicDecrement (int& variable) throw()
|
||||
{
|
||||
_InterlockedDecrement (reinterpret_cast <volatile long*> (&variable));
|
||||
}
|
||||
|
||||
/** Decrememts an integer in a thread-safe way and returns the incremented value. */
|
||||
forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw()
|
||||
{
|
||||
return _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable));
|
||||
}
|
||||
#else
|
||||
//==============================================================================
|
||||
/** Increments an integer in a thread-safe way. */
|
||||
forcedinline void __fastcall atomicIncrement (int& variable) throw()
|
||||
{
|
||||
__asm {
|
||||
mov ecx, dword ptr [variable]
|
||||
lock inc dword ptr [ecx]
|
||||
}
|
||||
}
|
||||
|
||||
/** Increments an integer in a thread-safe way and returns the incremented value. */
|
||||
forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw()
|
||||
{
|
||||
int result;
|
||||
|
||||
__asm {
|
||||
mov ecx, dword ptr [variable]
|
||||
mov eax, 1
|
||||
lock xadd dword ptr [ecx], eax
|
||||
inc eax
|
||||
mov result, eax
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Decrememts an integer in a thread-safe way. */
|
||||
forcedinline void __fastcall atomicDecrement (int& variable) throw()
|
||||
{
|
||||
__asm {
|
||||
mov ecx, dword ptr [variable]
|
||||
lock dec dword ptr [ecx]
|
||||
}
|
||||
}
|
||||
|
||||
/** Decrememts an integer in a thread-safe way and returns the incremented value. */
|
||||
forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw()
|
||||
{
|
||||
int result;
|
||||
|
||||
__asm {
|
||||
mov ecx, dword ptr [variable]
|
||||
mov eax, -1
|
||||
lock xadd dword ptr [ecx], eax
|
||||
dec eax
|
||||
mov result, eax
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __JUCE_ATOMIC_JUCEHEADER__
|
||||
|
|
|
|||
174
src/core/juce_ByteOrder.h
Normal file
174
src/core/juce_ByteOrder.h
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-9 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE 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.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCE_BYTEORDER_JUCEHEADER__
|
||||
#define __JUCE_BYTEORDER_JUCEHEADER__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Contains static methods for converting the byte order between different
|
||||
endiannesses.
|
||||
*/
|
||||
class JUCE_API ByteOrder
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Swaps the upper and lower bytes of a 16-bit integer. */
|
||||
static uint16 swap (uint16 value);
|
||||
|
||||
/** Reverses the order of the 4 bytes in a 32-bit integer. */
|
||||
static uint32 swap (uint32 value);
|
||||
|
||||
/** Reverses the order of the 8 bytes in a 64-bit integer. */
|
||||
static uint64 swap (uint64 value);
|
||||
|
||||
//==============================================================================
|
||||
/** Swaps the byte order of a 16-bit int if the CPU is big-endian */
|
||||
static uint16 swapIfBigEndian (const uint16 value);
|
||||
|
||||
/** Swaps the byte order of a 32-bit int if the CPU is big-endian */
|
||||
static uint32 swapIfBigEndian (const uint32 value);
|
||||
|
||||
/** Swaps the byte order of a 64-bit int if the CPU is big-endian */
|
||||
static uint64 swapIfBigEndian (const uint64 value);
|
||||
|
||||
/** Swaps the byte order of a 16-bit int if the CPU is little-endian */
|
||||
static uint16 swapIfLittleEndian (const uint16 value);
|
||||
|
||||
/** Swaps the byte order of a 32-bit int if the CPU is little-endian */
|
||||
static uint32 swapIfLittleEndian (const uint32 value);
|
||||
|
||||
/** Swaps the byte order of a 64-bit int if the CPU is little-endian */
|
||||
static uint64 swapIfLittleEndian (const uint64 value);
|
||||
|
||||
//==============================================================================
|
||||
/** Turns 4 bytes into a little-endian integer. */
|
||||
static uint32 littleEndianInt (const char* const bytes);
|
||||
|
||||
/** Turns 2 bytes into a little-endian integer. */
|
||||
static uint16 littleEndianShort (const char* const bytes);
|
||||
|
||||
/** Turns 4 bytes into a big-endian integer. */
|
||||
static uint32 bigEndianInt (const char* const bytes);
|
||||
|
||||
/** Turns 2 bytes into a big-endian integer. */
|
||||
static uint16 bigEndianShort (const char* const bytes);
|
||||
|
||||
//==============================================================================
|
||||
/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
|
||||
static int littleEndian24Bit (const char* const bytes);
|
||||
|
||||
/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
|
||||
static int bigEndian24Bit (const char* const bytes);
|
||||
|
||||
/** Copies a 24-bit number to 3 little-endian bytes. */
|
||||
static void littleEndian24BitToChars (const int value, char* const destBytes);
|
||||
|
||||
/** Copies a 24-bit number to 3 big-endian bytes. */
|
||||
static void bigEndian24BitToChars (const int value, char* const destBytes);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the current CPU is big-endian. */
|
||||
static bool isBigEndian();
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_USE_INTRINSICS
|
||||
#pragma intrinsic (_byteswap_ulong)
|
||||
#endif
|
||||
|
||||
inline uint16 ByteOrder::swap (uint16 n)
|
||||
{
|
||||
#if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic!
|
||||
return (uint16) _byteswap_ushort (n);
|
||||
#else
|
||||
return (uint16) ((n << 8) | (n >> 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32 ByteOrder::swap (uint32 n)
|
||||
{
|
||||
#if JUCE_MAC || JUCE_IPHONE
|
||||
return OSSwapInt32 (n);
|
||||
#elif JUCE_GCC
|
||||
asm("bswap %%eax" : "=a"(n) : "a"(n));
|
||||
return n;
|
||||
#elif JUCE_USE_INTRINSICS
|
||||
return _byteswap_ulong (n);
|
||||
#else
|
||||
__asm {
|
||||
mov eax, n
|
||||
bswap eax
|
||||
mov n, eax
|
||||
}
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint64 ByteOrder::swap (uint64 value)
|
||||
{
|
||||
#if JUCE_MAC || JUCE_IPHONE
|
||||
return OSSwapInt64 (value);
|
||||
#elif JUCE_USE_INTRINSICS
|
||||
return _byteswap_uint64 (value);
|
||||
#else
|
||||
return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if JUCE_LITTLE_ENDIAN
|
||||
inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) { return v; }
|
||||
inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) { return v; }
|
||||
inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) { return v; }
|
||||
inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) { return swap (v); }
|
||||
inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) { return swap (v); }
|
||||
inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) { return swap (v); }
|
||||
inline uint32 ByteOrder::littleEndianInt (const char* const bytes) { return *(uint32*) bytes; }
|
||||
inline uint16 ByteOrder::littleEndianShort (const char* const bytes) { return *(uint16*) bytes; }
|
||||
inline uint32 ByteOrder::bigEndianInt (const char* const bytes) { return swap (*(uint32*) bytes); }
|
||||
inline uint16 ByteOrder::bigEndianShort (const char* const bytes) { return swap (*(uint16*) bytes); }
|
||||
inline bool ByteOrder::isBigEndian() { return false; }
|
||||
#else
|
||||
inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) { return swap (v); }
|
||||
inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) { return swap (v); }
|
||||
inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) { return swap (v); }
|
||||
inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) { return v; }
|
||||
inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) { return v; }
|
||||
inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) { return v; }
|
||||
inline uint32 ByteOrder::littleEndianInt (const char* const bytes) { return swap (*(uint32*) bytes); }
|
||||
inline uint16 ByteOrder::littleEndianShort (const char* const bytes) { return swap (*(uint16*) bytes); }
|
||||
inline uint32 ByteOrder::bigEndianInt (const char* const bytes) { return *(uint32*) bytes; }
|
||||
inline uint16 ByteOrder::bigEndianShort (const char* const bytes) { return *(uint16*) bytes; }
|
||||
inline bool ByteOrder::isBigEndian() { return true; }
|
||||
#endif
|
||||
|
||||
inline int ByteOrder::littleEndian24Bit (const char* const bytes) { return (((int) bytes[2]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[0]); }
|
||||
inline int ByteOrder::bigEndian24Bit (const char* const bytes) { return (((int) bytes[0]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[2]); }
|
||||
inline void ByteOrder::littleEndian24BitToChars (const int value, char* const destBytes) { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); }
|
||||
inline void ByteOrder::bigEndian24BitToChars (const int value, char* const destBytes) { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); }
|
||||
|
||||
|
||||
#endif // __JUCE_BYTEORDER_JUCEHEADER__
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-9 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE 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.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__
|
||||
#define __JUCE_DATACONVERSIONS_JUCEHEADER__
|
||||
|
||||
#if JUCE_USE_INTRINSICS
|
||||
#pragma intrinsic (_byteswap_ulong)
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// Endianness conversions..
|
||||
|
||||
#if JUCE_IPHONE
|
||||
// a gcc compiler error seems to mean that these functions only work properly
|
||||
// on the iPhone if they are declared static..
|
||||
static forcedinline uint32 swapByteOrder (uint32 n) throw();
|
||||
static inline uint16 swapByteOrder (const uint16 n) throw();
|
||||
static inline uint64 swapByteOrder (const uint64 value) throw();
|
||||
#endif
|
||||
|
||||
/** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */
|
||||
forcedinline uint32 swapByteOrder (uint32 n) throw()
|
||||
{
|
||||
#if JUCE_MAC || JUCE_IPHONE
|
||||
// Mac version
|
||||
return OSSwapInt32 (n);
|
||||
#elif JUCE_GCC
|
||||
// Inpenetrable GCC version..
|
||||
asm("bswap %%eax" : "=a"(n) : "a"(n));
|
||||
return n;
|
||||
#elif JUCE_USE_INTRINSICS
|
||||
// Win32 intrinsics version..
|
||||
return _byteswap_ulong (n);
|
||||
#else
|
||||
// Win32 version..
|
||||
__asm {
|
||||
mov eax, n
|
||||
bswap eax
|
||||
mov n, eax
|
||||
}
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Swaps the byte-order of a 16-bit short. */
|
||||
inline uint16 swapByteOrder (const uint16 n) throw()
|
||||
{
|
||||
#if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic!
|
||||
// Win32 intrinsics version..
|
||||
return (uint16) _byteswap_ushort (n);
|
||||
#else
|
||||
return (uint16) ((n << 8) | (n >> 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint64 swapByteOrder (const uint64 value) throw()
|
||||
{
|
||||
#if JUCE_MAC || JUCE_IPHONE
|
||||
return OSSwapInt64 (value);
|
||||
#elif JUCE_USE_INTRINSICS
|
||||
return _byteswap_uint64 (value);
|
||||
#else
|
||||
return (((int64) swapByteOrder ((uint32) value)) << 32)
|
||||
| swapByteOrder ((uint32) (value >> 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if JUCE_LITTLE_ENDIAN
|
||||
/** Swaps the byte order of a 16-bit int if the CPU is big-endian */
|
||||
inline uint16 swapIfBigEndian (const uint16 v) throw() { return v; }
|
||||
/** Swaps the byte order of a 32-bit int if the CPU is big-endian */
|
||||
inline uint32 swapIfBigEndian (const uint32 v) throw() { return v; }
|
||||
/** Swaps the byte order of a 64-bit int if the CPU is big-endian */
|
||||
inline uint64 swapIfBigEndian (const uint64 v) throw() { return v; }
|
||||
|
||||
/** Swaps the byte order of a 16-bit int if the CPU is little-endian */
|
||||
inline uint16 swapIfLittleEndian (const uint16 v) throw() { return swapByteOrder (v); }
|
||||
/** Swaps the byte order of a 32-bit int if the CPU is little-endian */
|
||||
inline uint32 swapIfLittleEndian (const uint32 v) throw() { return swapByteOrder (v); }
|
||||
/** Swaps the byte order of a 64-bit int if the CPU is little-endian */
|
||||
inline uint64 swapIfLittleEndian (const uint64 v) throw() { return swapByteOrder (v); }
|
||||
|
||||
/** Turns 4 bytes into a little-endian integer. */
|
||||
inline uint32 littleEndianInt (const char* const bytes) throw() { return *(uint32*) bytes; }
|
||||
/** Turns 2 bytes into a little-endian integer. */
|
||||
inline uint16 littleEndianShort (const char* const bytes) throw() { return *(uint16*) bytes; }
|
||||
|
||||
/** Turns 4 bytes into a big-endian integer. */
|
||||
inline uint32 bigEndianInt (const char* const bytes) throw() { return swapByteOrder (*(uint32*) bytes); }
|
||||
/** Turns 2 bytes into a big-endian integer. */
|
||||
inline uint16 bigEndianShort (const char* const bytes) throw() { return swapByteOrder (*(uint16*) bytes); }
|
||||
|
||||
#else
|
||||
/** Swaps the byte order of a 16-bit int if the CPU is big-endian */
|
||||
inline uint16 swapIfBigEndian (const uint16 v) throw() { return swapByteOrder (v); }
|
||||
/** Swaps the byte order of a 32-bit int if the CPU is big-endian */
|
||||
inline uint32 swapIfBigEndian (const uint32 v) throw() { return swapByteOrder (v); }
|
||||
/** Swaps the byte order of a 64-bit int if the CPU is big-endian */
|
||||
inline uint64 swapIfBigEndian (const uint64 v) throw() { return swapByteOrder (v); }
|
||||
|
||||
/** Swaps the byte order of a 16-bit int if the CPU is little-endian */
|
||||
inline uint16 swapIfLittleEndian (const uint16 v) throw() { return v; }
|
||||
/** Swaps the byte order of a 32-bit int if the CPU is little-endian */
|
||||
inline uint32 swapIfLittleEndian (const uint32 v) throw() { return v; }
|
||||
/** Swaps the byte order of a 64-bit int if the CPU is little-endian */
|
||||
inline uint64 swapIfLittleEndian (const uint64 v) throw() { return v; }
|
||||
|
||||
/** Turns 4 bytes into a little-endian integer. */
|
||||
inline uint32 littleEndianInt (const char* const bytes) throw() { return swapByteOrder (*(uint32*) bytes); }
|
||||
/** Turns 2 bytes into a little-endian integer. */
|
||||
inline uint16 littleEndianShort (const char* const bytes) throw() { return swapByteOrder (*(uint16*) bytes); }
|
||||
|
||||
/** Turns 4 bytes into a big-endian integer. */
|
||||
inline uint32 bigEndianInt (const char* const bytes) throw() { return *(uint32*) bytes; }
|
||||
/** Turns 2 bytes into a big-endian integer. */
|
||||
inline uint16 bigEndianShort (const char* const bytes) throw() { return *(uint16*) bytes; }
|
||||
#endif
|
||||
|
||||
/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
|
||||
inline int littleEndian24Bit (const char* const bytes) throw() { return (((int) bytes[2]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[0]); }
|
||||
/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
|
||||
inline int bigEndian24Bit (const char* const bytes) throw() { return (((int) bytes[0]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[2]); }
|
||||
|
||||
/** Copies a 24-bit number to 3 little-endian bytes. */
|
||||
inline void littleEndian24BitToChars (const int value, char* const destBytes) throw() { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); }
|
||||
/** Copies a 24-bit number to 3 big-endian bytes. */
|
||||
inline void bigEndian24BitToChars (const int value, char* const destBytes) throw() { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is faster than using the normal c++ cast to convert a double to an int, and
|
||||
it will round the value to the nearest integer, rather than rounding it down
|
||||
like the normal cast does.
|
||||
|
||||
Note that this routine gets its speed at the expense of some accuracy, and when
|
||||
rounding values whose floating point component is exactly 0.5, odd numbers and
|
||||
even numbers will be rounded up or down differently. For a more accurate conversion,
|
||||
see roundDoubleToIntAccurate().
|
||||
*/
|
||||
inline int roundDoubleToInt (const double value) throw()
|
||||
{
|
||||
union { int asInt[2]; double asDouble; } n;
|
||||
n.asDouble = value + 6755399441055744.0;
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return n.asInt [1];
|
||||
#else
|
||||
return n.asInt [0];
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works
|
||||
fine for values above zero, but negative numbers are rounded the wrong way.
|
||||
*/
|
||||
inline int roundDoubleToIntAccurate (const double value) throw()
|
||||
{
|
||||
return roundDoubleToInt (value + 1.5e-8);
|
||||
}
|
||||
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is faster than using the normal c++ cast to convert a float to an int, and
|
||||
it will round the value to the nearest integer, rather than rounding it down
|
||||
like the normal cast does.
|
||||
|
||||
Note that this routine gets its speed at the expense of some accuracy, and when
|
||||
rounding values whose floating point component is exactly 0.5, odd numbers and
|
||||
even numbers will be rounded up or down differently.
|
||||
*/
|
||||
inline int roundFloatToInt (const float value) throw()
|
||||
{
|
||||
union { int asInt[2]; double asDouble; } n;
|
||||
n.asDouble = value + 6755399441055744.0;
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return n.asInt [1];
|
||||
#else
|
||||
return n.asInt [0];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif // __JUCE_DATACONVERSIONS_JUCEHEADER__
|
||||
|
|
@ -170,7 +170,7 @@ inline double jmin (const double a, const double b, const double c, const double
|
|||
and upperLimit (inclusive)
|
||||
@see jlimit0To, jmin, jmax
|
||||
*/
|
||||
template <class Type>
|
||||
template <typename Type>
|
||||
inline Type jlimit (const Type lowerLimit,
|
||||
const Type upperLimit,
|
||||
const Type valueToConstrain) throw()
|
||||
|
|
@ -185,8 +185,8 @@ inline Type jlimit (const Type lowerLimit,
|
|||
//==============================================================================
|
||||
/** Handy function to swap two values over.
|
||||
*/
|
||||
template <class Type>
|
||||
inline void swapVariables (Type& variable1, Type& variable2) throw()
|
||||
template <typename Type>
|
||||
inline void swapVariables (Type& variable1, Type& variable2)
|
||||
{
|
||||
const Type tempVal = variable1;
|
||||
variable1 = variable2;
|
||||
|
|
@ -207,25 +207,33 @@ inline void swapVariables (Type& variable1, Type& variable2) throw()
|
|||
//==============================================================================
|
||||
// Some useful maths functions that aren't always present with all compilers and build settings.
|
||||
|
||||
#if JUCE_WINDOWS || defined (DOXYGEN)
|
||||
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
||||
versions of these functions of various platforms and compilers. */
|
||||
forcedinline double juce_hypot (double a, double b) { return _hypot (a, b); }
|
||||
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
||||
versions of these functions of various platforms and compilers. */
|
||||
inline double juce_hypot (double a, double b)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
return _hypot (a, b);
|
||||
#else
|
||||
return hypot (a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
||||
versions of these functions of various platforms and compilers. */
|
||||
forcedinline float juce_hypotf (float a, float b) { return (float) _hypot (a, b); }
|
||||
#else
|
||||
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
||||
versions of these functions of various platforms and compilers. */
|
||||
forcedinline double juce_hypot (double a, double b) { return hypot (a, b); }
|
||||
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
||||
versions of these functions of various platforms and compilers. */
|
||||
inline float juce_hypotf (float a, float b)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
return (float) _hypot (a, b);
|
||||
#else
|
||||
return hypotf (a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
||||
versions of these functions of various platforms and compilers. */
|
||||
forcedinline float juce_hypotf (float a, float b) { return hypotf (a, b); }
|
||||
#endif
|
||||
|
||||
inline int64 abs64 (const int64 n) throw() { return (n >= 0) ? n : -n; }
|
||||
/** 64-bit abs function. */
|
||||
inline int64 abs64 (const int64 n)
|
||||
{
|
||||
return (n >= 0) ? n : -n;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -243,17 +251,74 @@ const float float_Pi = 3.14159265358979323846f;
|
|||
|
||||
|
||||
//==============================================================================
|
||||
/** The isfinite() method seems to vary greatly between platforms, so this is a
|
||||
platform-independent macro for it.
|
||||
/** The isfinite() method seems to vary between platforms, so this is a
|
||||
platform-independent function for it.
|
||||
*/
|
||||
#if JUCE_LINUX || JUCE_MAC || JUCE_IPHONE
|
||||
#define juce_isfinite(v) std::isfinite(v)
|
||||
#elif JUCE_WINDOWS && ! defined (isfinite)
|
||||
#define juce_isfinite(v) _finite(v)
|
||||
#else
|
||||
#define juce_isfinite(v) isfinite(v)
|
||||
#endif
|
||||
template <typename FloatingPointType>
|
||||
inline bool juce_isfinite (FloatingPointType value)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
return _finite (value);
|
||||
#else
|
||||
return std::isfinite (value);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is faster than using the normal c++ cast to convert a double to an int, and
|
||||
it will round the value to the nearest integer, rather than rounding it down
|
||||
like the normal cast does.
|
||||
|
||||
Note that this routine gets its speed at the expense of some accuracy, and when
|
||||
rounding values whose floating point component is exactly 0.5, odd numbers and
|
||||
even numbers will be rounded up or down differently. For a more accurate conversion,
|
||||
see roundDoubleToIntAccurate().
|
||||
*/
|
||||
inline int roundDoubleToInt (const double value) throw()
|
||||
{
|
||||
union { int asInt[2]; double asDouble; } n;
|
||||
n.asDouble = value + 6755399441055744.0;
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return n.asInt [1];
|
||||
#else
|
||||
return n.asInt [0];
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works
|
||||
fine for values above zero, but negative numbers are rounded the wrong way.
|
||||
*/
|
||||
inline int roundDoubleToIntAccurate (const double value) throw()
|
||||
{
|
||||
return roundDoubleToInt (value + 1.5e-8);
|
||||
}
|
||||
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is faster than using the normal c++ cast to convert a float to an int, and
|
||||
it will round the value to the nearest integer, rather than rounding it down
|
||||
like the normal cast does.
|
||||
|
||||
Note that this routine gets its speed at the expense of some accuracy, and when
|
||||
rounding values whose floating point component is exactly 0.5, odd numbers and
|
||||
even numbers will be rounded up or down differently.
|
||||
*/
|
||||
inline int roundFloatToInt (const float value) throw()
|
||||
{
|
||||
union { int asInt[2]; double asDouble; } n;
|
||||
n.asDouble = value + 6755399441055744.0;
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return n.asInt [1];
|
||||
#else
|
||||
return n.asInt [0];
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@
|
|||
|
||||
//==============================================================================
|
||||
#if JUCE_MSVC
|
||||
/** This is a compiler-indenpendent way of declaring a variable as being thread-local.
|
||||
/** This is a compiler-independent way of declaring a variable as being thread-local.
|
||||
|
||||
E.g.
|
||||
@code
|
||||
|
|
|
|||
|
|
@ -48,13 +48,11 @@ void Random::setSeed (const int64 newSeed) throw()
|
|||
|
||||
void Random::setSeedRandomly()
|
||||
{
|
||||
Random r1 (Time::getMillisecondCounter());
|
||||
Random r2 (Time::getHighResolutionTicks());
|
||||
Random r3 (Time::getHighResolutionTicksPerSecond());
|
||||
Random r4 (Time::currentTimeMillis());
|
||||
|
||||
setSeed (nextInt64() ^ r1.nextInt64() ^ r2.nextInt64()
|
||||
^ r3.nextInt64() ^ r4.nextInt64());
|
||||
seed ^= (int64) (pointer_sized_int) this;
|
||||
seed ^= nextInt64() ^ Time::getMillisecondCounter();
|
||||
seed ^= nextInt64() ^ Time::getHighResolutionTicks();
|
||||
seed ^= nextInt64() ^ Time::getHighResolutionTicksPerSecond();
|
||||
seed ^= nextInt64() ^ Time::currentTimeMillis();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@
|
|||
// Now include some basics that are needed by most of the Juce classes...
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
extern bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger();
|
||||
extern bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger();
|
||||
|
||||
#if JUCE_LOG_ASSERTIONS
|
||||
extern void JUCE_API juce_LogAssertion (const char* filename, const int lineNum) throw();
|
||||
|
|
@ -136,7 +136,7 @@ extern bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger();
|
|||
|
||||
#include "juce_Memory.h"
|
||||
#include "juce_MathsFunctions.h"
|
||||
#include "juce_DataConversions.h"
|
||||
#include "juce_ByteOrder.h"
|
||||
#include "juce_Logger.h"
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -63,12 +63,13 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
|
|||
// Some simple test code to keep an eye on things and make sure these functions
|
||||
// work ok on all platforms. Let me know if any of these assertions fail!
|
||||
int n = 1;
|
||||
atomicIncrement (n);
|
||||
jassert (atomicIncrementAndReturn (n) == 3);
|
||||
atomicDecrement (n);
|
||||
jassert (atomicDecrementAndReturn (n) == 1);
|
||||
Atomic::increment (n);
|
||||
jassert (Atomic::incrementAndReturn (n) == 3);
|
||||
Atomic::decrement (n);
|
||||
jassert (Atomic::decrementAndReturn (n) == 1);
|
||||
|
||||
jassert (swapByteOrder ((uint32) 0x11223344) == 0x44332211);
|
||||
jassert (ByteOrder::swap ((uint16) 0x1122) == 0x2211);
|
||||
jassert (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211);
|
||||
|
||||
// quick test to make sure the run-time lib doesn't crash on freeing a null-pointer.
|
||||
SystemStats* nullPointer = 0;
|
||||
|
|
|
|||
|
|
@ -335,28 +335,20 @@ const String Time::toString (const bool includeDate,
|
|||
|
||||
const String Time::formatted (const tchar* const format) const throw()
|
||||
{
|
||||
tchar buffer[80];
|
||||
String buffer;
|
||||
int bufferSize = 128;
|
||||
buffer.preallocateStorage (bufferSize);
|
||||
|
||||
struct tm t;
|
||||
millisToLocal (millisSinceEpoch, t);
|
||||
|
||||
if (CharacterFunctions::ftime (buffer, 79, format, &t) <= 0)
|
||||
while (CharacterFunctions::ftime ((tchar*) (const tchar*) buffer, bufferSize, format, &t) <= 0)
|
||||
{
|
||||
int bufferSize = 128;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
MemoryBlock mb (bufferSize * sizeof (tchar));
|
||||
tchar* const b = (tchar*) mb.getData();
|
||||
|
||||
if (CharacterFunctions::ftime (b, bufferSize, format, &t) > 0)
|
||||
return String (b);
|
||||
|
||||
bufferSize += 128;
|
||||
}
|
||||
bufferSize += 128;
|
||||
buffer.preallocateStorage (bufferSize);
|
||||
}
|
||||
|
||||
return String (buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue