1
0
Fork 0
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:
Julian Storer 2010-01-10 22:00:59 +00:00
parent 3ddbc82f9f
commit 18ffeba9da
64 changed files with 3721 additions and 3609 deletions

View file

@ -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
View 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__

View file

@ -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__

View file

@ -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
}
//==============================================================================

View file

@ -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

View file

@ -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();
}
//==============================================================================

View file

@ -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

View file

@ -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;

View file

@ -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;
}
//==============================================================================