diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index d085e5b3e7..3da2fe2f88 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -804,7 +804,7 @@ void Random::setSeedRandomly() Random r3 (Time::getHighResolutionTicksPerSecond()); Random r4 (Time::currentTimeMillis()); - setSeed (r1.nextInt64() ^ r2.nextInt64() + setSeed (nextInt64() ^ r1.nextInt64() ^ r2.nextInt64() ^ r3.nextInt64() ^ r4.nextInt64()); } @@ -841,10 +841,43 @@ double Random::nextDouble() throw() return ((uint32) nextInt()) / (double) 0xffffffff; } -static Random sysRand (1); +const BitArray Random::nextLargeNumber (const BitArray& maximumValue) throw() +{ + BitArray n; + + do + { + fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1); + } + while (n.compare (maximumValue) >= 0); + + return n; +} + +void Random::fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw() +{ + arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space + + while ((startBit & 31) != 0 && numBits > 0) + { + arrayToChange.setBit (startBit++, nextBool()); + --numBits; + } + + while (numBits >= 32) + { + arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt()); + startBit += 32; + numBits -= 32; + } + + while (--numBits >= 0) + arrayToChange.setBit (startBit + numBits, nextBool()); +} Random& Random::getSystemRandom() throw() { + static Random sysRand (1); return sysRand; } @@ -1123,9 +1156,10 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() juceInitialisedNonGUI = true; DBG (SystemStats::getJUCEVersion()); + Random::getSystemRandom().setSeedRandomly(); // (calling this more than once improves its randomness) juce_initialiseStrings(); SystemStats::initialiseStats(); - Random::getSystemRandom().setSeedRandomly(); + Random::getSystemRandom().setSeedRandomly(); // (calling this more than once improves its randomness) } } @@ -2395,45 +2429,6 @@ void BitArray::setBitRangeAsInt (const int startBit, int numBits, unsigned int v } } -void BitArray::fillBitsRandomly (int startBit, int numBits) throw() -{ - highestBit = jmax (highestBit, startBit + numBits); - ensureSize (((startBit + numBits) >> 5) + 1); - - while ((startBit & 31) != 0 && numBits > 0) - { - setBit (startBit++, Random::getSystemRandom().nextBool()); - - --numBits; - } - - while (numBits >= 32) - { - values [startBit >> 5] = (unsigned int) Random::getSystemRandom().nextInt(); - - startBit += 32; - numBits -= 32; - } - - while (--numBits >= 0) - { - setBit (startBit + numBits, Random::getSystemRandom().nextBool()); - } - - highestBit = getHighestBit(); -} - -void BitArray::createRandomNumber (const BitArray& maximumValue) throw() -{ - clear(); - - do - { - fillBitsRandomly (0, maximumValue.getHighestBit() + 1); - } - while (compare (maximumValue) >= 0); -} - bool BitArray::isNegative() const throw() { return negative && ! isEmpty(); @@ -4076,16 +4071,16 @@ const BitArray Primes::createProbablePrime (const int bitLength, const int* randomSeeds, int numRandomSeeds) throw() { - int defaultSeeds[8]; + int defaultSeeds [16]; if (numRandomSeeds <= 0) { randomSeeds = defaultSeeds; - numRandomSeeds = 8; + numRandomSeeds = numElementsInArray (defaultSeeds); + Random r (0); for (int j = 10; --j >= 0;) { - Random r (0); r.setSeedRandomly(); for (int i = numRandomSeeds; --i >= 0;) @@ -4101,15 +4096,14 @@ const BitArray Primes::createProbablePrime (const int bitLength, for (int i = numRandomSeeds; --i >= 0;) { - Random::getSystemRandom().setSeed (randomSeeds[i]); - BitArray p2; - p2.fillBitsRandomly (0, bitLength); + + Random r (randomSeeds[i]); + r.fillBitsRandomly (p2, 0, bitLength); + p.xorWith (p2); } - Random::getSystemRandom().setSeedRandomly(); - p.setBit (bitLength - 1); p.clearBit (0); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index c57643cf05..d2bf7fed1d 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -6991,206 +6991,444 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI(); #ifndef __JUCE_RANDOM_JUCEHEADER__ #define __JUCE_RANDOM_JUCEHEADER__ +/********* Start of inlined file: juce_BitArray.h *********/ +#ifndef __JUCE_BITARRAY_JUCEHEADER__ +#define __JUCE_BITARRAY_JUCEHEADER__ + +class MemoryBlock; + /** - A simple pseudo-random number generator. + An array of on/off bits, also usable to store large binary integers. + + A BitArray acts like an arbitrarily large integer whose bits can be set or + cleared, and some basic mathematical operations can be done on the number as + a whole. */ -class JUCE_API Random +class JUCE_API BitArray { public: - /** Creates a Random object based on a seed value. + /** Creates an empty BitArray */ + BitArray() throw(); - For a given seed value, the subsequent numbers generated by this object - will be predictable, so a good idea is to set this value based - on the time, e.g. + /** Creates a BitArray containing an integer value in its low bits. - new Random (Time::currentTimeMillis()) + The low 32 bits of the array are initialised with this value. */ - Random (const int64 seedValue) throw(); - - /** Destructor. */ - ~Random() throw(); + BitArray (const unsigned int value) throw(); - /** Returns the next random 32 bit integer. + /** Creates a BitArray containing an integer value in its low bits. - @returns a random integer from the full range 0x80000000 to 0x7fffffff + The low 32 bits of the array are initialised with the absolute value + passed in, and its sign is set to reflect the sign of the number. */ - int nextInt() throw(); + BitArray (const int value) throw(); - /** Returns the next random number, limited to a given range. + /** Creates a BitArray containing an integer value in its low bits. - @returns a random integer between 0 (inclusive) and maxValue (exclusive). + The low 64 bits of the array are initialised with the absolute value + passed in, and its sign is set to reflect the sign of the number. */ - int nextInt (const int maxValue) throw(); + BitArray (int64 value) throw(); - /** Returns the next 64-bit random number. + /** Creates a copy of another BitArray. */ + BitArray (const BitArray& other) throw(); - @returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff - */ - int64 nextInt64() throw(); + /** Destructor. */ + ~BitArray() throw(); - /** Returns the next random floating-point number. + /** Copies another BitArray onto this one. */ + const BitArray& operator= (const BitArray& other) throw(); - @returns a random value in the range 0 to 1.0 - */ - float nextFloat() throw(); + /** Two arrays are the same if the same bits are set. */ + bool operator== (const BitArray& other) const throw(); + /** Two arrays are the same if the same bits are set. */ + bool operator!= (const BitArray& other) const throw(); - /** Returns the next random floating-point number. + /** Clears all bits in the BitArray to 0. */ + void clear() throw(); - @returns a random value in the range 0 to 1.0 - */ - double nextDouble() throw(); + /** Clears a particular bit in the array. */ + void clearBit (const int bitNumber) throw(); - /** Returns the next random boolean value. + /** Sets a specified bit to 1. + + If the bit number is high, this will grow the array to accomodate it. */ - bool nextBool() throw(); + void setBit (const int bitNumber) throw(); - /** To avoid the overhead of having to create a new Random object whenever - you need a number, this is a shared application-wide object that - can be used. + /** Sets or clears a specified bit. */ + void setBit (const int bitNumber, + const bool shouldBeSet) throw(); - It's not thread-safe though, so threads should use their own Random object. + /** Sets a range of bits to be either on or off. + + @param startBit the first bit to change + @param numBits the number of bits to change + @param shouldBeSet whether to turn these bits on or off */ - static Random& getSystemRandom() throw(); + void setRange (int startBit, + int numBits, + const bool shouldBeSet) throw(); - /** Resets this Random object to a given seed value. */ - void setSeed (const int64 newSeed) throw(); + /** Inserts a bit an a given position, shifting up any bits above it. */ + void insertBit (const int bitNumber, + const bool shouldBeSet) throw(); - /** Reseeds this generator using a value generated from various semi-random system - properties like the current time, etc. + /** Returns the value of a specified bit in the array. + + If the index is out-of-range, the result will be false. */ - void setSeedRandomly(); + bool operator[] (const int bit) const throw(); - juce_UseDebuggingNewOperator + /** Returns true if no bits are set. */ + bool isEmpty() const throw(); -private: - int64 seed; -}; + /** Returns a range of bits in the array as an integer value. -#endif // __JUCE_RANDOM_JUCEHEADER__ -/********* End of inlined file: juce_Random.h *********/ + e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits. -#endif -#ifndef __JUCE_RELATIVETIME_JUCEHEADER__ + Asking for more than 32 bits isn't allowed (obviously). + */ + int getBitRangeAsInt (int startBit, int numBits) const throw(); -#endif -#ifndef __JUCE_SINGLETON_JUCEHEADER__ + /** Sets a range of bits in the array based on an integer value. -/********* Start of inlined file: juce_Singleton.h *********/ -#ifndef __JUCE_SINGLETON_JUCEHEADER__ -#define __JUCE_SINGLETON_JUCEHEADER__ + Copies the given integer into the array, starting at startBit, + and only using up to numBits of the available bits. + */ + void setBitRangeAsInt (int startBit, int numBits, + unsigned int valueToSet) throw(); -/********* Start of inlined file: juce_ScopedLock.h *********/ -#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__ -#define __JUCE_SCOPEDLOCK_JUCEHEADER__ + /** Performs a bitwise OR with another BitArray. -/** - Automatically locks and unlocks a CriticalSection object. + The result ends up in this array. + */ + void orWith (const BitArray& other) throw(); - Use one of these as a local variable to control access to a CriticalSection. + /** Performs a bitwise AND with another BitArray. - e.g. @code + The result ends up in this array. + */ + void andWith (const BitArray& other) throw(); - CriticalSection myCriticalSection; + /** Performs a bitwise XOR with another BitArray. - for (;;) - { - const ScopedLock myScopedLock (myCriticalSection); - // myCriticalSection is now locked + The result ends up in this array. + */ + void xorWith (const BitArray& other) throw(); - ...do some stuff... + /** Adds another BitArray's value to this one. - // myCriticalSection gets unlocked here. - } - @endcode + Treating the two arrays as large positive integers, this + adds them up and puts the result in this array. + */ + void add (const BitArray& other) throw(); - @see CriticalSection, ScopedUnlock -*/ -class JUCE_API ScopedLock -{ -public: + /** Subtracts another BitArray's value from this one. - /** Creates a ScopedLock. + Treating the two arrays as large positive integers, this + subtracts them and puts the result in this array. - As soon as it is created, this will lock the CriticalSection, and - when the ScopedLock object is deleted, the CriticalSection will - be unlocked. + Note that if the result should be negative, this won't be + handled correctly. + */ + void subtract (const BitArray& other) throw(); - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. + /** Multiplies another BitArray's value with this one. + + Treating the two arrays as large positive integers, this + multiplies them and puts the result in this array. */ - inline ScopedLock (const CriticalSection& lock) throw() : lock_ (lock) { lock.enter(); } + void multiplyBy (const BitArray& other) throw(); - /** Destructor. + /** Divides another BitArray's value into this one and also produces a remainder. - The CriticalSection will be unlocked when the destructor is called. + Treating the two arrays as large positive integers, this + divides this value by the other, leaving the quotient in this + array, and the remainder is copied into the other BitArray passed in. + */ + void divideBy (const BitArray& divisor, BitArray& remainder) throw(); - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! + /** Returns the largest value that will divide both this value and the one + passed-in. */ - inline ~ScopedLock() throw() { lock_.exit(); } + const BitArray findGreatestCommonDivisor (BitArray other) const throw(); -private: + /** Performs a modulo operation on this value. - const CriticalSection& lock_; + The result is stored in this value. + */ + void modulo (const BitArray& divisor) throw(); - ScopedLock (const ScopedLock&); - const ScopedLock& operator= (const ScopedLock&); -}; + /** Performs a combined exponent and modulo operation. -/** - Automatically unlocks and re-locks a CriticalSection object. + This BitArray's value becomes (this ^ exponent) % modulus. + */ + void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw(); - This is the reverse of a ScopedLock object - instead of locking the critical - section for the lifetime of this object, it unlocks it. + /** Performs an inverse modulo on the value. - Make sure you don't try to unlock critical sections that aren't actually locked! + i.e. the result is (this ^ -1) mod (modulus). + */ + void inverseModulo (const BitArray& modulus) throw(); - e.g. @code + /** Shifts a section of bits left or right. - CriticalSection myCriticalSection; + @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). + @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. + */ + void shiftBits (int howManyBitsLeft, + int startBit = 0) throw(); - for (;;) - { - const ScopedLock myScopedLock (myCriticalSection); - // myCriticalSection is now locked + /** Does a signed comparison of two BitArrays. - ... do some stuff with it locked .. + Return values are: + - 0 if the numbers are the same + - < 0 if this number is smaller than the other + - > 0 if this number is bigger than the other + */ + int compare (const BitArray& other) const throw(); - while (xyz) - { - ... do some stuff with it locked .. + /** Compares the magnitudes of two BitArrays, ignoring their signs. - const ScopedUnlock unlocker (myCriticalSection); + Return values are: + - 0 if the numbers are the same + - < 0 if this number is smaller than the other + - > 0 if this number is bigger than the other + */ + int compareAbsolute (const BitArray& other) const throw(); - // myCriticalSection is now unlocked for the remainder of this block, - // and re-locked at the end. + /** Returns true if the value is less than zero. - ...do some stuff with it unlocked ... - } + @see setNegative, negate + */ + bool isNegative() const throw(); + + /** Changes the sign of the number to be positive or negative. + + @see isNegative, negate + */ + void setNegative (const bool shouldBeNegative) throw(); + + /** Inverts the sign of the number. + + @see isNegative, setNegative + */ + void negate() throw(); + + /** Counts the total number of set bits in the array. */ + int countNumberOfSetBits() const throw(); + + /** Looks for the index of the next set bit after a given starting point. + + searches from startIndex (inclusive) upwards for the first set bit, + and returns its index. + + If no set bits are found, it returns -1. + */ + int findNextSetBit (int startIndex = 0) const throw(); + + /** Looks for the index of the next clear bit after a given starting point. + + searches from startIndex (inclusive) upwards for the first clear bit, + and returns its index. + */ + int findNextClearBit (int startIndex = 0) const throw(); + + /** Returns the index of the highest set bit in the array. + + If the array is empty, this will return -1. + */ + int getHighestBit() const throw(); + + /** Converts the array to a number string. + + Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + */ + const String toString (const int base) const throw(); + + /** Converts a number string to an array. + + Any non-valid characters will be ignored. + + Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + */ + void parseString (const String& text, + const int base) throw(); + + /** Turns the array into a block of binary data. + + The data is arranged as little-endian, so the first byte of data is the low 8 bits + of the array, and so on. + + @see loadFromMemoryBlock + */ + const MemoryBlock toMemoryBlock() const throw(); + + /** Copies a block of raw data onto this array. + + The data is arranged as little-endian, so the first byte of data is the low 8 bits + of the array, and so on. + + @see toMemoryBlock + */ + void loadFromMemoryBlock (const MemoryBlock& data) throw(); + + juce_UseDebuggingNewOperator + +private: + void ensureSize (const int numVals) throw(); + unsigned int* values; + int numValues, highestBit; + bool negative; +}; + +#endif // __JUCE_BITARRAY_JUCEHEADER__ +/********* End of inlined file: juce_BitArray.h *********/ + +/** + A simple pseudo-random number generator. +*/ +class JUCE_API Random +{ +public: + + /** Creates a Random object based on a seed value. + + For a given seed value, the subsequent numbers generated by this object + will be predictable, so a good idea is to set this value based + on the time, e.g. + + new Random (Time::currentTimeMillis()) + */ + Random (const int64 seedValue) throw(); + + /** Destructor. */ + ~Random() throw(); + + /** Returns the next random 32 bit integer. + + @returns a random integer from the full range 0x80000000 to 0x7fffffff + */ + int nextInt() throw(); + + /** Returns the next random number, limited to a given range. + + @returns a random integer between 0 (inclusive) and maxValue (exclusive). + */ + int nextInt (const int maxValue) throw(); + + /** Returns the next 64-bit random number. + + @returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff + */ + int64 nextInt64() throw(); + + /** Returns the next random floating-point number. + + @returns a random value in the range 0 to 1.0 + */ + float nextFloat() throw(); + + /** Returns the next random floating-point number. + + @returns a random value in the range 0 to 1.0 + */ + double nextDouble() throw(); + + /** Returns the next random boolean value. + */ + bool nextBool() throw(); + + /** Returns a BitArray containing a random number. + + @returns a random value in the range 0 to (maximumValue - 1). + */ + const BitArray nextLargeNumber (const BitArray& maximumValue) throw(); + + /** Sets a range of bits in a BitArray to random values. */ + void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw(); + + /** To avoid the overhead of having to create a new Random object whenever + you need a number, this is a shared application-wide object that + can be used. + + It's not thread-safe though, so threads should use their own Random object. + */ + static Random& getSystemRandom() throw(); + + /** Resets this Random object to a given seed value. */ + void setSeed (const int64 newSeed) throw(); + + /** Reseeds this generator using a value generated from various semi-random system + properties like the current time, etc. + + Because this function convolves the time with the last seed value, calling + it repeatedly will increase the randomness of the final result. + */ + void setSeedRandomly(); + + juce_UseDebuggingNewOperator + +private: + int64 seed; +}; + +#endif // __JUCE_RANDOM_JUCEHEADER__ +/********* End of inlined file: juce_Random.h *********/ + +#endif +#ifndef __JUCE_RELATIVETIME_JUCEHEADER__ + +#endif +#ifndef __JUCE_SINGLETON_JUCEHEADER__ + +/********* Start of inlined file: juce_Singleton.h *********/ +#ifndef __JUCE_SINGLETON_JUCEHEADER__ +#define __JUCE_SINGLETON_JUCEHEADER__ + +/********* Start of inlined file: juce_ScopedLock.h *********/ +#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__ +#define __JUCE_SCOPEDLOCK_JUCEHEADER__ + +/** + Automatically locks and unlocks a CriticalSection object. + + Use one of these as a local variable to control access to a CriticalSection. + + e.g. @code + + CriticalSection myCriticalSection; + + for (;;) + { + const ScopedLock myScopedLock (myCriticalSection); + // myCriticalSection is now locked + + ...do some stuff... // myCriticalSection gets unlocked here. } @endcode - @see CriticalSection, ScopedLock + @see CriticalSection, ScopedUnlock */ -class ScopedUnlock +class JUCE_API ScopedLock { public: - /** Creates a ScopedUnlock. + /** Creates a ScopedLock. - As soon as it is created, this will unlock the CriticalSection, and + As soon as it is created, this will lock the CriticalSection, and when the ScopedLock object is deleted, the CriticalSection will - be re-locked. + be unlocked. Make sure this object is created and deleted by the same thread, otherwise there are no guarantees what will happen! Best just to use it as a local stack object, rather than creating one with the new() operator. */ - inline ScopedUnlock (const CriticalSection& lock) throw() : lock_ (lock) { lock.exit(); } + inline ScopedLock (const CriticalSection& lock) throw() : lock_ (lock) { lock.enter(); } /** Destructor. @@ -7199,50 +7437,120 @@ public: Make sure this object is created and deleted by the same thread, otherwise there are no guarantees what will happen! */ - inline ~ScopedUnlock() throw() { lock_.enter(); } + inline ~ScopedLock() throw() { lock_.exit(); } private: const CriticalSection& lock_; - ScopedUnlock (const ScopedLock&); - const ScopedUnlock& operator= (const ScopedUnlock&); + ScopedLock (const ScopedLock&); + const ScopedLock& operator= (const ScopedLock&); }; -#endif // __JUCE_SCOPEDLOCK_JUCEHEADER__ -/********* End of inlined file: juce_ScopedLock.h *********/ - /** - Macro to declare member variables and methods for a singleton class. + Automatically unlocks and re-locks a CriticalSection object. - To use this, add the line juce_DeclareSingleton (MyClass, allowOnlyOneInstance) - to the class's definition. + This is the reverse of a ScopedLock object - instead of locking the critical + section for the lifetime of this object, it unlocks it. - If allowOnlyOneInstance == true, it won't allow the object to be created - more than once in the process's lifetime. + Make sure you don't try to unlock critical sections that aren't actually locked! - Then put a macro juce_ImplementSingleton (MyClass) along with the class's - implementation code. + e.g. @code - Clients can then call the static MyClass::getInstance() to get a pointer to the - singleton, or MyClass::getInstanceWithoutCreating() which may return 0 if no instance - is currently extant + CriticalSection myCriticalSection; - it's a very good idea to also add the call clearSingletonInstance() to the - destructor of the class, in case it is deleted by other means than deleteInstance() + for (;;) + { + const ScopedLock myScopedLock (myCriticalSection); + // myCriticalSection is now locked - e.g. @code + ... do some stuff with it locked .. - class MySingleton + while (xyz) { - public: - MySingleton() - { - } + ... do some stuff with it locked .. - ~MySingleton() - { - // this ensures that no dangling pointers are left when the + const ScopedUnlock unlocker (myCriticalSection); + + // myCriticalSection is now unlocked for the remainder of this block, + // and re-locked at the end. + + ...do some stuff with it unlocked ... + } + + // myCriticalSection gets unlocked here. + } + @endcode + + @see CriticalSection, ScopedLock +*/ +class ScopedUnlock +{ +public: + + /** Creates a ScopedUnlock. + + As soon as it is created, this will unlock the CriticalSection, and + when the ScopedLock object is deleted, the CriticalSection will + be re-locked. + + Make sure this object is created and deleted by the same thread, + otherwise there are no guarantees what will happen! Best just to use it + as a local stack object, rather than creating one with the new() operator. + */ + inline ScopedUnlock (const CriticalSection& lock) throw() : lock_ (lock) { lock.exit(); } + + /** Destructor. + + The CriticalSection will be unlocked when the destructor is called. + + Make sure this object is created and deleted by the same thread, + otherwise there are no guarantees what will happen! + */ + inline ~ScopedUnlock() throw() { lock_.enter(); } + +private: + + const CriticalSection& lock_; + + ScopedUnlock (const ScopedLock&); + const ScopedUnlock& operator= (const ScopedUnlock&); +}; + +#endif // __JUCE_SCOPEDLOCK_JUCEHEADER__ +/********* End of inlined file: juce_ScopedLock.h *********/ + +/** + Macro to declare member variables and methods for a singleton class. + + To use this, add the line juce_DeclareSingleton (MyClass, allowOnlyOneInstance) + to the class's definition. + + If allowOnlyOneInstance == true, it won't allow the object to be created + more than once in the process's lifetime. + + Then put a macro juce_ImplementSingleton (MyClass) along with the class's + implementation code. + + Clients can then call the static MyClass::getInstance() to get a pointer to the + singleton, or MyClass::getInstanceWithoutCreating() which may return 0 if no instance + is currently extant + + it's a very good idea to also add the call clearSingletonInstance() to the + destructor of the class, in case it is deleted by other means than deleteInstance() + + e.g. @code + + class MySingleton + { + public: + MySingleton() + { + } + + ~MySingleton() + { + // this ensures that no dangling pointers are left when the // singleton is deleted. clearSingletonInstance(); } @@ -7421,501 +7729,199 @@ private: _singletonInstance = new classname(); \ \ return _singletonInstance; \ - } \ -\ - static inline classname* getInstanceWithoutCreating() throw() \ - { \ - return _singletonInstance; \ - } \ -\ - static void deleteInstance() \ - { \ - if (_singletonInstance != 0) \ - { \ - classname* const old = _singletonInstance; \ - _singletonInstance = 0; \ - delete old; \ - } \ - } \ -\ - void clearSingletonInstance() throw() \ - { \ - if (_singletonInstance == this) \ - _singletonInstance = 0; \ - } - -/** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro. - - After adding juce_DeclareSingleton_SingleThreaded or juce_DeclareSingleton_SingleThreaded_Minimal - to the class definition, this macro has to be used somewhere in the cpp file. -*/ -#define juce_ImplementSingleton_SingleThreaded(classname) \ -\ - classname* classname::_singletonInstance = 0; - -#endif // __JUCE_SINGLETON_JUCEHEADER__ -/********* End of inlined file: juce_Singleton.h *********/ - -#endif -#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__ - -#endif -#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ - -/********* Start of inlined file: juce_SystemStats.h *********/ -#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ -#define __JUCE_SYSTEMSTATS_JUCEHEADER__ - -/** - Contains methods for finding out about the current hardware and OS configuration. -*/ -class JUCE_API SystemStats -{ -public: - - /** Returns the current version of JUCE, - - (just in case you didn't already know at compile-time.) - - See also the JUCE_VERSION, JUCE_MAJOR_VERSION and JUCE_MINOR_VERSION macros. - */ - static const String getJUCEVersion() throw(); - - /** The set of possible results of the getOperatingSystemType() method. - */ - enum OperatingSystemType - { - UnknownOS = 0, - - MacOSX = 0x1000, - Linux = 0x2000, - - Win95 = 0x4001, - Win98 = 0x4002, - WinNT351 = 0x4103, - WinNT40 = 0x4104, - Win2000 = 0x4105, - WinXP = 0x4106, - WinVista = 0x4107, - - Windows = 0x4000, /**< To test whether any version of Windows is running, - you can use the expression ((getOperatingSystemType() & Windows) != 0). */ - WindowsNT = 0x0100, /**< To test whether the platform is Windows NT or later (i.e. not Win95 or 98), - you can use the expression ((getOperatingSystemType() & WindowsNT) != 0). */ - }; - - /** Returns the type of operating system we're running on. - - @returns one of the values from the OperatingSystemType enum. - @see getOperatingSystemName - */ - static OperatingSystemType getOperatingSystemType() throw(); - - /** Returns the name of the type of operating system we're running on. - - @returns a string describing the OS type. - @see getOperatingSystemType - */ - static const String getOperatingSystemName() throw(); - - /** Returns true if the OS is 64-bit, or false for a 32-bit OS. - */ - static bool isOperatingSystem64Bit() throw(); - - // CPU and memory information.. - - /** Returns the approximate CPU speed. - - @returns the speed in megahertz, e.g. 1500, 2500, 32000 (depending on - what year you're reading this...) - */ - static int getCpuSpeedInMegaherz() throw(); - - /** Returns a string to indicate the CPU vendor. - - Might not be known on some systems. - */ - static const String getCpuVendor() throw(); - - /** Checks whether Intel MMX instructions are available. */ - static bool hasMMX() throw(); - - /** Checks whether Intel SSE instructions are available. */ - static bool hasSSE() throw(); - - /** Checks whether Intel SSE2 instructions are available. */ - static bool hasSSE2() throw(); - - /** Checks whether AMD 3DNOW instructions are available. */ - static bool has3DNow() throw(); - - /** Returns the number of CPUs. - */ - static int getNumCpus() throw(); - - /** Returns a clock-cycle tick counter, if available. - - If the machine can do it, this will return a tick-count - where each tick is one cpu clock cycle - used for profiling - code. - - @returns the tick count, or zero if not available. - */ - static int64 getClockCycleCounter() throw(); - - /** Finds out how much RAM is in the machine. - - @returns the approximate number of megabytes of memory, or zero if - something goes wrong when finding out. - */ - static int getMemorySizeInMegabytes() throw(); - - /** Returns the system page-size. - - This is only used by programmers with beards. - */ - static int getPageSize() throw(); - - /** Returns a list of MAC addresses found on this machine. - - @param addresses an array into which the MAC addresses should be copied - @param maxNum the number of elements in this array - @param littleEndian the endianness of the numbers to return. Note that - the default values of this parameter are different on - Mac/PC to avoid breaking old software that was written - before this parameter was added (when the two systems - defaulted to using different endiannesses). In newer - software you probably want to specify an explicit value - for this. - @returns the number of MAC addresses that were found - */ - static int getMACAddresses (int64* addresses, int maxNum, -#if JUCE_MAC - const bool littleEndian = true) throw(); -#else - const bool littleEndian = false) throw(); -#endif - - // not-for-public-use platform-specific method gets called at startup to initialise things. - static void initialiseStats() throw(); -}; - -#endif // __JUCE_SYSTEMSTATS_JUCEHEADER__ -/********* End of inlined file: juce_SystemStats.h *********/ - -#endif -#ifndef __JUCE_TIME_JUCEHEADER__ - -#endif -#ifndef __JUCE_ARRAY_JUCEHEADER__ - -#endif -#ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__ - -#endif -#ifndef __JUCE_BITARRAY_JUCEHEADER__ - -/********* Start of inlined file: juce_BitArray.h *********/ -#ifndef __JUCE_BITARRAY_JUCEHEADER__ -#define __JUCE_BITARRAY_JUCEHEADER__ - -class MemoryBlock; - -/** - An array of on/off bits, also usable to store large binary integers. - - A BitArray acts like an arbitrarily large integer whose bits can be set or - cleared, and some basic mathematical operations can be done on the number as - a whole. -*/ -class JUCE_API BitArray -{ -public: - - /** Creates an empty BitArray */ - BitArray() throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 32 bits of the array are initialised with this value. - */ - BitArray (const unsigned int value) throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 32 bits of the array are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BitArray (const int value) throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 64 bits of the array are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BitArray (int64 value) throw(); - - /** Creates a copy of another BitArray. */ - BitArray (const BitArray& other) throw(); - - /** Destructor. */ - ~BitArray() throw(); - - /** Copies another BitArray onto this one. */ - const BitArray& operator= (const BitArray& other) throw(); - - /** Two arrays are the same if the same bits are set. */ - bool operator== (const BitArray& other) const throw(); - /** Two arrays are the same if the same bits are set. */ - bool operator!= (const BitArray& other) const throw(); - - /** Clears all bits in the BitArray to 0. */ - void clear() throw(); - - /** Clears a particular bit in the array. */ - void clearBit (const int bitNumber) throw(); - - /** Sets a specified bit to 1. - - If the bit number is high, this will grow the array to accomodate it. - */ - void setBit (const int bitNumber) throw(); - - /** Sets or clears a specified bit. */ - void setBit (const int bitNumber, - const bool shouldBeSet) throw(); - - /** Sets a range of bits to be either on or off. - - @param startBit the first bit to change - @param numBits the number of bits to change - @param shouldBeSet whether to turn these bits on or off - */ - void setRange (int startBit, - int numBits, - const bool shouldBeSet) throw(); - - /** Inserts a bit an a given position, shifting up any bits above it. */ - void insertBit (const int bitNumber, - const bool shouldBeSet) throw(); - - /** Returns the value of a specified bit in the array. - - If the index is out-of-range, the result will be false. - */ - bool operator[] (const int bit) const throw(); - - /** Returns true if no bits are set. */ - bool isEmpty() const throw(); - - /** Returns a range of bits in the array as an integer value. - - e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits. - - Asking for more than 32 bits isn't allowed (obviously). - */ - int getBitRangeAsInt (int startBit, int numBits) const throw(); - - /** Sets a range of bits in the array based on an integer value. - - Copies the given integer into the array, starting at startBit, - and only using up to numBits of the available bits. - */ - void setBitRangeAsInt (int startBit, int numBits, - unsigned int valueToSet) throw(); - - /** Performs a bitwise OR with another BitArray. - - The result ends up in this array. - */ - void orWith (const BitArray& other) throw(); - - /** Performs a bitwise AND with another BitArray. - - The result ends up in this array. - */ - void andWith (const BitArray& other) throw(); - - /** Performs a bitwise XOR with another BitArray. + } \ +\ + static inline classname* getInstanceWithoutCreating() throw() \ + { \ + return _singletonInstance; \ + } \ +\ + static void deleteInstance() \ + { \ + if (_singletonInstance != 0) \ + { \ + classname* const old = _singletonInstance; \ + _singletonInstance = 0; \ + delete old; \ + } \ + } \ +\ + void clearSingletonInstance() throw() \ + { \ + if (_singletonInstance == this) \ + _singletonInstance = 0; \ + } - The result ends up in this array. - */ - void xorWith (const BitArray& other) throw(); +/** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro. - /** Adds another BitArray's value to this one. + After adding juce_DeclareSingleton_SingleThreaded or juce_DeclareSingleton_SingleThreaded_Minimal + to the class definition, this macro has to be used somewhere in the cpp file. +*/ +#define juce_ImplementSingleton_SingleThreaded(classname) \ +\ + classname* classname::_singletonInstance = 0; - Treating the two arrays as large positive integers, this - adds them up and puts the result in this array. - */ - void add (const BitArray& other) throw(); +#endif // __JUCE_SINGLETON_JUCEHEADER__ +/********* End of inlined file: juce_Singleton.h *********/ - /** Subtracts another BitArray's value from this one. +#endif +#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__ - Treating the two arrays as large positive integers, this - subtracts them and puts the result in this array. +#endif +#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ - Note that if the result should be negative, this won't be - handled correctly. - */ - void subtract (const BitArray& other) throw(); +/********* Start of inlined file: juce_SystemStats.h *********/ +#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ +#define __JUCE_SYSTEMSTATS_JUCEHEADER__ - /** Multiplies another BitArray's value with this one. +/** + Contains methods for finding out about the current hardware and OS configuration. +*/ +class JUCE_API SystemStats +{ +public: - Treating the two arrays as large positive integers, this - multiplies them and puts the result in this array. - */ - void multiplyBy (const BitArray& other) throw(); + /** Returns the current version of JUCE, - /** Divides another BitArray's value into this one and also produces a remainder. + (just in case you didn't already know at compile-time.) - Treating the two arrays as large positive integers, this - divides this value by the other, leaving the quotient in this - array, and the remainder is copied into the other BitArray passed in. + See also the JUCE_VERSION, JUCE_MAJOR_VERSION and JUCE_MINOR_VERSION macros. */ - void divideBy (const BitArray& divisor, BitArray& remainder) throw(); + static const String getJUCEVersion() throw(); - /** Returns the largest value that will divide both this value and the one - passed-in. + /** The set of possible results of the getOperatingSystemType() method. */ - const BitArray findGreatestCommonDivisor (BitArray other) const throw(); - - /** Performs a modulo operation on this value. + enum OperatingSystemType + { + UnknownOS = 0, - The result is stored in this value. - */ - void modulo (const BitArray& divisor) throw(); + MacOSX = 0x1000, + Linux = 0x2000, - /** Performs a combined exponent and modulo operation. + Win95 = 0x4001, + Win98 = 0x4002, + WinNT351 = 0x4103, + WinNT40 = 0x4104, + Win2000 = 0x4105, + WinXP = 0x4106, + WinVista = 0x4107, - This BitArray's value becomes (this ^ exponent) % modulus. - */ - void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw(); + Windows = 0x4000, /**< To test whether any version of Windows is running, + you can use the expression ((getOperatingSystemType() & Windows) != 0). */ + WindowsNT = 0x0100, /**< To test whether the platform is Windows NT or later (i.e. not Win95 or 98), + you can use the expression ((getOperatingSystemType() & WindowsNT) != 0). */ + }; - /** Performs an inverse modulo on the value. + /** Returns the type of operating system we're running on. - i.e. the result is (this ^ -1) mod (modulus). + @returns one of the values from the OperatingSystemType enum. + @see getOperatingSystemName */ - void inverseModulo (const BitArray& modulus) throw(); + static OperatingSystemType getOperatingSystemType() throw(); - /** Shifts a section of bits left or right. + /** Returns the name of the type of operating system we're running on. - @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). - @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. + @returns a string describing the OS type. + @see getOperatingSystemType */ - void shiftBits (int howManyBitsLeft, - int startBit = 0) throw(); - - /** Does a signed comparison of two BitArrays. + static const String getOperatingSystemName() throw(); - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other + /** Returns true if the OS is 64-bit, or false for a 32-bit OS. */ - int compare (const BitArray& other) const throw(); - - /** Compares the magnitudes of two BitArrays, ignoring their signs. + static bool isOperatingSystem64Bit() throw(); - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compareAbsolute (const BitArray& other) const throw(); + // CPU and memory information.. - /** Returns true if the value is less than zero. + /** Returns the approximate CPU speed. - @see setNegative, negate + @returns the speed in megahertz, e.g. 1500, 2500, 32000 (depending on + what year you're reading this...) */ - bool isNegative() const throw(); + static int getCpuSpeedInMegaherz() throw(); - /** Changes the sign of the number to be positive or negative. + /** Returns a string to indicate the CPU vendor. - @see isNegative, negate + Might not be known on some systems. */ - void setNegative (const bool shouldBeNegative) throw(); - - /** Inverts the sign of the number. + static const String getCpuVendor() throw(); - @see isNegative, setNegative - */ - void negate() throw(); + /** Checks whether Intel MMX instructions are available. */ + static bool hasMMX() throw(); - /** Counts the total number of set bits in the array. */ - int countNumberOfSetBits() const throw(); + /** Checks whether Intel SSE instructions are available. */ + static bool hasSSE() throw(); - /** Looks for the index of the next set bit after a given starting point. + /** Checks whether Intel SSE2 instructions are available. */ + static bool hasSSE2() throw(); - searches from startIndex (inclusive) upwards for the first set bit, - and returns its index. + /** Checks whether AMD 3DNOW instructions are available. */ + static bool has3DNow() throw(); - If no set bits are found, it returns -1. + /** Returns the number of CPUs. */ - int findNextSetBit (int startIndex = 0) const throw(); - - /** Looks for the index of the next clear bit after a given starting point. + static int getNumCpus() throw(); - searches from startIndex (inclusive) upwards for the first clear bit, - and returns its index. - */ - int findNextClearBit (int startIndex = 0) const throw(); + /** Returns a clock-cycle tick counter, if available. - /** Returns the index of the highest set bit in the array. + If the machine can do it, this will return a tick-count + where each tick is one cpu clock cycle - used for profiling + code. - If the array is empty, this will return -1. + @returns the tick count, or zero if not available. */ - int getHighestBit() const throw(); - - /** Sets a range of bits to random values. */ - void fillBitsRandomly (int startBit, int numBits) throw(); - - /** Turns this value into a random number less than the given value. */ - void createRandomNumber (const BitArray& maximumValue) throw(); + static int64 getClockCycleCounter() throw(); - /** Converts the array to a number string. + /** Finds out how much RAM is in the machine. - Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + @returns the approximate number of megabytes of memory, or zero if + something goes wrong when finding out. */ - const String toString (const int base) const throw(); - - /** Converts a number string to an array. + static int getMemorySizeInMegabytes() throw(); - Any non-valid characters will be ignored. + /** Returns the system page-size. - Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + This is only used by programmers with beards. */ - void parseString (const String& text, - const int base) throw(); - - /** Turns the array into a block of binary data. + static int getPageSize() throw(); - The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the array, and so on. + /** Returns a list of MAC addresses found on this machine. - @see loadFromMemoryBlock + @param addresses an array into which the MAC addresses should be copied + @param maxNum the number of elements in this array + @param littleEndian the endianness of the numbers to return. Note that + the default values of this parameter are different on + Mac/PC to avoid breaking old software that was written + before this parameter was added (when the two systems + defaulted to using different endiannesses). In newer + software you probably want to specify an explicit value + for this. + @returns the number of MAC addresses that were found */ - const MemoryBlock toMemoryBlock() const throw(); + static int getMACAddresses (int64* addresses, int maxNum, +#if JUCE_MAC + const bool littleEndian = true) throw(); +#else + const bool littleEndian = false) throw(); +#endif - /** Copies a block of raw data onto this array. + // not-for-public-use platform-specific method gets called at startup to initialise things. + static void initialiseStats() throw(); +}; - The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the array, and so on. +#endif // __JUCE_SYSTEMSTATS_JUCEHEADER__ +/********* End of inlined file: juce_SystemStats.h *********/ - @see toMemoryBlock - */ - void loadFromMemoryBlock (const MemoryBlock& data) throw(); +#endif +#ifndef __JUCE_TIME_JUCEHEADER__ - juce_UseDebuggingNewOperator +#endif +#ifndef __JUCE_ARRAY_JUCEHEADER__ -private: - void ensureSize (const int numVals) throw(); - unsigned int* values; - int numValues, highestBit; - bool negative; -}; +#endif +#ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__ -#endif // __JUCE_BITARRAY_JUCEHEADER__ -/********* End of inlined file: juce_BitArray.h *********/ +#endif +#ifndef __JUCE_BITARRAY_JUCEHEADER__ #endif #ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__ diff --git a/src/juce_core/basics/juce_Random.cpp b/src/juce_core/basics/juce_Random.cpp index 64b02ad95f..9f5ec7ed59 100644 --- a/src/juce_core/basics/juce_Random.cpp +++ b/src/juce_core/basics/juce_Random.cpp @@ -34,8 +34,8 @@ BEGIN_JUCE_NAMESPACE #include "juce_Random.h" -#include "../basics/juce_Time.h" -#include "../basics/juce_SystemStats.h" +#include "juce_Time.h" +#include "juce_SystemStats.h" //============================================================================== @@ -60,7 +60,7 @@ void Random::setSeedRandomly() Random r3 (Time::getHighResolutionTicksPerSecond()); Random r4 (Time::currentTimeMillis()); - setSeed (r1.nextInt64() ^ r2.nextInt64() + setSeed (nextInt64() ^ r1.nextInt64() ^ r2.nextInt64() ^ r3.nextInt64() ^ r4.nextInt64()); } @@ -98,11 +98,44 @@ double Random::nextDouble() throw() return ((uint32) nextInt()) / (double) 0xffffffff; } -//============================================================================== -static Random sysRand (1); +const BitArray Random::nextLargeNumber (const BitArray& maximumValue) throw() +{ + BitArray n; + + do + { + fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1); + } + while (n.compare (maximumValue) >= 0); + + return n; +} +void Random::fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw() +{ + arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space + + while ((startBit & 31) != 0 && numBits > 0) + { + arrayToChange.setBit (startBit++, nextBool()); + --numBits; + } + + while (numBits >= 32) + { + arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt()); + startBit += 32; + numBits -= 32; + } + + while (--numBits >= 0) + arrayToChange.setBit (startBit + numBits, nextBool()); +} + +//============================================================================== Random& Random::getSystemRandom() throw() { + static Random sysRand (1); return sysRand; } diff --git a/src/juce_core/basics/juce_Random.h b/src/juce_core/basics/juce_Random.h index b85c294a8f..50c7e2f0aa 100644 --- a/src/juce_core/basics/juce_Random.h +++ b/src/juce_core/basics/juce_Random.h @@ -32,6 +32,8 @@ #ifndef __JUCE_RANDOM_JUCEHEADER__ #define __JUCE_RANDOM_JUCEHEADER__ +#include "../containers/juce_BitArray.h" + //============================================================================== /** @@ -88,6 +90,15 @@ public: */ bool nextBool() throw(); + /** Returns a BitArray containing a random number. + + @returns a random value in the range 0 to (maximumValue - 1). + */ + const BitArray nextLargeNumber (const BitArray& maximumValue) throw(); + + /** Sets a range of bits in a BitArray to random values. */ + void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw(); + //============================================================================== /** To avoid the overhead of having to create a new Random object whenever you need a number, this is a shared application-wide object that @@ -100,8 +111,11 @@ public: /** Resets this Random object to a given seed value. */ void setSeed (const int64 newSeed) throw(); - /** Reseeds this generator using a value generated from various semi-random system + /** Reseeds this generator using a value generated from various semi-random system properties like the current time, etc. + + Because this function convolves the time with the last seed value, calling + it repeatedly will increase the randomness of the final result. */ void setSeedRandomly(); diff --git a/src/juce_core/basics/juce_SystemStats.cpp b/src/juce_core/basics/juce_SystemStats.cpp index 6209c6e326..7cf50da0b2 100644 --- a/src/juce_core/basics/juce_SystemStats.cpp +++ b/src/juce_core/basics/juce_SystemStats.cpp @@ -84,9 +84,10 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() juceInitialisedNonGUI = true; DBG (SystemStats::getJUCEVersion()); + Random::getSystemRandom().setSeedRandomly(); // (calling this more than once improves its randomness) juce_initialiseStrings(); SystemStats::initialiseStats(); - Random::getSystemRandom().setSeedRandomly(); + Random::getSystemRandom().setSeedRandomly(); // (calling this more than once improves its randomness) } } diff --git a/src/juce_core/containers/juce_BitArray.cpp b/src/juce_core/containers/juce_BitArray.cpp index 1e6a85b6bd..b6b681f5c2 100644 --- a/src/juce_core/containers/juce_BitArray.cpp +++ b/src/juce_core/containers/juce_BitArray.cpp @@ -736,46 +736,6 @@ void BitArray::setBitRangeAsInt (const int startBit, int numBits, unsigned int v } } -//============================================================================== -void BitArray::fillBitsRandomly (int startBit, int numBits) throw() -{ - highestBit = jmax (highestBit, startBit + numBits); - ensureSize (((startBit + numBits) >> 5) + 1); - - while ((startBit & 31) != 0 && numBits > 0) - { - setBit (startBit++, Random::getSystemRandom().nextBool()); - - --numBits; - } - - while (numBits >= 32) - { - values [startBit >> 5] = (unsigned int) Random::getSystemRandom().nextInt(); - - startBit += 32; - numBits -= 32; - } - - while (--numBits >= 0) - { - setBit (startBit + numBits, Random::getSystemRandom().nextBool()); - } - - highestBit = getHighestBit(); -} - -void BitArray::createRandomNumber (const BitArray& maximumValue) throw() -{ - clear(); - - do - { - fillBitsRandomly (0, maximumValue.getHighestBit() + 1); - } - while (compare (maximumValue) >= 0); -} - //============================================================================== bool BitArray::isNegative() const throw() { diff --git a/src/juce_core/containers/juce_BitArray.h b/src/juce_core/containers/juce_BitArray.h index 3b63967954..8757821346 100644 --- a/src/juce_core/containers/juce_BitArray.h +++ b/src/juce_core/containers/juce_BitArray.h @@ -289,13 +289,6 @@ public: */ int getHighestBit() const throw(); - //============================================================================== - /** Sets a range of bits to random values. */ - void fillBitsRandomly (int startBit, int numBits) throw(); - - /** Turns this value into a random number less than the given value. */ - void createRandomNumber (const BitArray& maximumValue) throw(); - //============================================================================== /** Converts the array to a number string. diff --git a/src/juce_core/cryptography/juce_Primes.cpp b/src/juce_core/cryptography/juce_Primes.cpp index 23a078cf1c..3bb7a7f063 100644 --- a/src/juce_core/cryptography/juce_Primes.cpp +++ b/src/juce_core/cryptography/juce_Primes.cpp @@ -126,16 +126,16 @@ const BitArray Primes::createProbablePrime (const int bitLength, const int* randomSeeds, int numRandomSeeds) throw() { - int defaultSeeds[8]; + int defaultSeeds [16]; if (numRandomSeeds <= 0) { randomSeeds = defaultSeeds; - numRandomSeeds = 8; + numRandomSeeds = numElementsInArray (defaultSeeds); + Random r (0); for (int j = 10; --j >= 0;) { - Random r (0); r.setSeedRandomly(); for (int i = numRandomSeeds; --i >= 0;) @@ -151,15 +151,14 @@ const BitArray Primes::createProbablePrime (const int bitLength, for (int i = numRandomSeeds; --i >= 0;) { - Random::getSystemRandom().setSeed (randomSeeds[i]); - BitArray p2; - p2.fillBitsRandomly (0, bitLength); + + Random r (randomSeeds[i]); + r.fillBitsRandomly (p2, 0, bitLength); + p.xorWith (p2); } - Random::getSystemRandom().setSeedRandomly(); - p.setBit (bitLength - 1); p.clearBit (0);