migrating to the latest JUCE version
This commit is contained in:
2738
deps/juce/modules/juce_core/maths/juce_BigInteger.cpp
vendored
2738
deps/juce/modules/juce_core/maths/juce_BigInteger.cpp
vendored
File diff suppressed because it is too large
Load Diff
684
deps/juce/modules/juce_core/maths/juce_BigInteger.h
vendored
684
deps/juce/modules/juce_core/maths/juce_BigInteger.h
vendored
@ -1,342 +1,342 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An arbitrarily large integer class.
|
||||
|
||||
A BigInteger can be used in a similar way to a normal integer, but has no size
|
||||
limit (except for memory and performance constraints).
|
||||
|
||||
Negative values are possible, but the value isn't stored as 2s-complement, so
|
||||
be careful if you use negative values and look at the values of individual bits.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API BigInteger
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty BigInteger */
|
||||
BigInteger();
|
||||
|
||||
/** Creates a BigInteger containing an integer value in its low bits.
|
||||
The low 32 bits of the number are initialised with this value.
|
||||
*/
|
||||
BigInteger (uint32 value);
|
||||
|
||||
/** Creates a BigInteger containing an integer value in its low bits.
|
||||
The low 32 bits of the number are initialised with the absolute value
|
||||
passed in, and its sign is set to reflect the sign of the number.
|
||||
*/
|
||||
BigInteger (int32 value);
|
||||
|
||||
/** Creates a BigInteger containing an integer value in its low bits.
|
||||
The low 64 bits of the number are initialised with the absolute value
|
||||
passed in, and its sign is set to reflect the sign of the number.
|
||||
*/
|
||||
BigInteger (int64 value);
|
||||
|
||||
/** Creates a copy of another BigInteger. */
|
||||
BigInteger (const BigInteger&);
|
||||
|
||||
/** Move constructor */
|
||||
BigInteger (BigInteger&&) noexcept;
|
||||
|
||||
/** Move assignment operator */
|
||||
BigInteger& operator= (BigInteger&&) noexcept;
|
||||
|
||||
/** Destructor. */
|
||||
~BigInteger();
|
||||
|
||||
//==============================================================================
|
||||
/** Copies another BigInteger onto this one. */
|
||||
BigInteger& operator= (const BigInteger&);
|
||||
|
||||
/** Swaps the internal contents of this with another object. */
|
||||
void swapWith (BigInteger&) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the value of a specified bit in the number.
|
||||
If the index is out-of-range, the result will be false.
|
||||
*/
|
||||
bool operator[] (int bit) const noexcept;
|
||||
|
||||
/** Returns true if no bits are set. */
|
||||
bool isZero() const noexcept;
|
||||
|
||||
/** Returns true if the value is 1. */
|
||||
bool isOne() const noexcept;
|
||||
|
||||
/** Attempts to get the lowest 32 bits of the value as an integer.
|
||||
If the value is bigger than the integer limits, this will return only the lower bits.
|
||||
*/
|
||||
int toInteger() const noexcept;
|
||||
|
||||
/** Attempts to get the lowest 64 bits of the value as an integer.
|
||||
If the value is bigger than the integer limits, this will return only the lower bits.
|
||||
*/
|
||||
int64 toInt64() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Resets the value to 0. */
|
||||
void clear() noexcept;
|
||||
|
||||
/** Clears a particular bit in the number. */
|
||||
void clearBit (int bitNumber) noexcept;
|
||||
|
||||
/** Sets a specified bit to 1. */
|
||||
void setBit (int bitNumber);
|
||||
|
||||
/** Sets or clears a specified bit. */
|
||||
void setBit (int bitNumber, bool shouldBeSet);
|
||||
|
||||
/** 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, bool shouldBeSet);
|
||||
|
||||
/** Inserts a bit an a given position, shifting up any bits above it. */
|
||||
void insertBit (int bitNumber, bool shouldBeSet);
|
||||
|
||||
/** Returns a range of bits as a new BigInteger.
|
||||
|
||||
e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits.
|
||||
@see getBitRangeAsInt
|
||||
*/
|
||||
BigInteger getBitRange (int startBit, int numBits) const;
|
||||
|
||||
/** Returns a range of bits 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) - for that, use
|
||||
getBitRange().
|
||||
*/
|
||||
uint32 getBitRangeAsInt (int startBit, int numBits) const noexcept;
|
||||
|
||||
/** Sets a range of bits to an integer value.
|
||||
|
||||
Copies the given integer onto a range of bits, starting at startBit,
|
||||
and using up to numBits of the available bits.
|
||||
*/
|
||||
void setBitRangeAsInt (int startBit, int numBits, uint32 valueToSet);
|
||||
|
||||
/** Shifts a section of bits left or right.
|
||||
|
||||
@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);
|
||||
|
||||
/** Returns the total number of set bits in the value. */
|
||||
int countNumberOfSetBits() const noexcept;
|
||||
|
||||
/** Looks for the index of the next set bit after a given starting point.
|
||||
|
||||
This 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) const noexcept;
|
||||
|
||||
/** Looks for the index of the next clear bit after a given starting point.
|
||||
|
||||
This searches from startIndex (inclusive) upwards for the first clear bit,
|
||||
and returns its index.
|
||||
*/
|
||||
int findNextClearBit (int startIndex) const noexcept;
|
||||
|
||||
/** Returns the index of the highest set bit in the number.
|
||||
If the value is zero, this will return -1.
|
||||
*/
|
||||
int getHighestBit() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the value is less than zero.
|
||||
@see setNegative, negate
|
||||
*/
|
||||
bool isNegative() const noexcept;
|
||||
|
||||
/** Changes the sign of the number to be positive or negative.
|
||||
@see isNegative, negate
|
||||
*/
|
||||
void setNegative (bool shouldBeNegative) noexcept;
|
||||
|
||||
/** Inverts the sign of the number.
|
||||
@see isNegative, setNegative
|
||||
*/
|
||||
void negate() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
// All the standard arithmetic ops...
|
||||
|
||||
BigInteger& operator+= (const BigInteger&);
|
||||
BigInteger& operator-= (const BigInteger&);
|
||||
BigInteger& operator*= (const BigInteger&);
|
||||
BigInteger& operator/= (const BigInteger&);
|
||||
BigInteger& operator|= (const BigInteger&);
|
||||
BigInteger& operator&= (const BigInteger&);
|
||||
BigInteger& operator^= (const BigInteger&);
|
||||
BigInteger& operator%= (const BigInteger&);
|
||||
BigInteger& operator<<= (int numBitsToShift);
|
||||
BigInteger& operator>>= (int numBitsToShift);
|
||||
BigInteger& operator++();
|
||||
BigInteger& operator--();
|
||||
BigInteger operator++ (int);
|
||||
BigInteger operator-- (int);
|
||||
|
||||
BigInteger operator-() const;
|
||||
BigInteger operator+ (const BigInteger&) const;
|
||||
BigInteger operator- (const BigInteger&) const;
|
||||
BigInteger operator* (const BigInteger&) const;
|
||||
BigInteger operator/ (const BigInteger&) const;
|
||||
BigInteger operator| (const BigInteger&) const;
|
||||
BigInteger operator& (const BigInteger&) const;
|
||||
BigInteger operator^ (const BigInteger&) const;
|
||||
BigInteger operator% (const BigInteger&) const;
|
||||
BigInteger operator<< (int numBitsToShift) const;
|
||||
BigInteger operator>> (int numBitsToShift) const;
|
||||
|
||||
bool operator== (const BigInteger&) const noexcept;
|
||||
bool operator!= (const BigInteger&) const noexcept;
|
||||
bool operator< (const BigInteger&) const noexcept;
|
||||
bool operator<= (const BigInteger&) const noexcept;
|
||||
bool operator> (const BigInteger&) const noexcept;
|
||||
bool operator>= (const BigInteger&) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Does a signed comparison of two BigIntegers.
|
||||
|
||||
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 BigInteger& other) const noexcept;
|
||||
|
||||
/** Compares the magnitudes of two BigIntegers, ignoring their signs.
|
||||
|
||||
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 BigInteger& other) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Divides this value by another one and returns the remainder.
|
||||
|
||||
This number is divided by other, leaving the quotient in this number,
|
||||
with the remainder being copied to the other BigInteger passed in.
|
||||
*/
|
||||
void divideBy (const BigInteger& divisor, BigInteger& remainder);
|
||||
|
||||
/** Returns the largest value that will divide both this value and the argument. */
|
||||
BigInteger findGreatestCommonDivisor (BigInteger other) const;
|
||||
|
||||
/** Performs a combined exponent and modulo operation.
|
||||
This BigInteger's value becomes (this ^ exponent) % modulus.
|
||||
*/
|
||||
void exponentModulo (const BigInteger& exponent, const BigInteger& modulus);
|
||||
|
||||
/** Performs an inverse modulo on the value.
|
||||
i.e. the result is (this ^ -1) mod (modulus).
|
||||
*/
|
||||
void inverseModulo (const BigInteger& modulus);
|
||||
|
||||
/** Performs the Montgomery Multiplication with modulo.
|
||||
This object is left containing the result value: ((this * other) * R1) % modulus.
|
||||
To get this result, we need modulus, modulusp and k such as R = 2^k, with
|
||||
modulus * modulusp - R * R1 = GCD(modulus, R) = 1
|
||||
*/
|
||||
void montgomeryMultiplication (const BigInteger& other, const BigInteger& modulus,
|
||||
const BigInteger& modulusp, int k);
|
||||
|
||||
/** Performs the Extended Euclidean algorithm.
|
||||
This method will set the xOut and yOut arguments such that (a * xOut) - (b * yOut) = GCD (a, b).
|
||||
On return, this object is left containing the value of the GCD.
|
||||
*/
|
||||
void extendedEuclidean (const BigInteger& a, const BigInteger& b,
|
||||
BigInteger& xOut, BigInteger& yOut);
|
||||
|
||||
//==============================================================================
|
||||
/** Converts the number to a string.
|
||||
|
||||
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
|
||||
If minimumNumCharacters is greater than 0, the returned string will be
|
||||
padded with leading zeros to reach at least that length.
|
||||
*/
|
||||
String toString (int base, int minimumNumCharacters = 1) const;
|
||||
|
||||
/** Reads the numeric value from a string.
|
||||
|
||||
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
|
||||
Any invalid characters will be ignored.
|
||||
*/
|
||||
void parseString (StringRef text, int base);
|
||||
|
||||
//==============================================================================
|
||||
/** Turns the number 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 number, and so on.
|
||||
|
||||
@see loadFromMemoryBlock
|
||||
*/
|
||||
MemoryBlock toMemoryBlock() const;
|
||||
|
||||
/** Converts a block of raw data into a number.
|
||||
|
||||
The data is arranged as little-endian, so the first byte of data is the low 8 bits
|
||||
of the number, and so on.
|
||||
|
||||
@see toMemoryBlock
|
||||
*/
|
||||
void loadFromMemoryBlock (const MemoryBlock& data);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
enum { numPreallocatedInts = 4 };
|
||||
HeapBlock<uint32> heapAllocation;
|
||||
uint32 preallocated[numPreallocatedInts];
|
||||
size_t allocatedSize;
|
||||
int highestBit = -1;
|
||||
bool negative = false;
|
||||
|
||||
uint32* getValues() const noexcept;
|
||||
uint32* ensureSize (size_t);
|
||||
void shiftLeft (int bits, int startBit);
|
||||
void shiftRight (int bits, int startBit);
|
||||
|
||||
JUCE_LEAK_DETECTOR (BigInteger)
|
||||
};
|
||||
|
||||
/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */
|
||||
OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value);
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An arbitrarily large integer class.
|
||||
|
||||
A BigInteger can be used in a similar way to a normal integer, but has no size
|
||||
limit (except for memory and performance constraints).
|
||||
|
||||
Negative values are possible, but the value isn't stored as 2s-complement, so
|
||||
be careful if you use negative values and look at the values of individual bits.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API BigInteger
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty BigInteger */
|
||||
BigInteger();
|
||||
|
||||
/** Creates a BigInteger containing an integer value in its low bits.
|
||||
The low 32 bits of the number are initialised with this value.
|
||||
*/
|
||||
BigInteger (uint32 value);
|
||||
|
||||
/** Creates a BigInteger containing an integer value in its low bits.
|
||||
The low 32 bits of the number are initialised with the absolute value
|
||||
passed in, and its sign is set to reflect the sign of the number.
|
||||
*/
|
||||
BigInteger (int32 value);
|
||||
|
||||
/** Creates a BigInteger containing an integer value in its low bits.
|
||||
The low 64 bits of the number are initialised with the absolute value
|
||||
passed in, and its sign is set to reflect the sign of the number.
|
||||
*/
|
||||
BigInteger (int64 value);
|
||||
|
||||
/** Creates a copy of another BigInteger. */
|
||||
BigInteger (const BigInteger&);
|
||||
|
||||
/** Move constructor */
|
||||
BigInteger (BigInteger&&) noexcept;
|
||||
|
||||
/** Move assignment operator */
|
||||
BigInteger& operator= (BigInteger&&) noexcept;
|
||||
|
||||
/** Destructor. */
|
||||
~BigInteger() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Copies another BigInteger onto this one. */
|
||||
BigInteger& operator= (const BigInteger&);
|
||||
|
||||
/** Swaps the internal contents of this with another object. */
|
||||
void swapWith (BigInteger&) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the value of a specified bit in the number.
|
||||
If the index is out-of-range, the result will be false.
|
||||
*/
|
||||
bool operator[] (int bit) const noexcept;
|
||||
|
||||
/** Returns true if no bits are set. */
|
||||
bool isZero() const noexcept;
|
||||
|
||||
/** Returns true if the value is 1. */
|
||||
bool isOne() const noexcept;
|
||||
|
||||
/** Attempts to get the lowest 32 bits of the value as an integer.
|
||||
If the value is bigger than the integer limits, this will return only the lower bits.
|
||||
*/
|
||||
int toInteger() const noexcept;
|
||||
|
||||
/** Attempts to get the lowest 64 bits of the value as an integer.
|
||||
If the value is bigger than the integer limits, this will return only the lower bits.
|
||||
*/
|
||||
int64 toInt64() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Resets the value to 0. */
|
||||
void clear() noexcept;
|
||||
|
||||
/** Clears a particular bit in the number. */
|
||||
void clearBit (int bitNumber) noexcept;
|
||||
|
||||
/** Sets a specified bit to 1. */
|
||||
void setBit (int bitNumber);
|
||||
|
||||
/** Sets or clears a specified bit. */
|
||||
void setBit (int bitNumber, bool shouldBeSet);
|
||||
|
||||
/** 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, bool shouldBeSet);
|
||||
|
||||
/** Inserts a bit an a given position, shifting up any bits above it. */
|
||||
void insertBit (int bitNumber, bool shouldBeSet);
|
||||
|
||||
/** Returns a range of bits as a new BigInteger.
|
||||
|
||||
e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits.
|
||||
@see getBitRangeAsInt
|
||||
*/
|
||||
BigInteger getBitRange (int startBit, int numBits) const;
|
||||
|
||||
/** Returns a range of bits 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) - for that, use
|
||||
getBitRange().
|
||||
*/
|
||||
uint32 getBitRangeAsInt (int startBit, int numBits) const noexcept;
|
||||
|
||||
/** Sets a range of bits to an integer value.
|
||||
|
||||
Copies the given integer onto a range of bits, starting at startBit,
|
||||
and using up to numBits of the available bits.
|
||||
*/
|
||||
void setBitRangeAsInt (int startBit, int numBits, uint32 valueToSet);
|
||||
|
||||
/** Shifts a section of bits left or right.
|
||||
|
||||
@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);
|
||||
|
||||
/** Returns the total number of set bits in the value. */
|
||||
int countNumberOfSetBits() const noexcept;
|
||||
|
||||
/** Looks for the index of the next set bit after a given starting point.
|
||||
|
||||
This 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) const noexcept;
|
||||
|
||||
/** Looks for the index of the next clear bit after a given starting point.
|
||||
|
||||
This searches from startIndex (inclusive) upwards for the first clear bit,
|
||||
and returns its index.
|
||||
*/
|
||||
int findNextClearBit (int startIndex) const noexcept;
|
||||
|
||||
/** Returns the index of the highest set bit in the number.
|
||||
If the value is zero, this will return -1.
|
||||
*/
|
||||
int getHighestBit() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the value is less than zero.
|
||||
@see setNegative, negate
|
||||
*/
|
||||
bool isNegative() const noexcept;
|
||||
|
||||
/** Changes the sign of the number to be positive or negative.
|
||||
@see isNegative, negate
|
||||
*/
|
||||
void setNegative (bool shouldBeNegative) noexcept;
|
||||
|
||||
/** Inverts the sign of the number.
|
||||
@see isNegative, setNegative
|
||||
*/
|
||||
void negate() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
// All the standard arithmetic ops...
|
||||
|
||||
BigInteger& operator+= (const BigInteger&);
|
||||
BigInteger& operator-= (const BigInteger&);
|
||||
BigInteger& operator*= (const BigInteger&);
|
||||
BigInteger& operator/= (const BigInteger&);
|
||||
BigInteger& operator|= (const BigInteger&);
|
||||
BigInteger& operator&= (const BigInteger&);
|
||||
BigInteger& operator^= (const BigInteger&);
|
||||
BigInteger& operator%= (const BigInteger&);
|
||||
BigInteger& operator<<= (int numBitsToShift);
|
||||
BigInteger& operator>>= (int numBitsToShift);
|
||||
BigInteger& operator++();
|
||||
BigInteger& operator--();
|
||||
BigInteger operator++ (int);
|
||||
BigInteger operator-- (int);
|
||||
|
||||
BigInteger operator-() const;
|
||||
BigInteger operator+ (const BigInteger&) const;
|
||||
BigInteger operator- (const BigInteger&) const;
|
||||
BigInteger operator* (const BigInteger&) const;
|
||||
BigInteger operator/ (const BigInteger&) const;
|
||||
BigInteger operator| (const BigInteger&) const;
|
||||
BigInteger operator& (const BigInteger&) const;
|
||||
BigInteger operator^ (const BigInteger&) const;
|
||||
BigInteger operator% (const BigInteger&) const;
|
||||
BigInteger operator<< (int numBitsToShift) const;
|
||||
BigInteger operator>> (int numBitsToShift) const;
|
||||
|
||||
bool operator== (const BigInteger&) const noexcept;
|
||||
bool operator!= (const BigInteger&) const noexcept;
|
||||
bool operator< (const BigInteger&) const noexcept;
|
||||
bool operator<= (const BigInteger&) const noexcept;
|
||||
bool operator> (const BigInteger&) const noexcept;
|
||||
bool operator>= (const BigInteger&) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Does a signed comparison of two BigIntegers.
|
||||
|
||||
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 BigInteger& other) const noexcept;
|
||||
|
||||
/** Compares the magnitudes of two BigIntegers, ignoring their signs.
|
||||
|
||||
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 BigInteger& other) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Divides this value by another one and returns the remainder.
|
||||
|
||||
This number is divided by other, leaving the quotient in this number,
|
||||
with the remainder being copied to the other BigInteger passed in.
|
||||
*/
|
||||
void divideBy (const BigInteger& divisor, BigInteger& remainder);
|
||||
|
||||
/** Returns the largest value that will divide both this value and the argument. */
|
||||
BigInteger findGreatestCommonDivisor (BigInteger other) const;
|
||||
|
||||
/** Performs a combined exponent and modulo operation.
|
||||
This BigInteger's value becomes (this ^ exponent) % modulus.
|
||||
*/
|
||||
void exponentModulo (const BigInteger& exponent, const BigInteger& modulus);
|
||||
|
||||
/** Performs an inverse modulo on the value.
|
||||
i.e. the result is (this ^ -1) mod (modulus).
|
||||
*/
|
||||
void inverseModulo (const BigInteger& modulus);
|
||||
|
||||
/** Performs the Montgomery Multiplication with modulo.
|
||||
This object is left containing the result value: ((this * other) * R1) % modulus.
|
||||
To get this result, we need modulus, modulusp and k such as R = 2^k, with
|
||||
modulus * modulusp - R * R1 = GCD(modulus, R) = 1
|
||||
*/
|
||||
void montgomeryMultiplication (const BigInteger& other, const BigInteger& modulus,
|
||||
const BigInteger& modulusp, int k);
|
||||
|
||||
/** Performs the Extended Euclidean algorithm.
|
||||
This method will set the xOut and yOut arguments such that (a * xOut) - (b * yOut) = GCD (a, b).
|
||||
On return, this object is left containing the value of the GCD.
|
||||
*/
|
||||
void extendedEuclidean (const BigInteger& a, const BigInteger& b,
|
||||
BigInteger& xOut, BigInteger& yOut);
|
||||
|
||||
//==============================================================================
|
||||
/** Converts the number to a string.
|
||||
|
||||
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
|
||||
If minimumNumCharacters is greater than 0, the returned string will be
|
||||
padded with leading zeros to reach at least that length.
|
||||
*/
|
||||
String toString (int base, int minimumNumCharacters = 1) const;
|
||||
|
||||
/** Reads the numeric value from a string.
|
||||
|
||||
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
|
||||
Any invalid characters will be ignored.
|
||||
*/
|
||||
void parseString (StringRef text, int base);
|
||||
|
||||
//==============================================================================
|
||||
/** Turns the number 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 number, and so on.
|
||||
|
||||
@see loadFromMemoryBlock
|
||||
*/
|
||||
MemoryBlock toMemoryBlock() const;
|
||||
|
||||
/** Converts a block of raw data into a number.
|
||||
|
||||
The data is arranged as little-endian, so the first byte of data is the low 8 bits
|
||||
of the number, and so on.
|
||||
|
||||
@see toMemoryBlock
|
||||
*/
|
||||
void loadFromMemoryBlock (const MemoryBlock& data);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
enum { numPreallocatedInts = 4 };
|
||||
HeapBlock<uint32> heapAllocation;
|
||||
uint32 preallocated[numPreallocatedInts];
|
||||
size_t allocatedSize;
|
||||
int highestBit = -1;
|
||||
bool negative = false;
|
||||
|
||||
uint32* getValues() const noexcept;
|
||||
uint32* ensureSize (size_t);
|
||||
void shiftLeft (int bits, int startBit);
|
||||
void shiftRight (int bits, int startBit);
|
||||
|
||||
JUCE_LEAK_DETECTOR (BigInteger)
|
||||
};
|
||||
|
||||
/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */
|
||||
OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value);
|
||||
|
||||
} // namespace juce
|
||||
|
2350
deps/juce/modules/juce_core/maths/juce_Expression.cpp
vendored
2350
deps/juce/modules/juce_core/maths/juce_Expression.cpp
vendored
File diff suppressed because it is too large
Load Diff
502
deps/juce/modules/juce_core/maths/juce_Expression.h
vendored
502
deps/juce/modules/juce_core/maths/juce_Expression.h
vendored
@ -1,251 +1,251 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class for dynamically evaluating simple numeric expressions.
|
||||
|
||||
This class can parse a simple C-style string expression involving floating point
|
||||
numbers, named symbols and functions. The basic arithmetic operations of +, -, *, /
|
||||
are supported, as well as parentheses, and any alphanumeric identifiers are
|
||||
assumed to be named symbols which will be resolved when the expression is
|
||||
evaluated.
|
||||
|
||||
Expressions which use identifiers and functions require a subclass of
|
||||
Expression::Scope to be supplied when evaluating them, and this object
|
||||
is expected to be able to resolve the symbol names and perform the functions that
|
||||
are used.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API Expression
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a simple expression with a value of 0. */
|
||||
Expression();
|
||||
|
||||
/** Destructor. */
|
||||
~Expression();
|
||||
|
||||
/** Creates a copy of an expression. */
|
||||
Expression (const Expression&);
|
||||
|
||||
/** Copies another expression. */
|
||||
Expression& operator= (const Expression&);
|
||||
|
||||
/** Move constructor */
|
||||
Expression (Expression&&) noexcept;
|
||||
|
||||
/** Move assignment operator */
|
||||
Expression& operator= (Expression&&) noexcept;
|
||||
|
||||
/** Creates a simple expression with a specified constant value. */
|
||||
explicit Expression (double constant);
|
||||
|
||||
/** Attempts to create an expression by parsing a string.
|
||||
Any errors are returned in the parseError argument provided.
|
||||
*/
|
||||
Expression (const String& stringToParse, String& parseError);
|
||||
|
||||
/** Returns a string version of the expression. */
|
||||
String toString() const;
|
||||
|
||||
/** Returns an expression which is an addition operation of two existing expressions. */
|
||||
Expression operator+ (const Expression&) const;
|
||||
/** Returns an expression which is a subtraction operation of two existing expressions. */
|
||||
Expression operator- (const Expression&) const;
|
||||
/** Returns an expression which is a multiplication operation of two existing expressions. */
|
||||
Expression operator* (const Expression&) const;
|
||||
/** Returns an expression which is a division operation of two existing expressions. */
|
||||
Expression operator/ (const Expression&) const;
|
||||
/** Returns an expression which performs a negation operation on an existing expression. */
|
||||
Expression operator-() const;
|
||||
|
||||
/** Returns an Expression which is an identifier reference. */
|
||||
static Expression symbol (const String& symbol);
|
||||
|
||||
/** Returns an Expression which is a function call. */
|
||||
static Expression function (const String& functionName, const Array<Expression>& parameters);
|
||||
|
||||
/** Returns an Expression which parses a string from a character pointer, and updates the pointer
|
||||
to indicate where it finished.
|
||||
|
||||
The pointer is incremented so that on return, it indicates the character that follows
|
||||
the end of the expression that was parsed.
|
||||
|
||||
If there's a syntax error in parsing, the parseError argument will be set
|
||||
to a description of the problem.
|
||||
*/
|
||||
static Expression parse (String::CharPointerType& stringToParse, String& parseError);
|
||||
|
||||
//==============================================================================
|
||||
/** When evaluating an Expression object, this class is used to resolve symbols and
|
||||
perform functions that the expression uses.
|
||||
*/
|
||||
class JUCE_API Scope
|
||||
{
|
||||
public:
|
||||
Scope();
|
||||
virtual ~Scope();
|
||||
|
||||
/** Returns some kind of globally unique ID that identifies this scope. */
|
||||
virtual String getScopeUID() const;
|
||||
|
||||
/** Returns the value of a symbol.
|
||||
If the symbol is unknown, this can throw an Expression::EvaluationError exception.
|
||||
The member value is set to the part of the symbol that followed the dot, if there is
|
||||
one, e.g. for "foo.bar", symbol = "foo" and member = "bar".
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
virtual Expression getSymbolValue (const String& symbol) const;
|
||||
|
||||
/** Executes a named function.
|
||||
If the function name is unknown, this can throw an Expression::EvaluationError exception.
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
virtual double evaluateFunction (const String& functionName,
|
||||
const double* parameters, int numParameters) const;
|
||||
|
||||
/** Used as a callback by the Scope::visitRelativeScope() method.
|
||||
You should never create an instance of this class yourself, it's used by the
|
||||
expression evaluation code.
|
||||
*/
|
||||
class Visitor
|
||||
{
|
||||
public:
|
||||
virtual ~Visitor() = default;
|
||||
virtual void visit (const Scope&) = 0;
|
||||
};
|
||||
|
||||
/** Creates a Scope object for a named scope, and then calls a visitor
|
||||
to do some kind of processing with this new scope.
|
||||
|
||||
If the name is valid, this method must create a suitable (temporary) Scope
|
||||
object to represent it, and must call the Visitor::visit() method with this
|
||||
new scope.
|
||||
*/
|
||||
virtual void visitRelativeScope (const String& scopeName, Visitor& visitor) const;
|
||||
};
|
||||
|
||||
/** Evaluates this expression, without using a Scope.
|
||||
Without a Scope, no symbols can be used, and only basic functions such as sin, cos, tan,
|
||||
min, max are available.
|
||||
To find out about any errors during evaluation, use the other version of this method which
|
||||
takes a String parameter.
|
||||
*/
|
||||
double evaluate() const;
|
||||
|
||||
/** Evaluates this expression, providing a scope that should be able to evaluate any symbols
|
||||
or functions that it uses.
|
||||
To find out about any errors during evaluation, use the other version of this method which
|
||||
takes a String parameter.
|
||||
*/
|
||||
double evaluate (const Scope& scope) const;
|
||||
|
||||
/** Evaluates this expression, providing a scope that should be able to evaluate any symbols
|
||||
or functions that it uses.
|
||||
*/
|
||||
double evaluate (const Scope& scope, String& evaluationError) const;
|
||||
|
||||
/** Attempts to return an expression which is a copy of this one, but with a constant adjusted
|
||||
to make the expression resolve to a target value.
|
||||
|
||||
E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return
|
||||
the expression "x + 3". Obviously some expressions can't be reversed in this way, in which
|
||||
case they might just be adjusted by adding a constant to the original expression.
|
||||
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const;
|
||||
|
||||
/** Represents a symbol that is used in an Expression. */
|
||||
struct Symbol
|
||||
{
|
||||
Symbol (const String& scopeUID, const String& symbolName);
|
||||
bool operator== (const Symbol&) const noexcept;
|
||||
bool operator!= (const Symbol&) const noexcept;
|
||||
|
||||
String scopeUID; /**< The unique ID of the Scope that contains this symbol. */
|
||||
String symbolName; /**< The name of the symbol. */
|
||||
};
|
||||
|
||||
/** Returns a copy of this expression in which all instances of a given symbol have been renamed. */
|
||||
Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const;
|
||||
|
||||
/** Returns true if this expression makes use of the specified symbol.
|
||||
If a suitable scope is supplied, the search will dereference and recursively check
|
||||
all symbols, so that it can be determined whether this expression relies on the given
|
||||
symbol at any level in its evaluation. If the scope parameter is null, this just checks
|
||||
whether the expression contains any direct references to the symbol.
|
||||
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
bool referencesSymbol (const Symbol& symbol, const Scope& scope) const;
|
||||
|
||||
/** Returns true if this expression contains any symbols. */
|
||||
bool usesAnySymbols() const;
|
||||
|
||||
/** Returns a list of all symbols that may be needed to resolve this expression in the given scope. */
|
||||
void findReferencedSymbols (Array<Symbol>& results, const Scope& scope) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Expression type.
|
||||
@see Expression::getType()
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
constantType,
|
||||
functionType,
|
||||
operatorType,
|
||||
symbolType
|
||||
};
|
||||
|
||||
/** Returns the type of this expression. */
|
||||
Type getType() const noexcept;
|
||||
|
||||
/** If this expression is a symbol, function or operator, this returns its identifier. */
|
||||
String getSymbolOrFunction() const;
|
||||
|
||||
/** Returns the number of inputs to this expression.
|
||||
@see getInput
|
||||
*/
|
||||
int getNumInputs() const;
|
||||
|
||||
/** Retrieves one of the inputs to this expression.
|
||||
@see getNumInputs
|
||||
*/
|
||||
Expression getInput (int index) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class Term;
|
||||
struct Helpers;
|
||||
ReferenceCountedObjectPtr<Term> term;
|
||||
|
||||
explicit Expression (Term*);
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class for dynamically evaluating simple numeric expressions.
|
||||
|
||||
This class can parse a simple C-style string expression involving floating point
|
||||
numbers, named symbols and functions. The basic arithmetic operations of +, -, *, /
|
||||
are supported, as well as parentheses, and any alphanumeric identifiers are
|
||||
assumed to be named symbols which will be resolved when the expression is
|
||||
evaluated.
|
||||
|
||||
Expressions which use identifiers and functions require a subclass of
|
||||
Expression::Scope to be supplied when evaluating them, and this object
|
||||
is expected to be able to resolve the symbol names and perform the functions that
|
||||
are used.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API Expression
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a simple expression with a value of 0. */
|
||||
Expression();
|
||||
|
||||
/** Destructor. */
|
||||
~Expression();
|
||||
|
||||
/** Creates a copy of an expression. */
|
||||
Expression (const Expression&);
|
||||
|
||||
/** Copies another expression. */
|
||||
Expression& operator= (const Expression&);
|
||||
|
||||
/** Move constructor */
|
||||
Expression (Expression&&) noexcept;
|
||||
|
||||
/** Move assignment operator */
|
||||
Expression& operator= (Expression&&) noexcept;
|
||||
|
||||
/** Creates a simple expression with a specified constant value. */
|
||||
explicit Expression (double constant);
|
||||
|
||||
/** Attempts to create an expression by parsing a string.
|
||||
Any errors are returned in the parseError argument provided.
|
||||
*/
|
||||
Expression (const String& stringToParse, String& parseError);
|
||||
|
||||
/** Returns a string version of the expression. */
|
||||
String toString() const;
|
||||
|
||||
/** Returns an expression which is an addition operation of two existing expressions. */
|
||||
Expression operator+ (const Expression&) const;
|
||||
/** Returns an expression which is a subtraction operation of two existing expressions. */
|
||||
Expression operator- (const Expression&) const;
|
||||
/** Returns an expression which is a multiplication operation of two existing expressions. */
|
||||
Expression operator* (const Expression&) const;
|
||||
/** Returns an expression which is a division operation of two existing expressions. */
|
||||
Expression operator/ (const Expression&) const;
|
||||
/** Returns an expression which performs a negation operation on an existing expression. */
|
||||
Expression operator-() const;
|
||||
|
||||
/** Returns an Expression which is an identifier reference. */
|
||||
static Expression symbol (const String& symbol);
|
||||
|
||||
/** Returns an Expression which is a function call. */
|
||||
static Expression function (const String& functionName, const Array<Expression>& parameters);
|
||||
|
||||
/** Returns an Expression which parses a string from a character pointer, and updates the pointer
|
||||
to indicate where it finished.
|
||||
|
||||
The pointer is incremented so that on return, it indicates the character that follows
|
||||
the end of the expression that was parsed.
|
||||
|
||||
If there's a syntax error in parsing, the parseError argument will be set
|
||||
to a description of the problem.
|
||||
*/
|
||||
static Expression parse (String::CharPointerType& stringToParse, String& parseError);
|
||||
|
||||
//==============================================================================
|
||||
/** When evaluating an Expression object, this class is used to resolve symbols and
|
||||
perform functions that the expression uses.
|
||||
*/
|
||||
class JUCE_API Scope
|
||||
{
|
||||
public:
|
||||
Scope();
|
||||
virtual ~Scope();
|
||||
|
||||
/** Returns some kind of globally unique ID that identifies this scope. */
|
||||
virtual String getScopeUID() const;
|
||||
|
||||
/** Returns the value of a symbol.
|
||||
If the symbol is unknown, this can throw an Expression::EvaluationError exception.
|
||||
The member value is set to the part of the symbol that followed the dot, if there is
|
||||
one, e.g. for "foo.bar", symbol = "foo" and member = "bar".
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
virtual Expression getSymbolValue (const String& symbol) const;
|
||||
|
||||
/** Executes a named function.
|
||||
If the function name is unknown, this can throw an Expression::EvaluationError exception.
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
virtual double evaluateFunction (const String& functionName,
|
||||
const double* parameters, int numParameters) const;
|
||||
|
||||
/** Used as a callback by the Scope::visitRelativeScope() method.
|
||||
You should never create an instance of this class yourself, it's used by the
|
||||
expression evaluation code.
|
||||
*/
|
||||
class Visitor
|
||||
{
|
||||
public:
|
||||
virtual ~Visitor() = default;
|
||||
virtual void visit (const Scope&) = 0;
|
||||
};
|
||||
|
||||
/** Creates a Scope object for a named scope, and then calls a visitor
|
||||
to do some kind of processing with this new scope.
|
||||
|
||||
If the name is valid, this method must create a suitable (temporary) Scope
|
||||
object to represent it, and must call the Visitor::visit() method with this
|
||||
new scope.
|
||||
*/
|
||||
virtual void visitRelativeScope (const String& scopeName, Visitor& visitor) const;
|
||||
};
|
||||
|
||||
/** Evaluates this expression, without using a Scope.
|
||||
Without a Scope, no symbols can be used, and only basic functions such as sin, cos, tan,
|
||||
min, max are available.
|
||||
To find out about any errors during evaluation, use the other version of this method which
|
||||
takes a String parameter.
|
||||
*/
|
||||
double evaluate() const;
|
||||
|
||||
/** Evaluates this expression, providing a scope that should be able to evaluate any symbols
|
||||
or functions that it uses.
|
||||
To find out about any errors during evaluation, use the other version of this method which
|
||||
takes a String parameter.
|
||||
*/
|
||||
double evaluate (const Scope& scope) const;
|
||||
|
||||
/** Evaluates this expression, providing a scope that should be able to evaluate any symbols
|
||||
or functions that it uses.
|
||||
*/
|
||||
double evaluate (const Scope& scope, String& evaluationError) const;
|
||||
|
||||
/** Attempts to return an expression which is a copy of this one, but with a constant adjusted
|
||||
to make the expression resolve to a target value.
|
||||
|
||||
E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return
|
||||
the expression "x + 3". Obviously some expressions can't be reversed in this way, in which
|
||||
case they might just be adjusted by adding a constant to the original expression.
|
||||
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const;
|
||||
|
||||
/** Represents a symbol that is used in an Expression. */
|
||||
struct Symbol
|
||||
{
|
||||
Symbol (const String& scopeUID, const String& symbolName);
|
||||
bool operator== (const Symbol&) const noexcept;
|
||||
bool operator!= (const Symbol&) const noexcept;
|
||||
|
||||
String scopeUID; /**< The unique ID of the Scope that contains this symbol. */
|
||||
String symbolName; /**< The name of the symbol. */
|
||||
};
|
||||
|
||||
/** Returns a copy of this expression in which all instances of a given symbol have been renamed. */
|
||||
Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const;
|
||||
|
||||
/** Returns true if this expression makes use of the specified symbol.
|
||||
If a suitable scope is supplied, the search will dereference and recursively check
|
||||
all symbols, so that it can be determined whether this expression relies on the given
|
||||
symbol at any level in its evaluation. If the scope parameter is null, this just checks
|
||||
whether the expression contains any direct references to the symbol.
|
||||
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
bool referencesSymbol (const Symbol& symbol, const Scope& scope) const;
|
||||
|
||||
/** Returns true if this expression contains any symbols. */
|
||||
bool usesAnySymbols() const;
|
||||
|
||||
/** Returns a list of all symbols that may be needed to resolve this expression in the given scope. */
|
||||
void findReferencedSymbols (Array<Symbol>& results, const Scope& scope) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Expression type.
|
||||
@see Expression::getType()
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
constantType,
|
||||
functionType,
|
||||
operatorType,
|
||||
symbolType
|
||||
};
|
||||
|
||||
/** Returns the type of this expression. */
|
||||
Type getType() const noexcept;
|
||||
|
||||
/** If this expression is a symbol, function or operator, this returns its identifier. */
|
||||
String getSymbolOrFunction() const;
|
||||
|
||||
/** Returns the number of inputs to this expression.
|
||||
@see getInput
|
||||
*/
|
||||
int getNumInputs() const;
|
||||
|
||||
/** Retrieves one of the inputs to this expression.
|
||||
@see getNumInputs
|
||||
*/
|
||||
Expression getInput (int index) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class Term;
|
||||
struct Helpers;
|
||||
ReferenceCountedObjectPtr<Term> term;
|
||||
|
||||
explicit Expression (Term*);
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
1370
deps/juce/modules/juce_core/maths/juce_MathsFunctions.h
vendored
1370
deps/juce/modules/juce_core/maths/juce_MathsFunctions.h
vendored
File diff suppressed because it is too large
Load Diff
@ -1,261 +1,261 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a mapping between an arbitrary range of values and a
|
||||
normalised 0->1 range.
|
||||
|
||||
The properties of the mapping also include an optional snapping interval
|
||||
and skew-factor.
|
||||
|
||||
@see Range
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <typename ValueType>
|
||||
class NormalisableRange
|
||||
{
|
||||
public:
|
||||
/** Creates a continuous range that performs a dummy mapping. */
|
||||
NormalisableRange() = default;
|
||||
|
||||
NormalisableRange (const NormalisableRange&) = default;
|
||||
NormalisableRange& operator= (const NormalisableRange&) = default;
|
||||
NormalisableRange (NormalisableRange&&) = default;
|
||||
NormalisableRange& operator= (NormalisableRange&&) = default;
|
||||
|
||||
/** Creates a NormalisableRange with a given range, interval and skew factor. */
|
||||
NormalisableRange (ValueType rangeStart,
|
||||
ValueType rangeEnd,
|
||||
ValueType intervalValue,
|
||||
ValueType skewFactor,
|
||||
bool useSymmetricSkew = false) noexcept
|
||||
: start (rangeStart), end (rangeEnd), interval (intervalValue),
|
||||
skew (skewFactor), symmetricSkew (useSymmetricSkew)
|
||||
{
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** Creates a NormalisableRange with a given range, continuous interval, but a dummy skew-factor. */
|
||||
NormalisableRange (ValueType rangeStart,
|
||||
ValueType rangeEnd) noexcept
|
||||
: start (rangeStart), end (rangeEnd)
|
||||
{
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** Creates a NormalisableRange with a given range and interval, but a dummy skew-factor. */
|
||||
NormalisableRange (ValueType rangeStart,
|
||||
ValueType rangeEnd,
|
||||
ValueType intervalValue) noexcept
|
||||
: start (rangeStart), end (rangeEnd), interval (intervalValue)
|
||||
{
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** Creates a NormalisableRange with a given range, continuous interval, but a dummy skew-factor. */
|
||||
NormalisableRange (Range<ValueType> range) noexcept
|
||||
: NormalisableRange (range.getStart(), range.getEnd())
|
||||
{
|
||||
}
|
||||
|
||||
/** Creates a NormalisableRange with a given range and interval, but a dummy skew-factor. */
|
||||
NormalisableRange (Range<ValueType> range, ValueType intervalValue) noexcept
|
||||
: NormalisableRange (range.getStart(), range.getEnd(), intervalValue)
|
||||
{
|
||||
}
|
||||
|
||||
/** A function object which can remap a value in some way based on the start and end of a range. */
|
||||
using ValueRemapFunction = std::function<ValueType(ValueType rangeStart,
|
||||
ValueType rangeEnd,
|
||||
ValueType valueToRemap)>;
|
||||
|
||||
/** Creates a NormalisableRange with a given range and an injective mapping function.
|
||||
|
||||
@param rangeStart The minimum value in the range.
|
||||
@param rangeEnd The maximum value in the range.
|
||||
@param convertFrom0To1Func A function which uses the current start and end of this NormalisableRange
|
||||
and produces a mapped value from a normalised value.
|
||||
@param convertTo0To1Func A function which uses the current start and end of this NormalisableRange
|
||||
and produces a normalised value from a mapped value.
|
||||
@param snapToLegalValueFunc A function which uses the current start and end of this NormalisableRange
|
||||
to take a mapped value and snap it to the nearest legal value.
|
||||
*/
|
||||
NormalisableRange (ValueType rangeStart,
|
||||
ValueType rangeEnd,
|
||||
ValueRemapFunction convertFrom0To1Func,
|
||||
ValueRemapFunction convertTo0To1Func,
|
||||
ValueRemapFunction snapToLegalValueFunc = {}) noexcept
|
||||
: start (rangeStart),
|
||||
end (rangeEnd),
|
||||
convertFrom0To1Function (std::move (convertFrom0To1Func)),
|
||||
convertTo0To1Function (std::move (convertTo0To1Func)),
|
||||
snapToLegalValueFunction (std::move (snapToLegalValueFunc))
|
||||
{
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** Uses the properties of this mapping to convert a non-normalised value to
|
||||
its 0->1 representation.
|
||||
*/
|
||||
ValueType convertTo0to1 (ValueType v) const noexcept
|
||||
{
|
||||
if (convertTo0To1Function != nullptr)
|
||||
return clampTo0To1 (convertTo0To1Function (start, end, v));
|
||||
|
||||
auto proportion = clampTo0To1 ((v - start) / (end - start));
|
||||
|
||||
if (skew == static_cast<ValueType> (1))
|
||||
return proportion;
|
||||
|
||||
if (! symmetricSkew)
|
||||
return std::pow (proportion, skew);
|
||||
|
||||
auto distanceFromMiddle = static_cast<ValueType> (2) * proportion - static_cast<ValueType> (1);
|
||||
|
||||
return (static_cast<ValueType> (1) + std::pow (std::abs (distanceFromMiddle), skew)
|
||||
* (distanceFromMiddle < ValueType() ? static_cast<ValueType> (-1)
|
||||
: static_cast<ValueType> (1)))
|
||||
/ static_cast<ValueType> (2);
|
||||
}
|
||||
|
||||
/** Uses the properties of this mapping to convert a normalised 0->1 value to
|
||||
its full-range representation.
|
||||
*/
|
||||
ValueType convertFrom0to1 (ValueType proportion) const noexcept
|
||||
{
|
||||
proportion = clampTo0To1 (proportion);
|
||||
|
||||
if (convertFrom0To1Function != nullptr)
|
||||
return convertFrom0To1Function (start, end, proportion);
|
||||
|
||||
if (! symmetricSkew)
|
||||
{
|
||||
if (skew != static_cast<ValueType> (1) && proportion > ValueType())
|
||||
proportion = std::exp (std::log (proportion) / skew);
|
||||
|
||||
return start + (end - start) * proportion;
|
||||
}
|
||||
|
||||
auto distanceFromMiddle = static_cast<ValueType> (2) * proportion - static_cast<ValueType> (1);
|
||||
|
||||
if (skew != static_cast<ValueType> (1) && distanceFromMiddle != static_cast<ValueType> (0))
|
||||
distanceFromMiddle = std::exp (std::log (std::abs (distanceFromMiddle)) / skew)
|
||||
* (distanceFromMiddle < ValueType() ? static_cast<ValueType> (-1)
|
||||
: static_cast<ValueType> (1));
|
||||
|
||||
return start + (end - start) / static_cast<ValueType> (2) * (static_cast<ValueType> (1) + distanceFromMiddle);
|
||||
}
|
||||
|
||||
/** Takes a non-normalised value and snaps it based on either the interval property of
|
||||
this NormalisableRange or the lambda function supplied to the constructor.
|
||||
*/
|
||||
ValueType snapToLegalValue (ValueType v) const noexcept
|
||||
{
|
||||
if (snapToLegalValueFunction != nullptr)
|
||||
return snapToLegalValueFunction (start, end, v);
|
||||
|
||||
if (interval > ValueType())
|
||||
v = start + interval * std::floor ((v - start) / interval + static_cast<ValueType> (0.5));
|
||||
|
||||
return (v <= start || end <= start) ? start : (v >= end ? end : v);
|
||||
}
|
||||
|
||||
/** Returns the extent of the normalisable range. */
|
||||
Range<ValueType> getRange() const noexcept { return { start, end }; }
|
||||
|
||||
/** Given a value which is between the start and end points, this sets the skew
|
||||
such that convertFrom0to1 (0.5) will return this value.
|
||||
|
||||
If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the
|
||||
constructor of this class then the skew value is ignored.
|
||||
|
||||
@param centrePointValue this must be greater than the start of the range and less than the end.
|
||||
*/
|
||||
void setSkewForCentre (ValueType centrePointValue) noexcept
|
||||
{
|
||||
jassert (centrePointValue > start);
|
||||
jassert (centrePointValue < end);
|
||||
|
||||
symmetricSkew = false;
|
||||
skew = std::log (static_cast<ValueType> (0.5)) / std::log ((centrePointValue - start) / (end - start));
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** The minimum value of the non-normalised range. */
|
||||
ValueType start = 0;
|
||||
|
||||
/** The maximum value of the non-normalised range. */
|
||||
ValueType end = 1;
|
||||
|
||||
/** The snapping interval that should be used (for a non-normalised value). Use 0 for a
|
||||
continuous range.
|
||||
|
||||
If you have used a lambda function for snapToLegalValueFunction in the constructor of
|
||||
this class then the interval is ignored.
|
||||
*/
|
||||
ValueType interval = 0;
|
||||
|
||||
/** An optional skew factor that alters the way values are distribute across the range.
|
||||
|
||||
The skew factor lets you skew the mapping logarithmically so that larger or smaller
|
||||
values are given a larger proportion of the available space.
|
||||
|
||||
A factor of 1.0 has no skewing effect at all. If the factor is < 1.0, the lower end
|
||||
of the range will fill more of the slider's length; if the factor is > 1.0, the upper
|
||||
end of the range will be expanded.
|
||||
|
||||
If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the
|
||||
constructor of this class then the skew value is ignored.
|
||||
*/
|
||||
ValueType skew = 1;
|
||||
|
||||
/** If true, the skew factor applies from the middle of the slider to each of its ends. */
|
||||
bool symmetricSkew = false;
|
||||
|
||||
private:
|
||||
void checkInvariants() const
|
||||
{
|
||||
jassert (end > start);
|
||||
jassert (interval >= ValueType());
|
||||
jassert (skew > ValueType());
|
||||
}
|
||||
|
||||
static ValueType clampTo0To1 (ValueType value)
|
||||
{
|
||||
auto clampedValue = jlimit (static_cast<ValueType> (0), static_cast<ValueType> (1), value);
|
||||
|
||||
// If you hit this assertion then either your normalisation function is not working
|
||||
// correctly or your input is out of the expected bounds.
|
||||
jassert (clampedValue == value);
|
||||
|
||||
return clampedValue;
|
||||
}
|
||||
|
||||
ValueRemapFunction convertFrom0To1Function, convertTo0To1Function, snapToLegalValueFunction;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a mapping between an arbitrary range of values and a
|
||||
normalised 0->1 range.
|
||||
|
||||
The properties of the mapping also include an optional snapping interval
|
||||
and skew-factor.
|
||||
|
||||
@see Range
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <typename ValueType>
|
||||
class NormalisableRange
|
||||
{
|
||||
public:
|
||||
/** Creates a continuous range that performs a dummy mapping. */
|
||||
NormalisableRange() = default;
|
||||
|
||||
NormalisableRange (const NormalisableRange&) = default;
|
||||
NormalisableRange& operator= (const NormalisableRange&) = default;
|
||||
NormalisableRange (NormalisableRange&&) = default;
|
||||
NormalisableRange& operator= (NormalisableRange&&) = default;
|
||||
|
||||
/** Creates a NormalisableRange with a given range, interval and skew factor. */
|
||||
NormalisableRange (ValueType rangeStart,
|
||||
ValueType rangeEnd,
|
||||
ValueType intervalValue,
|
||||
ValueType skewFactor,
|
||||
bool useSymmetricSkew = false) noexcept
|
||||
: start (rangeStart), end (rangeEnd), interval (intervalValue),
|
||||
skew (skewFactor), symmetricSkew (useSymmetricSkew)
|
||||
{
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** Creates a NormalisableRange with a given range, continuous interval, but a dummy skew-factor. */
|
||||
NormalisableRange (ValueType rangeStart,
|
||||
ValueType rangeEnd) noexcept
|
||||
: start (rangeStart), end (rangeEnd)
|
||||
{
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** Creates a NormalisableRange with a given range and interval, but a dummy skew-factor. */
|
||||
NormalisableRange (ValueType rangeStart,
|
||||
ValueType rangeEnd,
|
||||
ValueType intervalValue) noexcept
|
||||
: start (rangeStart), end (rangeEnd), interval (intervalValue)
|
||||
{
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** Creates a NormalisableRange with a given range, continuous interval, but a dummy skew-factor. */
|
||||
NormalisableRange (Range<ValueType> range) noexcept
|
||||
: NormalisableRange (range.getStart(), range.getEnd())
|
||||
{
|
||||
}
|
||||
|
||||
/** Creates a NormalisableRange with a given range and interval, but a dummy skew-factor. */
|
||||
NormalisableRange (Range<ValueType> range, ValueType intervalValue) noexcept
|
||||
: NormalisableRange (range.getStart(), range.getEnd(), intervalValue)
|
||||
{
|
||||
}
|
||||
|
||||
/** A function object which can remap a value in some way based on the start and end of a range. */
|
||||
using ValueRemapFunction = std::function<ValueType(ValueType rangeStart,
|
||||
ValueType rangeEnd,
|
||||
ValueType valueToRemap)>;
|
||||
|
||||
/** Creates a NormalisableRange with a given range and an injective mapping function.
|
||||
|
||||
@param rangeStart The minimum value in the range.
|
||||
@param rangeEnd The maximum value in the range.
|
||||
@param convertFrom0To1Func A function which uses the current start and end of this NormalisableRange
|
||||
and produces a mapped value from a normalised value.
|
||||
@param convertTo0To1Func A function which uses the current start and end of this NormalisableRange
|
||||
and produces a normalised value from a mapped value.
|
||||
@param snapToLegalValueFunc A function which uses the current start and end of this NormalisableRange
|
||||
to take a mapped value and snap it to the nearest legal value.
|
||||
*/
|
||||
NormalisableRange (ValueType rangeStart,
|
||||
ValueType rangeEnd,
|
||||
ValueRemapFunction convertFrom0To1Func,
|
||||
ValueRemapFunction convertTo0To1Func,
|
||||
ValueRemapFunction snapToLegalValueFunc = {}) noexcept
|
||||
: start (rangeStart),
|
||||
end (rangeEnd),
|
||||
convertFrom0To1Function (std::move (convertFrom0To1Func)),
|
||||
convertTo0To1Function (std::move (convertTo0To1Func)),
|
||||
snapToLegalValueFunction (std::move (snapToLegalValueFunc))
|
||||
{
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** Uses the properties of this mapping to convert a non-normalised value to
|
||||
its 0->1 representation.
|
||||
*/
|
||||
ValueType convertTo0to1 (ValueType v) const noexcept
|
||||
{
|
||||
if (convertTo0To1Function != nullptr)
|
||||
return clampTo0To1 (convertTo0To1Function (start, end, v));
|
||||
|
||||
auto proportion = clampTo0To1 ((v - start) / (end - start));
|
||||
|
||||
if (skew == static_cast<ValueType> (1))
|
||||
return proportion;
|
||||
|
||||
if (! symmetricSkew)
|
||||
return std::pow (proportion, skew);
|
||||
|
||||
auto distanceFromMiddle = static_cast<ValueType> (2) * proportion - static_cast<ValueType> (1);
|
||||
|
||||
return (static_cast<ValueType> (1) + std::pow (std::abs (distanceFromMiddle), skew)
|
||||
* (distanceFromMiddle < ValueType() ? static_cast<ValueType> (-1)
|
||||
: static_cast<ValueType> (1)))
|
||||
/ static_cast<ValueType> (2);
|
||||
}
|
||||
|
||||
/** Uses the properties of this mapping to convert a normalised 0->1 value to
|
||||
its full-range representation.
|
||||
*/
|
||||
ValueType convertFrom0to1 (ValueType proportion) const noexcept
|
||||
{
|
||||
proportion = clampTo0To1 (proportion);
|
||||
|
||||
if (convertFrom0To1Function != nullptr)
|
||||
return convertFrom0To1Function (start, end, proportion);
|
||||
|
||||
if (! symmetricSkew)
|
||||
{
|
||||
if (skew != static_cast<ValueType> (1) && proportion > ValueType())
|
||||
proportion = std::exp (std::log (proportion) / skew);
|
||||
|
||||
return start + (end - start) * proportion;
|
||||
}
|
||||
|
||||
auto distanceFromMiddle = static_cast<ValueType> (2) * proportion - static_cast<ValueType> (1);
|
||||
|
||||
if (skew != static_cast<ValueType> (1) && distanceFromMiddle != static_cast<ValueType> (0))
|
||||
distanceFromMiddle = std::exp (std::log (std::abs (distanceFromMiddle)) / skew)
|
||||
* (distanceFromMiddle < ValueType() ? static_cast<ValueType> (-1)
|
||||
: static_cast<ValueType> (1));
|
||||
|
||||
return start + (end - start) / static_cast<ValueType> (2) * (static_cast<ValueType> (1) + distanceFromMiddle);
|
||||
}
|
||||
|
||||
/** Takes a non-normalised value and snaps it based on either the interval property of
|
||||
this NormalisableRange or the lambda function supplied to the constructor.
|
||||
*/
|
||||
ValueType snapToLegalValue (ValueType v) const noexcept
|
||||
{
|
||||
if (snapToLegalValueFunction != nullptr)
|
||||
return snapToLegalValueFunction (start, end, v);
|
||||
|
||||
if (interval > ValueType())
|
||||
v = start + interval * std::floor ((v - start) / interval + static_cast<ValueType> (0.5));
|
||||
|
||||
return (v <= start || end <= start) ? start : (v >= end ? end : v);
|
||||
}
|
||||
|
||||
/** Returns the extent of the normalisable range. */
|
||||
Range<ValueType> getRange() const noexcept { return { start, end }; }
|
||||
|
||||
/** Given a value which is between the start and end points, this sets the skew
|
||||
such that convertFrom0to1 (0.5) will return this value.
|
||||
|
||||
If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the
|
||||
constructor of this class then the skew value is ignored.
|
||||
|
||||
@param centrePointValue this must be greater than the start of the range and less than the end.
|
||||
*/
|
||||
void setSkewForCentre (ValueType centrePointValue) noexcept
|
||||
{
|
||||
jassert (centrePointValue > start);
|
||||
jassert (centrePointValue < end);
|
||||
|
||||
symmetricSkew = false;
|
||||
skew = std::log (static_cast<ValueType> (0.5)) / std::log ((centrePointValue - start) / (end - start));
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/** The minimum value of the non-normalised range. */
|
||||
ValueType start = 0;
|
||||
|
||||
/** The maximum value of the non-normalised range. */
|
||||
ValueType end = 1;
|
||||
|
||||
/** The snapping interval that should be used (for a non-normalised value). Use 0 for a
|
||||
continuous range.
|
||||
|
||||
If you have used a lambda function for snapToLegalValueFunction in the constructor of
|
||||
this class then the interval is ignored.
|
||||
*/
|
||||
ValueType interval = 0;
|
||||
|
||||
/** An optional skew factor that alters the way values are distribute across the range.
|
||||
|
||||
The skew factor lets you skew the mapping logarithmically so that larger or smaller
|
||||
values are given a larger proportion of the available space.
|
||||
|
||||
A factor of 1.0 has no skewing effect at all. If the factor is < 1.0, the lower end
|
||||
of the range will fill more of the slider's length; if the factor is > 1.0, the upper
|
||||
end of the range will be expanded.
|
||||
|
||||
If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the
|
||||
constructor of this class then the skew value is ignored.
|
||||
*/
|
||||
ValueType skew = 1;
|
||||
|
||||
/** If true, the skew factor applies from the middle of the slider to each of its ends. */
|
||||
bool symmetricSkew = false;
|
||||
|
||||
private:
|
||||
void checkInvariants() const
|
||||
{
|
||||
jassert (end > start);
|
||||
jassert (interval >= ValueType());
|
||||
jassert (skew > ValueType());
|
||||
}
|
||||
|
||||
static ValueType clampTo0To1 (ValueType value)
|
||||
{
|
||||
auto clampedValue = jlimit (static_cast<ValueType> (0), static_cast<ValueType> (1), value);
|
||||
|
||||
// If you hit this assertion then either your normalisation function is not working
|
||||
// correctly or your input is out of the expected bounds.
|
||||
jassert (clampedValue == value);
|
||||
|
||||
return clampedValue;
|
||||
}
|
||||
|
||||
ValueRemapFunction convertFrom0To1Function, convertTo0To1Function, snapToLegalValueFunction;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
404
deps/juce/modules/juce_core/maths/juce_Random.cpp
vendored
404
deps/juce/modules/juce_core/maths/juce_Random.cpp
vendored
@ -1,204 +1,200 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
Random::Random (int64 seedValue) noexcept : seed (seedValue)
|
||||
{
|
||||
}
|
||||
|
||||
Random::Random() : seed (1)
|
||||
{
|
||||
setSeedRandomly();
|
||||
}
|
||||
|
||||
Random::~Random() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void Random::setSeed (const int64 newSeed) noexcept
|
||||
{
|
||||
if (this == &getSystemRandom())
|
||||
{
|
||||
// Resetting the system Random risks messing up
|
||||
// JUCE's internal state. If you need a predictable
|
||||
// stream of random numbers you should use a local
|
||||
// Random object.
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
seed = newSeed;
|
||||
}
|
||||
|
||||
void Random::combineSeed (const int64 seedValue) noexcept
|
||||
{
|
||||
seed ^= nextInt64() ^ seedValue;
|
||||
}
|
||||
|
||||
void Random::setSeedRandomly()
|
||||
{
|
||||
static std::atomic<int64> globalSeed { 0 };
|
||||
|
||||
combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
|
||||
combineSeed (Time::getMillisecondCounter());
|
||||
combineSeed (Time::getHighResolutionTicks());
|
||||
combineSeed (Time::getHighResolutionTicksPerSecond());
|
||||
combineSeed (Time::currentTimeMillis());
|
||||
globalSeed ^= seed;
|
||||
}
|
||||
|
||||
Random& Random::getSystemRandom() noexcept
|
||||
{
|
||||
static Random sysRand;
|
||||
return sysRand;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int Random::nextInt() noexcept
|
||||
{
|
||||
seed = (int64) (((((uint64) seed) * 0x5deece66dLL) + 11) & 0xffffffffffffLL);
|
||||
|
||||
return (int) (seed >> 16);
|
||||
}
|
||||
|
||||
int Random::nextInt (const int maxValue) noexcept
|
||||
{
|
||||
jassert (maxValue > 0);
|
||||
return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
|
||||
}
|
||||
|
||||
int Random::nextInt (Range<int> range) noexcept
|
||||
{
|
||||
return range.getStart() + nextInt (range.getLength());
|
||||
}
|
||||
|
||||
int64 Random::nextInt64() noexcept
|
||||
{
|
||||
return (int64) ((((uint64) (unsigned int) nextInt()) << 32) | (uint64) (unsigned int) nextInt());
|
||||
}
|
||||
|
||||
bool Random::nextBool() noexcept
|
||||
{
|
||||
return (nextInt() & 0x40000000) != 0;
|
||||
}
|
||||
|
||||
float Random::nextFloat() noexcept
|
||||
{
|
||||
auto result = static_cast<float> (static_cast<uint32> (nextInt()))
|
||||
/ (static_cast<float> (std::numeric_limits<uint32>::max()) + 1.0f);
|
||||
return result == 1.0f ? 1.0f - std::numeric_limits<float>::epsilon() : result;
|
||||
}
|
||||
|
||||
double Random::nextDouble() noexcept
|
||||
{
|
||||
return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0);
|
||||
}
|
||||
|
||||
BigInteger Random::nextLargeNumber (const BigInteger& maximumValue)
|
||||
{
|
||||
BigInteger n;
|
||||
|
||||
do
|
||||
{
|
||||
fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
|
||||
}
|
||||
while (n >= maximumValue);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void Random::fillBitsRandomly (void* const buffer, size_t bytes)
|
||||
{
|
||||
int* d = static_cast<int*> (buffer);
|
||||
|
||||
for (; bytes >= sizeof (int); bytes -= sizeof (int))
|
||||
*d++ = nextInt();
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
const int lastBytes = nextInt();
|
||||
memcpy (d, &lastBytes, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
class RandomTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
RandomTests()
|
||||
: UnitTest ("Random", UnitTestCategories::maths)
|
||||
{}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("Random");
|
||||
|
||||
Random r = getRandom();
|
||||
|
||||
for (int i = 2000; --i >= 0;)
|
||||
{
|
||||
expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
|
||||
expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
|
||||
expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
|
||||
expect (r.nextInt (1) == 0);
|
||||
|
||||
int n = r.nextInt (50) + 1;
|
||||
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
|
||||
|
||||
n = r.nextInt (0x7ffffffe) + 1;
|
||||
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static RandomTests randomTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
Random::Random (int64 seedValue) noexcept : seed (seedValue)
|
||||
{
|
||||
}
|
||||
|
||||
Random::Random() : seed (1)
|
||||
{
|
||||
setSeedRandomly();
|
||||
}
|
||||
|
||||
void Random::setSeed (const int64 newSeed) noexcept
|
||||
{
|
||||
if (this == &getSystemRandom())
|
||||
{
|
||||
// Resetting the system Random risks messing up
|
||||
// JUCE's internal state. If you need a predictable
|
||||
// stream of random numbers you should use a local
|
||||
// Random object.
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
seed = newSeed;
|
||||
}
|
||||
|
||||
void Random::combineSeed (const int64 seedValue) noexcept
|
||||
{
|
||||
seed ^= nextInt64() ^ seedValue;
|
||||
}
|
||||
|
||||
void Random::setSeedRandomly()
|
||||
{
|
||||
static std::atomic<int64> globalSeed { 0 };
|
||||
|
||||
combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
|
||||
combineSeed (Time::getMillisecondCounter());
|
||||
combineSeed (Time::getHighResolutionTicks());
|
||||
combineSeed (Time::getHighResolutionTicksPerSecond());
|
||||
combineSeed (Time::currentTimeMillis());
|
||||
globalSeed ^= seed;
|
||||
}
|
||||
|
||||
Random& Random::getSystemRandom() noexcept
|
||||
{
|
||||
static Random sysRand;
|
||||
return sysRand;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int Random::nextInt() noexcept
|
||||
{
|
||||
seed = (int64) (((((uint64) seed) * 0x5deece66dLL) + 11) & 0xffffffffffffLL);
|
||||
|
||||
return (int) (seed >> 16);
|
||||
}
|
||||
|
||||
int Random::nextInt (const int maxValue) noexcept
|
||||
{
|
||||
jassert (maxValue > 0);
|
||||
return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
|
||||
}
|
||||
|
||||
int Random::nextInt (Range<int> range) noexcept
|
||||
{
|
||||
return range.getStart() + nextInt (range.getLength());
|
||||
}
|
||||
|
||||
int64 Random::nextInt64() noexcept
|
||||
{
|
||||
return (int64) ((((uint64) (unsigned int) nextInt()) << 32) | (uint64) (unsigned int) nextInt());
|
||||
}
|
||||
|
||||
bool Random::nextBool() noexcept
|
||||
{
|
||||
return (nextInt() & 0x40000000) != 0;
|
||||
}
|
||||
|
||||
float Random::nextFloat() noexcept
|
||||
{
|
||||
auto result = static_cast<float> (static_cast<uint32> (nextInt()))
|
||||
/ (static_cast<float> (std::numeric_limits<uint32>::max()) + 1.0f);
|
||||
return result == 1.0f ? 1.0f - std::numeric_limits<float>::epsilon() : result;
|
||||
}
|
||||
|
||||
double Random::nextDouble() noexcept
|
||||
{
|
||||
return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0);
|
||||
}
|
||||
|
||||
BigInteger Random::nextLargeNumber (const BigInteger& maximumValue)
|
||||
{
|
||||
BigInteger n;
|
||||
|
||||
do
|
||||
{
|
||||
fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
|
||||
}
|
||||
while (n >= maximumValue);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void Random::fillBitsRandomly (void* const buffer, size_t bytes)
|
||||
{
|
||||
int* d = static_cast<int*> (buffer);
|
||||
|
||||
for (; bytes >= sizeof (int); bytes -= sizeof (int))
|
||||
*d++ = nextInt();
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
const int lastBytes = nextInt();
|
||||
memcpy (d, &lastBytes, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
class RandomTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
RandomTests()
|
||||
: UnitTest ("Random", UnitTestCategories::maths)
|
||||
{}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("Random");
|
||||
|
||||
Random r = getRandom();
|
||||
|
||||
for (int i = 2000; --i >= 0;)
|
||||
{
|
||||
expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
|
||||
expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
|
||||
expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
|
||||
expect (r.nextInt (1) == 0);
|
||||
|
||||
int n = r.nextInt (50) + 1;
|
||||
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
|
||||
|
||||
n = r.nextInt (0x7ffffffe) + 1;
|
||||
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static RandomTests randomTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
271
deps/juce/modules/juce_core/maths/juce_Random.h
vendored
271
deps/juce/modules/juce_core/maths/juce_Random.h
vendored
@ -1,137 +1,134 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A random number generator.
|
||||
|
||||
You can create a Random object and use it to generate a sequence of random numbers.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API Random final
|
||||
{
|
||||
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())
|
||||
*/
|
||||
explicit Random (int64 seedValue) noexcept;
|
||||
|
||||
/** Creates a Random object using a random seed value.
|
||||
Internally, this calls setSeedRandomly() to randomise the seed.
|
||||
*/
|
||||
Random();
|
||||
|
||||
/** Destructor. */
|
||||
~Random() noexcept;
|
||||
|
||||
/** Returns the next random 32 bit integer.
|
||||
@returns a random integer from the full range 0x80000000 to 0x7fffffff
|
||||
*/
|
||||
int nextInt() noexcept;
|
||||
|
||||
/** Returns the next random number, limited to a given range.
|
||||
The maxValue parameter may not be negative, or zero.
|
||||
@returns a random integer between 0 (inclusive) and maxValue (exclusive).
|
||||
*/
|
||||
int nextInt (int maxValue) noexcept;
|
||||
|
||||
/** Returns the next random number, limited to a given range.
|
||||
@returns a random integer between the range start (inclusive) and its end (exclusive).
|
||||
*/
|
||||
int nextInt (Range<int> range) noexcept;
|
||||
|
||||
/** Returns the next 64-bit random number.
|
||||
@returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff
|
||||
*/
|
||||
int64 nextInt64() noexcept;
|
||||
|
||||
/** Returns the next random floating-point number.
|
||||
@returns a random value in the range 0 (inclusive) to 1.0 (exclusive)
|
||||
*/
|
||||
float nextFloat() noexcept;
|
||||
|
||||
/** Returns the next random floating-point number.
|
||||
@returns a random value in the range 0 (inclusive) to 1.0 (exclusive)
|
||||
*/
|
||||
double nextDouble() noexcept;
|
||||
|
||||
/** Returns the next random boolean value. */
|
||||
bool nextBool() noexcept;
|
||||
|
||||
/** Returns a BigInteger containing a random number.
|
||||
@returns a random value in the range 0 to (maximumValue - 1).
|
||||
*/
|
||||
BigInteger nextLargeNumber (const BigInteger& maximumValue);
|
||||
|
||||
/** Fills a block of memory with random values. */
|
||||
void fillBitsRandomly (void* bufferToFill, size_t sizeInBytes);
|
||||
|
||||
/** Sets a range of bits in a BigInteger to random values. */
|
||||
void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits);
|
||||
|
||||
//==============================================================================
|
||||
/** Resets this Random object to a given seed value. */
|
||||
void setSeed (int64 newSeed) noexcept;
|
||||
|
||||
/** Returns the RNG's current seed. */
|
||||
int64 getSeed() const noexcept { return seed; }
|
||||
|
||||
/** Merges this object's seed with another value.
|
||||
This sets the seed to be a value created by combining the current seed and this
|
||||
new value.
|
||||
*/
|
||||
void combineSeed (int64 seedValue) noexcept;
|
||||
|
||||
/** 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();
|
||||
|
||||
/** The overhead of creating a new Random object is fairly small, but if you want to avoid
|
||||
it, you can call this method to get a global shared Random object.
|
||||
|
||||
It's not thread-safe though, so threads should use their own Random object, otherwise
|
||||
you run the risk of your random numbers becoming.. erm.. randomly corrupted..
|
||||
*/
|
||||
static Random& getSystemRandom() noexcept;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int64 seed;
|
||||
|
||||
JUCE_LEAK_DETECTOR (Random)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A random number generator.
|
||||
|
||||
You can create a Random object and use it to generate a sequence of random numbers.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API Random final
|
||||
{
|
||||
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())
|
||||
*/
|
||||
explicit Random (int64 seedValue) noexcept;
|
||||
|
||||
/** Creates a Random object using a random seed value.
|
||||
Internally, this calls setSeedRandomly() to randomise the seed.
|
||||
*/
|
||||
Random();
|
||||
|
||||
/** Returns the next random 32 bit integer.
|
||||
@returns a random integer from the full range 0x80000000 to 0x7fffffff
|
||||
*/
|
||||
int nextInt() noexcept;
|
||||
|
||||
/** Returns the next random number, limited to a given range.
|
||||
The maxValue parameter may not be negative, or zero.
|
||||
@returns a random integer between 0 (inclusive) and maxValue (exclusive).
|
||||
*/
|
||||
int nextInt (int maxValue) noexcept;
|
||||
|
||||
/** Returns the next random number, limited to a given range.
|
||||
@returns a random integer between the range start (inclusive) and its end (exclusive).
|
||||
*/
|
||||
int nextInt (Range<int> range) noexcept;
|
||||
|
||||
/** Returns the next 64-bit random number.
|
||||
@returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff
|
||||
*/
|
||||
int64 nextInt64() noexcept;
|
||||
|
||||
/** Returns the next random floating-point number.
|
||||
@returns a random value in the range 0 (inclusive) to 1.0 (exclusive)
|
||||
*/
|
||||
float nextFloat() noexcept;
|
||||
|
||||
/** Returns the next random floating-point number.
|
||||
@returns a random value in the range 0 (inclusive) to 1.0 (exclusive)
|
||||
*/
|
||||
double nextDouble() noexcept;
|
||||
|
||||
/** Returns the next random boolean value. */
|
||||
bool nextBool() noexcept;
|
||||
|
||||
/** Returns a BigInteger containing a random number.
|
||||
@returns a random value in the range 0 to (maximumValue - 1).
|
||||
*/
|
||||
BigInteger nextLargeNumber (const BigInteger& maximumValue);
|
||||
|
||||
/** Fills a block of memory with random values. */
|
||||
void fillBitsRandomly (void* bufferToFill, size_t sizeInBytes);
|
||||
|
||||
/** Sets a range of bits in a BigInteger to random values. */
|
||||
void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits);
|
||||
|
||||
//==============================================================================
|
||||
/** Resets this Random object to a given seed value. */
|
||||
void setSeed (int64 newSeed) noexcept;
|
||||
|
||||
/** Returns the RNG's current seed. */
|
||||
int64 getSeed() const noexcept { return seed; }
|
||||
|
||||
/** Merges this object's seed with another value.
|
||||
This sets the seed to be a value created by combining the current seed and this
|
||||
new value.
|
||||
*/
|
||||
void combineSeed (int64 seedValue) noexcept;
|
||||
|
||||
/** 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();
|
||||
|
||||
/** The overhead of creating a new Random object is fairly small, but if you want to avoid
|
||||
it, you can call this method to get a global shared Random object.
|
||||
|
||||
It's not thread-safe though, so threads should use their own Random object, otherwise
|
||||
you run the risk of your random numbers becoming.. erm.. randomly corrupted..
|
||||
*/
|
||||
static Random& getSystemRandom() noexcept;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int64 seed;
|
||||
|
||||
JUCE_LEAK_DETECTOR (Random)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
595
deps/juce/modules/juce_core/maths/juce_Range.h
vendored
595
deps/juce/modules/juce_core/maths/juce_Range.h
vendored
@ -1,297 +1,298 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/** A general-purpose range object, that simply represents any linear range with
|
||||
a start and end point.
|
||||
|
||||
Note that when checking whether values fall within the range, the start value is
|
||||
considered to be inclusive, and the end of the range exclusive.
|
||||
|
||||
The templated parameter is expected to be a primitive integer or floating point
|
||||
type, though class types could also be used if they behave in a number-like way.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <typename ValueType>
|
||||
class Range
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Constructs an empty range. */
|
||||
constexpr Range() = default;
|
||||
|
||||
/** Constructs a range with given start and end values. */
|
||||
constexpr Range (const ValueType startValue, const ValueType endValue) noexcept
|
||||
: start (startValue), end (jmax (startValue, endValue))
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructs a copy of another range. */
|
||||
constexpr Range (const Range&) = default;
|
||||
|
||||
/** Copies another range object. */
|
||||
Range& operator= (const Range&) = default;
|
||||
|
||||
/** Returns the range that lies between two positions (in either order). */
|
||||
constexpr static Range between (const ValueType position1, const ValueType position2) noexcept
|
||||
{
|
||||
return position1 < position2 ? Range (position1, position2)
|
||||
: Range (position2, position1);
|
||||
}
|
||||
|
||||
/** Returns a range with a given start and length. */
|
||||
static Range withStartAndLength (const ValueType startValue, const ValueType length) noexcept
|
||||
{
|
||||
jassert (length >= ValueType());
|
||||
return Range (startValue, startValue + length);
|
||||
}
|
||||
|
||||
/** Returns a range with the specified start position and a length of zero. */
|
||||
constexpr static Range emptyRange (const ValueType start) noexcept
|
||||
{
|
||||
return Range (start, start);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the start of the range. */
|
||||
constexpr inline ValueType getStart() const noexcept { return start; }
|
||||
|
||||
/** Returns the length of the range. */
|
||||
constexpr inline ValueType getLength() const noexcept { return end - start; }
|
||||
|
||||
/** Returns the end of the range. */
|
||||
constexpr inline ValueType getEnd() const noexcept { return end; }
|
||||
|
||||
/** Returns true if the range has a length of zero. */
|
||||
constexpr inline bool isEmpty() const noexcept { return start == end; }
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the start position of the range, leaving the end position unchanged.
|
||||
If the new start position is higher than the current end of the range, the end point
|
||||
will be pushed along to equal it, leaving an empty range at the new position.
|
||||
*/
|
||||
void setStart (const ValueType newStart) noexcept
|
||||
{
|
||||
start = newStart;
|
||||
if (end < newStart)
|
||||
end = newStart;
|
||||
}
|
||||
|
||||
/** Returns a range with the same end as this one, but a different start.
|
||||
If the new start position is higher than the current end of the range, the end point
|
||||
will be pushed along to equal it, returning an empty range at the new position.
|
||||
*/
|
||||
constexpr Range withStart (const ValueType newStart) const noexcept
|
||||
{
|
||||
return Range (newStart, jmax (newStart, end));
|
||||
}
|
||||
|
||||
/** Returns a range with the same length as this one, but moved to have the given start position. */
|
||||
constexpr Range movedToStartAt (const ValueType newStart) const noexcept
|
||||
{
|
||||
return Range (newStart, end + (newStart - start));
|
||||
}
|
||||
|
||||
/** Changes the end position of the range, leaving the start unchanged.
|
||||
If the new end position is below the current start of the range, the start point
|
||||
will be pushed back to equal the new end point.
|
||||
*/
|
||||
void setEnd (const ValueType newEnd) noexcept
|
||||
{
|
||||
end = newEnd;
|
||||
if (newEnd < start)
|
||||
start = newEnd;
|
||||
}
|
||||
|
||||
/** Returns a range with the same start position as this one, but a different end.
|
||||
If the new end position is below the current start of the range, the start point
|
||||
will be pushed back to equal the new end point.
|
||||
*/
|
||||
constexpr Range withEnd (const ValueType newEnd) const noexcept
|
||||
{
|
||||
return Range (jmin (start, newEnd), newEnd);
|
||||
}
|
||||
|
||||
/** Returns a range with the same length as this one, but moved to have the given end position. */
|
||||
constexpr Range movedToEndAt (const ValueType newEnd) const noexcept
|
||||
{
|
||||
return Range (start + (newEnd - end), newEnd);
|
||||
}
|
||||
|
||||
/** Changes the length of the range.
|
||||
Lengths less than zero are treated as zero.
|
||||
*/
|
||||
void setLength (const ValueType newLength) noexcept
|
||||
{
|
||||
end = start + jmax (ValueType(), newLength);
|
||||
}
|
||||
|
||||
/** Returns a range with the same start as this one, but a different length.
|
||||
Lengths less than zero are treated as zero.
|
||||
*/
|
||||
constexpr Range withLength (const ValueType newLength) const noexcept
|
||||
{
|
||||
return Range (start, start + newLength);
|
||||
}
|
||||
|
||||
/** Returns a range which has its start moved down and its end moved up by the
|
||||
given amount.
|
||||
@returns The returned range will be (start - amount, end + amount)
|
||||
*/
|
||||
constexpr Range expanded (ValueType amount) const noexcept
|
||||
{
|
||||
return Range (start - amount, end + amount);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Adds an amount to the start and end of the range. */
|
||||
inline Range operator+= (const ValueType amountToAdd) noexcept
|
||||
{
|
||||
start += amountToAdd;
|
||||
end += amountToAdd;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Subtracts an amount from the start and end of the range. */
|
||||
inline Range operator-= (const ValueType amountToSubtract) noexcept
|
||||
{
|
||||
start -= amountToSubtract;
|
||||
end -= amountToSubtract;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Returns a range that is equal to this one with an amount added to its
|
||||
start and end.
|
||||
*/
|
||||
constexpr Range operator+ (const ValueType amountToAdd) const noexcept
|
||||
{
|
||||
return Range (start + amountToAdd, end + amountToAdd);
|
||||
}
|
||||
|
||||
/** Returns a range that is equal to this one with the specified amount
|
||||
subtracted from its start and end. */
|
||||
constexpr Range operator- (const ValueType amountToSubtract) const noexcept
|
||||
{
|
||||
return Range (start - amountToSubtract, end - amountToSubtract);
|
||||
}
|
||||
|
||||
constexpr bool operator== (Range other) const noexcept { return start == other.start && end == other.end; }
|
||||
constexpr bool operator!= (Range other) const noexcept { return start != other.start || end != other.end; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the given position lies inside this range.
|
||||
When making this comparison, the start value is considered to be inclusive,
|
||||
and the end of the range exclusive.
|
||||
*/
|
||||
constexpr bool contains (const ValueType position) const noexcept
|
||||
{
|
||||
return start <= position && position < end;
|
||||
}
|
||||
|
||||
/** Returns the nearest value to the one supplied, which lies within the range. */
|
||||
ValueType clipValue (const ValueType value) const noexcept
|
||||
{
|
||||
return jlimit (start, end, value);
|
||||
}
|
||||
|
||||
/** Returns true if the given range lies entirely inside this range. */
|
||||
constexpr bool contains (Range other) const noexcept
|
||||
{
|
||||
return start <= other.start && end >= other.end;
|
||||
}
|
||||
|
||||
/** Returns true if the given range intersects this one. */
|
||||
constexpr bool intersects (Range other) const noexcept
|
||||
{
|
||||
return other.start < end && start < other.end;
|
||||
}
|
||||
|
||||
/** Returns the range that is the intersection of the two ranges, or an empty range
|
||||
with an undefined start position if they don't overlap. */
|
||||
constexpr Range getIntersectionWith (Range other) const noexcept
|
||||
{
|
||||
return Range (jmax (start, other.start),
|
||||
jmin (end, other.end));
|
||||
}
|
||||
|
||||
/** Returns the smallest range that contains both this one and the other one. */
|
||||
constexpr Range getUnionWith (Range other) const noexcept
|
||||
{
|
||||
return Range (jmin (start, other.start),
|
||||
jmax (end, other.end));
|
||||
}
|
||||
|
||||
/** Returns the smallest range that contains both this one and the given value. */
|
||||
constexpr Range getUnionWith (const ValueType valueToInclude) const noexcept
|
||||
{
|
||||
return Range (jmin (valueToInclude, start),
|
||||
jmax (valueToInclude, end));
|
||||
}
|
||||
|
||||
/** Returns a given range, after moving it forwards or backwards to fit it
|
||||
within this range.
|
||||
|
||||
If the supplied range has a greater length than this one, the return value
|
||||
will be this range.
|
||||
|
||||
Otherwise, if the supplied range is smaller than this one, the return value
|
||||
will be the new range, shifted forwards or backwards so that it doesn't extend
|
||||
beyond this one, but keeping its original length.
|
||||
*/
|
||||
Range constrainRange (Range rangeToConstrain) const noexcept
|
||||
{
|
||||
const ValueType otherLen = rangeToConstrain.getLength();
|
||||
return getLength() <= otherLen
|
||||
? *this
|
||||
: rangeToConstrain.movedToStartAt (jlimit (start, end - otherLen, rangeToConstrain.getStart()));
|
||||
}
|
||||
|
||||
/** Scans an array of values for its min and max, and returns these as a Range. */
|
||||
static Range findMinAndMax (const ValueType* values, int numValues) noexcept
|
||||
{
|
||||
if (numValues <= 0)
|
||||
return Range();
|
||||
|
||||
const ValueType first (*values++);
|
||||
Range r (first, first);
|
||||
|
||||
while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
|
||||
{
|
||||
const ValueType v (*values++);
|
||||
|
||||
if (r.end < v) r.end = v;
|
||||
if (v < r.start) r.start = v;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ValueType start{}, end{};
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/** A general-purpose range object, that simply represents any linear range with
|
||||
a start and end point.
|
||||
|
||||
Note that when checking whether values fall within the range, the start value is
|
||||
considered to be inclusive, and the end of the range exclusive.
|
||||
|
||||
The templated parameter is expected to be a primitive integer or floating point
|
||||
type, though class types could also be used if they behave in a number-like way.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <typename ValueType>
|
||||
class Range
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Constructs an empty range. */
|
||||
constexpr Range() = default;
|
||||
|
||||
/** Constructs a range with given start and end values. */
|
||||
constexpr Range (const ValueType startValue, const ValueType endValue) noexcept
|
||||
: start (startValue), end (jmax (startValue, endValue))
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructs a copy of another range. */
|
||||
constexpr Range (const Range&) = default;
|
||||
|
||||
/** Copies another range object. */
|
||||
Range& operator= (const Range&) = default;
|
||||
|
||||
/** Returns the range that lies between two positions (in either order). */
|
||||
constexpr static Range between (const ValueType position1, const ValueType position2) noexcept
|
||||
{
|
||||
return position1 < position2 ? Range (position1, position2)
|
||||
: Range (position2, position1);
|
||||
}
|
||||
|
||||
/** Returns a range with a given start and length. */
|
||||
JUCE_NODISCARD static Range withStartAndLength (const ValueType startValue, const ValueType length) noexcept
|
||||
{
|
||||
jassert (length >= ValueType());
|
||||
return Range (startValue, startValue + length);
|
||||
}
|
||||
|
||||
/** Returns a range with the specified start position and a length of zero. */
|
||||
JUCE_NODISCARD constexpr static Range emptyRange (const ValueType start) noexcept
|
||||
{
|
||||
return Range (start, start);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the start of the range. */
|
||||
constexpr inline ValueType getStart() const noexcept { return start; }
|
||||
|
||||
/** Returns the length of the range. */
|
||||
constexpr inline ValueType getLength() const noexcept { return end - start; }
|
||||
|
||||
/** Returns the end of the range. */
|
||||
constexpr inline ValueType getEnd() const noexcept { return end; }
|
||||
|
||||
/** Returns true if the range has a length of zero. */
|
||||
constexpr inline bool isEmpty() const noexcept { return start == end; }
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the start position of the range, leaving the end position unchanged.
|
||||
If the new start position is higher than the current end of the range, the end point
|
||||
will be pushed along to equal it, leaving an empty range at the new position.
|
||||
*/
|
||||
void setStart (const ValueType newStart) noexcept
|
||||
{
|
||||
start = newStart;
|
||||
if (end < newStart)
|
||||
end = newStart;
|
||||
}
|
||||
|
||||
/** Returns a range with the same end as this one, but a different start.
|
||||
If the new start position is higher than the current end of the range, the end point
|
||||
will be pushed along to equal it, returning an empty range at the new position.
|
||||
*/
|
||||
JUCE_NODISCARD constexpr Range withStart (const ValueType newStart) const noexcept
|
||||
{
|
||||
return Range (newStart, jmax (newStart, end));
|
||||
}
|
||||
|
||||
/** Returns a range with the same length as this one, but moved to have the given start position. */
|
||||
JUCE_NODISCARD constexpr Range movedToStartAt (const ValueType newStart) const noexcept
|
||||
{
|
||||
return Range (newStart, end + (newStart - start));
|
||||
}
|
||||
|
||||
/** Changes the end position of the range, leaving the start unchanged.
|
||||
If the new end position is below the current start of the range, the start point
|
||||
will be pushed back to equal the new end point.
|
||||
*/
|
||||
void setEnd (const ValueType newEnd) noexcept
|
||||
{
|
||||
end = newEnd;
|
||||
if (newEnd < start)
|
||||
start = newEnd;
|
||||
}
|
||||
|
||||
/** Returns a range with the same start position as this one, but a different end.
|
||||
If the new end position is below the current start of the range, the start point
|
||||
will be pushed back to equal the new end point.
|
||||
*/
|
||||
JUCE_NODISCARD constexpr Range withEnd (const ValueType newEnd) const noexcept
|
||||
{
|
||||
return Range (jmin (start, newEnd), newEnd);
|
||||
}
|
||||
|
||||
/** Returns a range with the same length as this one, but moved to have the given end position. */
|
||||
JUCE_NODISCARD constexpr Range movedToEndAt (const ValueType newEnd) const noexcept
|
||||
{
|
||||
return Range (start + (newEnd - end), newEnd);
|
||||
}
|
||||
|
||||
/** Changes the length of the range.
|
||||
Lengths less than zero are treated as zero.
|
||||
*/
|
||||
void setLength (const ValueType newLength) noexcept
|
||||
{
|
||||
end = start + jmax (ValueType(), newLength);
|
||||
}
|
||||
|
||||
/** Returns a range with the same start as this one, but a different length.
|
||||
Lengths less than zero are treated as zero.
|
||||
*/
|
||||
JUCE_NODISCARD constexpr Range withLength (const ValueType newLength) const noexcept
|
||||
{
|
||||
return Range (start, start + newLength);
|
||||
}
|
||||
|
||||
/** Returns a range which has its start moved down and its end moved up by the
|
||||
given amount.
|
||||
@returns The returned range will be (start - amount, end + amount)
|
||||
*/
|
||||
JUCE_NODISCARD constexpr Range expanded (ValueType amount) const noexcept
|
||||
{
|
||||
return Range (start - amount, end + amount);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Adds an amount to the start and end of the range. */
|
||||
inline Range operator+= (const ValueType amountToAdd) noexcept
|
||||
{
|
||||
start += amountToAdd;
|
||||
end += amountToAdd;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Subtracts an amount from the start and end of the range. */
|
||||
inline Range operator-= (const ValueType amountToSubtract) noexcept
|
||||
{
|
||||
start -= amountToSubtract;
|
||||
end -= amountToSubtract;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Returns a range that is equal to this one with an amount added to its
|
||||
start and end.
|
||||
*/
|
||||
constexpr Range operator+ (const ValueType amountToAdd) const noexcept
|
||||
{
|
||||
return Range (start + amountToAdd, end + amountToAdd);
|
||||
}
|
||||
|
||||
/** Returns a range that is equal to this one with the specified amount
|
||||
subtracted from its start and end. */
|
||||
constexpr Range operator- (const ValueType amountToSubtract) const noexcept
|
||||
{
|
||||
return Range (start - amountToSubtract, end - amountToSubtract);
|
||||
}
|
||||
|
||||
constexpr bool operator== (Range other) const noexcept { return start == other.start && end == other.end; }
|
||||
constexpr bool operator!= (Range other) const noexcept { return start != other.start || end != other.end; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the given position lies inside this range.
|
||||
When making this comparison, the start value is considered to be inclusive,
|
||||
and the end of the range exclusive.
|
||||
*/
|
||||
constexpr bool contains (const ValueType position) const noexcept
|
||||
{
|
||||
return start <= position && position < end;
|
||||
}
|
||||
|
||||
/** Returns the nearest value to the one supplied, which lies within the range. */
|
||||
ValueType clipValue (const ValueType value) const noexcept
|
||||
{
|
||||
return jlimit (start, end, value);
|
||||
}
|
||||
|
||||
/** Returns true if the given range lies entirely inside this range. */
|
||||
constexpr bool contains (Range other) const noexcept
|
||||
{
|
||||
return start <= other.start && end >= other.end;
|
||||
}
|
||||
|
||||
/** Returns true if the given range intersects this one. */
|
||||
constexpr bool intersects (Range other) const noexcept
|
||||
{
|
||||
return other.start < end && start < other.end;
|
||||
}
|
||||
|
||||
/** Returns the range that is the intersection of the two ranges, or an empty range
|
||||
with an undefined start position if they don't overlap. */
|
||||
JUCE_NODISCARD constexpr Range getIntersectionWith (Range other) const noexcept
|
||||
{
|
||||
return Range (jmax (start, other.start),
|
||||
jmin (end, other.end));
|
||||
}
|
||||
|
||||
/** Returns the smallest range that contains both this one and the other one. */
|
||||
JUCE_NODISCARD constexpr Range getUnionWith (Range other) const noexcept
|
||||
{
|
||||
return Range (jmin (start, other.start),
|
||||
jmax (end, other.end));
|
||||
}
|
||||
|
||||
/** Returns the smallest range that contains both this one and the given value. */
|
||||
JUCE_NODISCARD constexpr Range getUnionWith (const ValueType valueToInclude) const noexcept
|
||||
{
|
||||
return Range (jmin (valueToInclude, start),
|
||||
jmax (valueToInclude, end));
|
||||
}
|
||||
|
||||
/** Returns a given range, after moving it forwards or backwards to fit it
|
||||
within this range.
|
||||
|
||||
If the supplied range has a greater length than this one, the return value
|
||||
will be this range.
|
||||
|
||||
Otherwise, if the supplied range is smaller than this one, the return value
|
||||
will be the new range, shifted forwards or backwards so that it doesn't extend
|
||||
beyond this one, but keeping its original length.
|
||||
*/
|
||||
Range constrainRange (Range rangeToConstrain) const noexcept
|
||||
{
|
||||
const ValueType otherLen = rangeToConstrain.getLength();
|
||||
return getLength() <= otherLen
|
||||
? *this
|
||||
: rangeToConstrain.movedToStartAt (jlimit (start, end - otherLen, rangeToConstrain.getStart()));
|
||||
}
|
||||
|
||||
/** Scans an array of values for its min and max, and returns these as a Range. */
|
||||
template <typename Integral, std::enable_if_t<std::is_integral<Integral>::value, int> = 0>
|
||||
static Range findMinAndMax (const ValueType* values, Integral numValues) noexcept
|
||||
{
|
||||
if (numValues <= 0)
|
||||
return Range();
|
||||
|
||||
const ValueType first (*values++);
|
||||
Range r (first, first);
|
||||
|
||||
while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
|
||||
{
|
||||
const ValueType v (*values++);
|
||||
|
||||
if (r.end < v) r.end = v;
|
||||
if (v < r.start) r.start = v;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ValueType start{}, end{};
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,136 +1,136 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class that measures various statistics about a series of floating point
|
||||
values that it is given.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <typename FloatType>
|
||||
class StatisticsAccumulator
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Constructs a new StatisticsAccumulator. */
|
||||
StatisticsAccumulator() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Add a new value to the accumulator.
|
||||
This will update all running statistics accordingly.
|
||||
*/
|
||||
void addValue (FloatType v) noexcept
|
||||
{
|
||||
jassert (juce_isfinite (v));
|
||||
|
||||
sum += v;
|
||||
sumSquares += v * v;
|
||||
++count;
|
||||
|
||||
if (v > maximum) maximum = v;
|
||||
if (v < minimum) minimum = v;
|
||||
}
|
||||
|
||||
/** Reset the accumulator.
|
||||
This will reset all currently saved statistcs.
|
||||
*/
|
||||
void reset() noexcept { *this = StatisticsAccumulator<FloatType>(); }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the average (arithmetic mean) of all previously added values.
|
||||
If no values have been added yet, this will return zero.
|
||||
*/
|
||||
FloatType getAverage() const noexcept
|
||||
{
|
||||
return count > 0 ? sum / (FloatType) count
|
||||
: FloatType();
|
||||
}
|
||||
|
||||
/** Returns the variance of all previously added values.
|
||||
If no values have been added yet, this will return zero.
|
||||
*/
|
||||
FloatType getVariance() const noexcept
|
||||
{
|
||||
return count > 0 ? (sumSquares - sum * sum / (FloatType) count) / (FloatType) count
|
||||
: FloatType();
|
||||
}
|
||||
|
||||
/** Returns the standard deviation of all previously added values.
|
||||
If no values have been added yet, this will return zero.
|
||||
*/
|
||||
FloatType getStandardDeviation() const noexcept
|
||||
{
|
||||
return std::sqrt (getVariance());
|
||||
}
|
||||
|
||||
/** Returns the smallest of all previously added values.
|
||||
If no values have been added yet, this will return positive infinity.
|
||||
*/
|
||||
FloatType getMinValue() const noexcept
|
||||
{
|
||||
return minimum;
|
||||
}
|
||||
|
||||
/** Returns the largest of all previously added values.
|
||||
If no values have been added yet, this will return negative infinity.
|
||||
*/
|
||||
FloatType getMaxValue() const noexcept
|
||||
{
|
||||
return maximum;
|
||||
}
|
||||
|
||||
/** Returns how many values have been added to this accumulator. */
|
||||
size_t getCount() const noexcept
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct KahanSum
|
||||
{
|
||||
KahanSum() = default;
|
||||
operator FloatType() const noexcept { return sum; }
|
||||
|
||||
void JUCE_NO_ASSOCIATIVE_MATH_OPTIMISATIONS operator+= (FloatType value) noexcept
|
||||
{
|
||||
FloatType correctedValue = value - error;
|
||||
FloatType newSum = sum + correctedValue;
|
||||
error = (newSum - sum) - correctedValue;
|
||||
sum = newSum;
|
||||
}
|
||||
|
||||
FloatType sum{}, error{};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
size_t count { 0 };
|
||||
KahanSum sum, sumSquares;
|
||||
FloatType minimum { std::numeric_limits<FloatType>::infinity() },
|
||||
maximum { -std::numeric_limits<FloatType>::infinity() };
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class that measures various statistics about a series of floating point
|
||||
values that it is given.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <typename FloatType>
|
||||
class StatisticsAccumulator
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Constructs a new StatisticsAccumulator. */
|
||||
StatisticsAccumulator() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Add a new value to the accumulator.
|
||||
This will update all running statistics accordingly.
|
||||
*/
|
||||
void addValue (FloatType v) noexcept
|
||||
{
|
||||
jassert (juce_isfinite (v));
|
||||
|
||||
sum += v;
|
||||
sumSquares += v * v;
|
||||
++count;
|
||||
|
||||
if (v > maximum) maximum = v;
|
||||
if (v < minimum) minimum = v;
|
||||
}
|
||||
|
||||
/** Reset the accumulator.
|
||||
This will reset all currently saved statistcs.
|
||||
*/
|
||||
void reset() noexcept { *this = StatisticsAccumulator<FloatType>(); }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the average (arithmetic mean) of all previously added values.
|
||||
If no values have been added yet, this will return zero.
|
||||
*/
|
||||
FloatType getAverage() const noexcept
|
||||
{
|
||||
return count > 0 ? sum / (FloatType) count
|
||||
: FloatType();
|
||||
}
|
||||
|
||||
/** Returns the variance of all previously added values.
|
||||
If no values have been added yet, this will return zero.
|
||||
*/
|
||||
FloatType getVariance() const noexcept
|
||||
{
|
||||
return count > 0 ? (sumSquares - sum * sum / (FloatType) count) / (FloatType) count
|
||||
: FloatType();
|
||||
}
|
||||
|
||||
/** Returns the standard deviation of all previously added values.
|
||||
If no values have been added yet, this will return zero.
|
||||
*/
|
||||
FloatType getStandardDeviation() const noexcept
|
||||
{
|
||||
return std::sqrt (getVariance());
|
||||
}
|
||||
|
||||
/** Returns the smallest of all previously added values.
|
||||
If no values have been added yet, this will return positive infinity.
|
||||
*/
|
||||
FloatType getMinValue() const noexcept
|
||||
{
|
||||
return minimum;
|
||||
}
|
||||
|
||||
/** Returns the largest of all previously added values.
|
||||
If no values have been added yet, this will return negative infinity.
|
||||
*/
|
||||
FloatType getMaxValue() const noexcept
|
||||
{
|
||||
return maximum;
|
||||
}
|
||||
|
||||
/** Returns how many values have been added to this accumulator. */
|
||||
size_t getCount() const noexcept
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct KahanSum
|
||||
{
|
||||
KahanSum() = default;
|
||||
operator FloatType() const noexcept { return sum; }
|
||||
|
||||
void JUCE_NO_ASSOCIATIVE_MATH_OPTIMISATIONS operator+= (FloatType value) noexcept
|
||||
{
|
||||
FloatType correctedValue = value - error;
|
||||
FloatType newSum = sum + correctedValue;
|
||||
error = (newSum - sum) - correctedValue;
|
||||
sum = newSum;
|
||||
}
|
||||
|
||||
FloatType sum{}, error{};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
size_t count { 0 };
|
||||
KahanSum sum, sumSquares;
|
||||
FloatType minimum { std::numeric_limits<FloatType>::infinity() },
|
||||
maximum { -std::numeric_limits<FloatType>::infinity() };
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
Reference in New Issue
Block a user