mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Squashed 'src/beast/' content from commit 43e6d34
git-subtree-dir: src/beast
git-subtree-split: 43e6d345e4
This commit is contained in:
1016
modules/beast_core/maths/beast_BigInteger.cpp
Normal file
1016
modules/beast_core/maths/beast_BigInteger.cpp
Normal file
File diff suppressed because it is too large
Load Diff
322
modules/beast_core/maths/beast_BigInteger.h
Normal file
322
modules/beast_core/maths/beast_BigInteger.h
Normal file
@@ -0,0 +1,322 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_BIGINTEGER_H_INCLUDED
|
||||
#define BEAST_BIGINTEGER_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
class BEAST_API BigInteger : LeakChecked <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& other);
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
BigInteger (BigInteger&& other) noexcept;
|
||||
BigInteger& operator= (BigInteger&& other) noexcept;
|
||||
#endif
|
||||
|
||||
/** Destructor. */
|
||||
~BigInteger();
|
||||
|
||||
//==============================================================================
|
||||
/** Copies another BigInteger onto this one. */
|
||||
BigInteger& operator= (const BigInteger& other);
|
||||
|
||||
/** Swaps the internal contents of this with another object. */
|
||||
void swapWith (BigInteger& other) 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 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;
|
||||
|
||||
//==============================================================================
|
||||
/** Resets the value to 0. */
|
||||
void clear();
|
||||
|
||||
/** 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;
|
||||
|
||||
//==============================================================================
|
||||
// All the standard arithmetic ops...
|
||||
|
||||
BigInteger& operator+= (const BigInteger& other);
|
||||
BigInteger& operator-= (const BigInteger& other);
|
||||
BigInteger& operator*= (const BigInteger& other);
|
||||
BigInteger& operator/= (const BigInteger& other);
|
||||
BigInteger& operator|= (const BigInteger& other);
|
||||
BigInteger& operator&= (const BigInteger& other);
|
||||
BigInteger& operator^= (const BigInteger& other);
|
||||
BigInteger& operator%= (const BigInteger& other);
|
||||
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& other) const;
|
||||
BigInteger operator- (const BigInteger& other) const;
|
||||
BigInteger operator* (const BigInteger& other) const;
|
||||
BigInteger operator/ (const BigInteger& other) const;
|
||||
BigInteger operator| (const BigInteger& other) const;
|
||||
BigInteger operator& (const BigInteger& other) const;
|
||||
BigInteger operator^ (const BigInteger& other) const;
|
||||
BigInteger operator% (const BigInteger& other) const;
|
||||
BigInteger operator<< (int numBitsToShift) const;
|
||||
BigInteger operator>> (int numBitsToShift) const;
|
||||
|
||||
bool operator== (const BigInteger& other) const noexcept;
|
||||
bool operator!= (const BigInteger& other) const noexcept;
|
||||
bool operator< (const BigInteger& other) const noexcept;
|
||||
bool operator<= (const BigInteger& other) const noexcept;
|
||||
bool operator> (const BigInteger& other) const noexcept;
|
||||
bool operator>= (const BigInteger& other) 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 one passed-in.
|
||||
*/
|
||||
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);
|
||||
|
||||
//==============================================================================
|
||||
/** 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;
|
||||
|
||||
//==============================================================================
|
||||
/** 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 (const String& 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:
|
||||
//==============================================================================
|
||||
HeapBlock <uint32> values;
|
||||
size_t numValues;
|
||||
int highestBit;
|
||||
bool negative;
|
||||
|
||||
void ensureSize (size_t numVals);
|
||||
void shiftLeft (int bits, int startBit);
|
||||
void shiftRight (int bits, int startBit);
|
||||
};
|
||||
|
||||
/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */
|
||||
OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value);
|
||||
|
||||
//==============================================================================
|
||||
#ifndef DOXYGEN
|
||||
// For backwards compatibility, BitArray is defined as an alias for BigInteger.
|
||||
typedef BigInteger BitArray;
|
||||
#endif
|
||||
|
||||
|
||||
#endif // BEAST_BIGINTEGER_H_INCLUDED
|
||||
1162
modules/beast_core/maths/beast_Expression.cpp
Normal file
1162
modules/beast_core/maths/beast_Expression.cpp
Normal file
File diff suppressed because it is too large
Load Diff
264
modules/beast_core/maths/beast_Expression.h
Normal file
264
modules/beast_core/maths/beast_Expression.h
Normal file
@@ -0,0 +1,264 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_EXPRESSION_H_INCLUDED
|
||||
#define BEAST_EXPRESSION_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
class BEAST_API Expression
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a simple expression with a value of 0. */
|
||||
Expression();
|
||||
|
||||
/** Destructor. */
|
||||
~Expression();
|
||||
|
||||
/** Creates a simple expression with a specified constant value. */
|
||||
explicit Expression (double constant);
|
||||
|
||||
/** Creates a copy of an expression. */
|
||||
Expression (const Expression& other);
|
||||
|
||||
/** Copies another expression. */
|
||||
Expression& operator= (const Expression& other);
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
Expression (Expression&& other) noexcept;
|
||||
Expression& operator= (Expression&& other) noexcept;
|
||||
#endif
|
||||
|
||||
/** Creates an expression by parsing a string.
|
||||
If there's a syntax error in the string, this will throw a ParseError exception.
|
||||
@throws ParseError
|
||||
*/
|
||||
explicit Expression (const String& stringToParse);
|
||||
|
||||
/** Returns a string version of the expression. */
|
||||
String toString() const;
|
||||
|
||||
/** Returns an expression which is an addtion operation of two existing expressions. */
|
||||
Expression operator+ (const Expression& other) const;
|
||||
/** Returns an expression which is a subtraction operation of two existing expressions. */
|
||||
Expression operator- (const Expression& other) const;
|
||||
/** Returns an expression which is a multiplication operation of two existing expressions. */
|
||||
Expression operator* (const Expression& other) const;
|
||||
/** Returns an expression which is a division operation of two existing expressions. */
|
||||
Expression operator/ (const Expression& other) 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 the string, this will throw a ParseError exception.
|
||||
@throws ParseError
|
||||
*/
|
||||
static Expression parse (String::CharPointerType& stringToParse);
|
||||
|
||||
//==============================================================================
|
||||
/** When evaluating an Expression object, this class is used to resolve symbols and
|
||||
perform functions that the expression uses.
|
||||
*/
|
||||
class BEAST_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() {}
|
||||
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;
|
||||
|
||||
//==============================================================================
|
||||
/** An exception that can be thrown by Expression::parse(). */
|
||||
class ParseError : public std::exception
|
||||
{
|
||||
public:
|
||||
ParseError (const String& message);
|
||||
|
||||
String description;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** 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;
|
||||
friend class Term;
|
||||
friend struct Helpers;
|
||||
friend class ScopedPointer<Term>;
|
||||
friend class SharedPtr<Term>;
|
||||
SharedPtr<Term> term;
|
||||
|
||||
explicit Expression (Term*);
|
||||
};
|
||||
|
||||
#endif // BEAST_EXPRESSION_H_INCLUDED
|
||||
387
modules/beast_core/maths/beast_Interval.h
Normal file
387
modules/beast_core/maths/beast_Interval.h
Normal file
@@ -0,0 +1,387 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_INTERVAL_H_INCLUDED
|
||||
#define BEAST_INTERVAL_H_INCLUDED
|
||||
|
||||
/** A half-open interval.
|
||||
|
||||
This represents the half-open interval [begin, end) over the scalar
|
||||
type of template parameter `Ty`. It may also be considered as the
|
||||
specification of a subset of a 1-dimensional Euclidean space.
|
||||
|
||||
@tparam Ty A scalar numerical type.
|
||||
*/
|
||||
template <class Ty>
|
||||
class Interval
|
||||
{
|
||||
public:
|
||||
typedef Ty value_type;
|
||||
|
||||
/** The empty interval.
|
||||
*/
|
||||
static const Interval none;
|
||||
|
||||
/** Create an uninitialized interval.
|
||||
*/
|
||||
Interval ()
|
||||
{
|
||||
}
|
||||
|
||||
/** Create an interval with the specified values.
|
||||
*/
|
||||
Interval (Ty begin, Ty end)
|
||||
: m_begin (begin)
|
||||
, m_end (end)
|
||||
{
|
||||
}
|
||||
|
||||
/** Create an interval from another interval.
|
||||
*/
|
||||
Interval (Interval const& other)
|
||||
: m_begin (other.m_begin)
|
||||
, m_end (other.m_end)
|
||||
{
|
||||
}
|
||||
|
||||
/** Assign from another interval.
|
||||
|
||||
@param other The interval to assign from.
|
||||
|
||||
@return A reference to this interval.
|
||||
*/
|
||||
Interval& operator= (const Interval& other)
|
||||
{
|
||||
m_begin = other.m_begin;
|
||||
m_end = other.m_end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Compare an interval for equality.
|
||||
|
||||
Empty intervals are always equal to other empty intervals.
|
||||
|
||||
@param rhs The other interval to compare.
|
||||
|
||||
@return `true` if this interval is equal to the specified interval.
|
||||
*/
|
||||
bool operator== (Interval const& rhs) const
|
||||
{
|
||||
return (empty () && rhs.empty ()) ||
|
||||
(m_begin == rhs.m_begin && m_end == rhs.m_end);
|
||||
}
|
||||
|
||||
/** Compare an interval for inequality.
|
||||
|
||||
@param rhs The other interval to compare.
|
||||
|
||||
@return `true` if this interval is not equal to the specified interval.
|
||||
*/
|
||||
bool operator!= (Interval const& rhs) const
|
||||
{
|
||||
return !this->operator== (rhs);
|
||||
}
|
||||
|
||||
/** Get the starting value of the interval.
|
||||
|
||||
@return The starting point of the interval.
|
||||
*/
|
||||
Ty begin () const
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
/** Get the ending value of the interval.
|
||||
|
||||
@return The ending point of the interval.
|
||||
*/
|
||||
Ty end () const
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
/** Get the Lebesque measure.
|
||||
|
||||
@return The Lebesque measure.
|
||||
*/
|
||||
Ty length () const
|
||||
{
|
||||
return empty () ? Ty () : (end () - begin ());
|
||||
}
|
||||
|
||||
//Ty count () const { return length (); } // sugar
|
||||
//Ty distance () const { return length (); } // sugar
|
||||
|
||||
/** Determine if the interval is empty.
|
||||
|
||||
@return `true` if the interval is empty.
|
||||
*/
|
||||
bool empty () const
|
||||
{
|
||||
return m_begin >= m_end;
|
||||
}
|
||||
|
||||
/** Determine if the interval is non-empty.
|
||||
|
||||
@return `true` if the interval is not empty.
|
||||
*/
|
||||
bool notEmpty () const
|
||||
{
|
||||
return m_begin < m_end;
|
||||
}
|
||||
|
||||
/** Set the starting point of the interval.
|
||||
|
||||
@param v The starting point.
|
||||
*/
|
||||
void setBegin (Ty v)
|
||||
{
|
||||
m_begin = v;
|
||||
}
|
||||
|
||||
/** Set the ending point of the interval.
|
||||
|
||||
@param v The ending point.
|
||||
*/
|
||||
void setEnd (Ty v)
|
||||
{
|
||||
m_end = v;
|
||||
}
|
||||
|
||||
/** Set the ending point relative to the starting point.
|
||||
|
||||
@param v The length of the resulting interval.
|
||||
*/
|
||||
void setLength (Ty v)
|
||||
{
|
||||
m_end = m_begin + v;
|
||||
}
|
||||
|
||||
/** Determine if a value is contained in the interval.
|
||||
|
||||
@param v The value to check.
|
||||
|
||||
@return `true` if this interval contains `v`.
|
||||
*/
|
||||
bool contains (Ty v) const
|
||||
{
|
||||
return notEmpty () && v >= m_begin && v < m_end;
|
||||
}
|
||||
|
||||
/** Determine if this interval intersects another interval.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return `true` if the intervals intersect.
|
||||
*/
|
||||
template <class To>
|
||||
bool intersects (Interval <To> const& other) const
|
||||
{
|
||||
return notEmpty () && other.notEmpty () &&
|
||||
end () > other.begin () && begin () < other.end ();
|
||||
}
|
||||
|
||||
/** Determine if this interval adjoins another interval.
|
||||
|
||||
An interval is adjoint to another interval if and only if the union of the
|
||||
intervals is a single non-empty half-open subset.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return `true` if the intervals are adjoint.
|
||||
*/
|
||||
template <class To>
|
||||
bool adjoins (Interval <To> const& other) const
|
||||
{
|
||||
return (empty () != other.empty ()) ||
|
||||
(notEmpty () && end () >= other.begin ()
|
||||
&& begin () <= other.end ());
|
||||
}
|
||||
|
||||
/** Determine if this interval is disjoint from another interval.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return `true` if the intervals are disjoint.
|
||||
*/
|
||||
bool disjoint (Interval const& other) const
|
||||
{
|
||||
return !intersects (other);
|
||||
}
|
||||
|
||||
/** Determine if this interval is a superset of another interval.
|
||||
|
||||
An interval A is a superset of interval B if B is empty or if A fully
|
||||
contains B.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return `true` if this is a superset of `other`.
|
||||
*/
|
||||
template <class To>
|
||||
bool superset_of (Interval <To> const& other) const
|
||||
{
|
||||
return other.empty () ||
|
||||
(notEmpty () && begin () <= other.begin ()
|
||||
&& end () >= other.end ());
|
||||
}
|
||||
|
||||
/** Determine if this interval is a proper superset of another interval.
|
||||
|
||||
An interval A is a proper superset of interval B if A is a superset of
|
||||
B and A is not equal to B.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return `true` if this interval is a proper superset of `other`.
|
||||
*/
|
||||
template <class To>
|
||||
bool proper_superset_of (Interval <To> const& other) const
|
||||
{
|
||||
return this->superset_of (other) && this->operator != (other);
|
||||
}
|
||||
|
||||
/** Determine if this interval is a subset of another interval.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return `true` if this interval is a subset of `other`.
|
||||
*/
|
||||
template <class To>
|
||||
bool subset_of (Interval <To> const& other) const
|
||||
{
|
||||
return other.superset_of (*this);
|
||||
}
|
||||
|
||||
/** Determine if this interval is a proper subset of another interval.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return `true` if this interval is a proper subset of `other`.
|
||||
*/
|
||||
template <class To>
|
||||
bool proper_subset_of (Interval <To> const& other) const
|
||||
{
|
||||
return other.proper_superset_of (*this);
|
||||
}
|
||||
|
||||
/** Return the intersection of this interval with another interval.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return The intersection of the intervals.
|
||||
*/
|
||||
template <class To>
|
||||
Interval intersection (Interval <To> const& other) const
|
||||
{
|
||||
return Interval (std::max (begin (), other.begin ()),
|
||||
std::min (end (), other.end ()));
|
||||
}
|
||||
|
||||
/** Determine the smallest interval that contains both intervals.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return The simple union of the intervals.
|
||||
*/
|
||||
template <class To>
|
||||
Interval simple_union (Interval <To> const& other) const
|
||||
{
|
||||
return Interval (
|
||||
std::min (other.normalized ().begin (), normalized ().begin ()),
|
||||
std::max (other.normalized ().end (), normalized ().end ()));
|
||||
}
|
||||
|
||||
/** Calculate the single-interval union.
|
||||
|
||||
The result is empty if the union cannot be represented as a
|
||||
single half-open interval.
|
||||
|
||||
@param other The other interval.
|
||||
|
||||
@return The simple union of the intervals.
|
||||
*/
|
||||
template <class To>
|
||||
Interval single_union (Interval <To> const& other) const
|
||||
{
|
||||
if (empty ())
|
||||
return other;
|
||||
|
||||
else if (other.empty ())
|
||||
return *this;
|
||||
|
||||
else if (end () < other.begin () || begin () > other.end ())
|
||||
return none;
|
||||
|
||||
else
|
||||
return Interval (std::min (begin (), other.begin ()),
|
||||
std::max (end (), other.end ()));
|
||||
}
|
||||
|
||||
/** Determine if the interval is correctly ordered.
|
||||
|
||||
@return `true` if the interval is correctly ordered.
|
||||
*/
|
||||
bool normal () const
|
||||
{
|
||||
return end () >= begin ();
|
||||
}
|
||||
|
||||
/** Return a normalized interval.
|
||||
|
||||
@return The normalized interval.
|
||||
*/
|
||||
Interval normalized () const
|
||||
{
|
||||
if (normal ())
|
||||
return *this;
|
||||
else
|
||||
return Interval (end (), begin ());
|
||||
}
|
||||
|
||||
/** Clamp a value to the interval.
|
||||
|
||||
@param v The value to clamp.
|
||||
|
||||
@return The clamped result.
|
||||
*/
|
||||
template <typename Tv>
|
||||
Ty clamp (Tv v) const
|
||||
{
|
||||
// These conditionals are carefully ordered so
|
||||
// that if m_begin == m_end, value is assigned m_begin.
|
||||
if (v > end ())
|
||||
v = end () - (std::numeric_limits <Tv>::is_integer ? 1 :
|
||||
std::numeric_limits <Tv>::epsilon ());
|
||||
|
||||
if (v < begin ())
|
||||
v = begin ();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
private:
|
||||
Ty m_begin;
|
||||
Ty m_end;
|
||||
};
|
||||
|
||||
template <typename Ty>
|
||||
const Interval<Ty> Interval<Ty>::none = Interval<Ty> (Ty (), Ty ());
|
||||
|
||||
#endif
|
||||
84
modules/beast_core/maths/beast_Math.h
Normal file
84
modules/beast_core/maths/beast_Math.h
Normal file
@@ -0,0 +1,84 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MATH_H_INCLUDED
|
||||
#define BEAST_MATH_H_INCLUDED
|
||||
|
||||
//
|
||||
// Miscellaneous mathematical calculations
|
||||
//
|
||||
|
||||
// Calculate the bin for a value given the bin size.
|
||||
// This correctly handles negative numbers. For example
|
||||
// if value == -1 then calc_bin returns -1.
|
||||
template <typename Ty>
|
||||
inline Ty calc_bin (Ty value, int size)
|
||||
{
|
||||
if (value >= 0)
|
||||
return value / size;
|
||||
else
|
||||
return (value - size + 1) / size;
|
||||
}
|
||||
|
||||
// Given a number and a bin size, this returns the first
|
||||
// corresponding value of the bin associated with the given number.
|
||||
// It correctly handles negative numbers. For example,
|
||||
// if value == -1 then calc_bin always returns -size
|
||||
template <typename Ty>
|
||||
inline Ty calc_bin_start (Ty value, int size)
|
||||
{
|
||||
return calc_bin (value, size) * size;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T pi () noexcept
|
||||
{
|
||||
return 3.14159265358979;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T twoPi () noexcept
|
||||
{
|
||||
return 6.28318530717958;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T oneOverTwoPi () noexcept
|
||||
{
|
||||
return 0.1591549430918955;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline T degreesToRadians (U degrees)
|
||||
{
|
||||
return T (degrees * 0.0174532925199433);
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline T radiansToDegrees (U radians)
|
||||
{
|
||||
T deg = T (radians * U (57.29577951308238));
|
||||
|
||||
if (deg < 0)
|
||||
deg += 360;
|
||||
|
||||
return deg;
|
||||
}
|
||||
|
||||
#endif
|
||||
515
modules/beast_core/maths/beast_MathsFunctions.h
Normal file
515
modules/beast_core/maths/beast_MathsFunctions.h
Normal file
@@ -0,0 +1,515 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MATHSFUNCTIONS_H_INCLUDED
|
||||
#define BEAST_MATHSFUNCTIONS_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This file sets up some handy mathematical typdefs and functions.
|
||||
*/
|
||||
|
||||
//==============================================================================
|
||||
// Definitions for the int8, int16, int32, int64 and pointer_sized_int types.
|
||||
|
||||
/** A platform-independent 8-bit signed integer type. */
|
||||
typedef signed char int8;
|
||||
/** A platform-independent 8-bit unsigned integer type. */
|
||||
typedef unsigned char uint8;
|
||||
/** A platform-independent 16-bit signed integer type. */
|
||||
typedef signed short int16;
|
||||
/** A platform-independent 16-bit unsigned integer type. */
|
||||
typedef unsigned short uint16;
|
||||
/** A platform-independent 32-bit signed integer type. */
|
||||
typedef signed int int32;
|
||||
/** A platform-independent 32-bit unsigned integer type. */
|
||||
typedef unsigned int uint32;
|
||||
|
||||
#if BEAST_MSVC
|
||||
/** A platform-independent 64-bit integer type. */
|
||||
typedef __int64 int64;
|
||||
/** A platform-independent 64-bit unsigned integer type. */
|
||||
typedef unsigned __int64 uint64;
|
||||
/** A platform-independent macro for writing 64-bit literals, needed because
|
||||
different compilers have different syntaxes for this.
|
||||
|
||||
E.g. writing literal64bit (0x1000000000) will translate to 0x1000000000LL for
|
||||
GCC, or 0x1000000000 for MSVC.
|
||||
*/
|
||||
#define literal64bit(longLiteral) ((__int64) longLiteral)
|
||||
#else
|
||||
/** A platform-independent 64-bit integer type. */
|
||||
typedef long long int64;
|
||||
/** A platform-independent 64-bit unsigned integer type. */
|
||||
typedef unsigned long long uint64;
|
||||
/** A platform-independent macro for writing 64-bit literals, needed because
|
||||
different compilers have different syntaxes for this.
|
||||
|
||||
E.g. writing literal64bit (0x1000000000) will translate to 0x1000000000LL for
|
||||
GCC, or 0x1000000000 for MSVC.
|
||||
*/
|
||||
#define literal64bit(longLiteral) (longLiteral##LL)
|
||||
#endif
|
||||
|
||||
|
||||
#if BEAST_64BIT
|
||||
/** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
||||
typedef int64 pointer_sized_int;
|
||||
/** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
||||
typedef uint64 pointer_sized_uint;
|
||||
#elif BEAST_MSVC
|
||||
/** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
||||
typedef _W64 int pointer_sized_int;
|
||||
/** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
||||
typedef _W64 unsigned int pointer_sized_uint;
|
||||
#else
|
||||
/** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
||||
typedef int pointer_sized_int;
|
||||
/** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
||||
typedef unsigned int pointer_sized_uint;
|
||||
#endif
|
||||
|
||||
#if BEAST_MSVC
|
||||
typedef pointer_sized_int ssize_t;
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// Some indispensible min/max functions
|
||||
|
||||
/** Returns the larger of two values. */
|
||||
template <typename Type>
|
||||
inline Type bmax (const Type a, const Type b) { return (a < b) ? b : a; }
|
||||
|
||||
/** Returns the larger of three values. */
|
||||
template <typename Type>
|
||||
inline Type bmax (const Type a, const Type b, const Type c) { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
|
||||
|
||||
/** Returns the larger of four values. */
|
||||
template <typename Type>
|
||||
inline Type bmax (const Type a, const Type b, const Type c, const Type d) { return bmax (a, bmax (b, c, d)); }
|
||||
|
||||
/** Returns the smaller of two values. */
|
||||
template <typename Type>
|
||||
inline Type bmin (const Type a, const Type b) { return (b < a) ? b : a; }
|
||||
|
||||
/** Returns the smaller of three values. */
|
||||
template <typename Type>
|
||||
inline Type bmin (const Type a, const Type b, const Type c) { return (b < a) ? ((c < b) ? c : b) : ((c < a) ? c : a); }
|
||||
|
||||
/** Returns the smaller of four values. */
|
||||
template <typename Type>
|
||||
inline Type bmin (const Type a, const Type b, const Type c, const Type d) { return bmin (a, bmin (b, c, d)); }
|
||||
|
||||
/** Scans an array of values, returning the minimum value that it contains. */
|
||||
template <typename Type>
|
||||
const Type findMinimum (const Type* data, int numValues)
|
||||
{
|
||||
if (numValues <= 0)
|
||||
return Type();
|
||||
|
||||
Type result (*data++);
|
||||
|
||||
while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
|
||||
{
|
||||
const Type& v = *data++;
|
||||
if (v < result) result = v;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Scans an array of values, returning the maximum value that it contains. */
|
||||
template <typename Type>
|
||||
const Type findMaximum (const Type* values, int numValues)
|
||||
{
|
||||
if (numValues <= 0)
|
||||
return Type();
|
||||
|
||||
Type result (*values++);
|
||||
|
||||
while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
|
||||
{
|
||||
const Type& v = *values++;
|
||||
if (result < v) result = v;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Scans an array of values, returning the minimum and maximum values that it contains. */
|
||||
template <typename Type>
|
||||
void findMinAndMax (const Type* values, int numValues, Type& lowest, Type& highest)
|
||||
{
|
||||
if (numValues <= 0)
|
||||
{
|
||||
lowest = Type();
|
||||
highest = Type();
|
||||
}
|
||||
else
|
||||
{
|
||||
Type mn (*values++);
|
||||
Type mx (mn);
|
||||
|
||||
while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
|
||||
{
|
||||
const Type& v = *values++;
|
||||
|
||||
if (mx < v) mx = v;
|
||||
if (v < mn) mn = v;
|
||||
}
|
||||
|
||||
lowest = mn;
|
||||
highest = mx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Constrains a value to keep it within a given range.
|
||||
|
||||
This will check that the specified value lies between the lower and upper bounds
|
||||
specified, and if not, will return the nearest value that would be in-range. Effectively,
|
||||
it's like calling bmax (lowerLimit, bmin (upperLimit, value)).
|
||||
|
||||
Note that it expects that lowerLimit <= upperLimit. If this isn't true,
|
||||
the results will be unpredictable.
|
||||
|
||||
@param lowerLimit the minimum value to return
|
||||
@param upperLimit the maximum value to return
|
||||
@param valueToConstrain the value to try to return
|
||||
@returns the closest value to valueToConstrain which lies between lowerLimit
|
||||
and upperLimit (inclusive)
|
||||
@see blimit0To, bmin, bmax
|
||||
*/
|
||||
template <typename Type>
|
||||
inline Type blimit (const Type lowerLimit,
|
||||
const Type upperLimit,
|
||||
const Type valueToConstrain) noexcept
|
||||
{
|
||||
bassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable..
|
||||
|
||||
return (valueToConstrain < lowerLimit) ? lowerLimit
|
||||
: ((upperLimit < valueToConstrain) ? upperLimit
|
||||
: valueToConstrain);
|
||||
}
|
||||
|
||||
/** Returns true if a value is at least zero, and also below a specified upper limit.
|
||||
This is basically a quicker way to write:
|
||||
@code valueToTest >= 0 && valueToTest < upperLimit
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type>
|
||||
inline bool isPositiveAndBelow (Type valueToTest, Type upperLimit) noexcept
|
||||
{
|
||||
bassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero..
|
||||
return Type() <= valueToTest && valueToTest < upperLimit;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool isPositiveAndBelow (const int valueToTest, const int upperLimit) noexcept
|
||||
{
|
||||
bassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
|
||||
return static_cast <unsigned int> (valueToTest) < static_cast <unsigned int> (upperLimit);
|
||||
}
|
||||
|
||||
/** Returns true if a value is at least zero, and also less than or equal to a specified upper limit.
|
||||
This is basically a quicker way to write:
|
||||
@code valueToTest >= 0 && valueToTest <= upperLimit
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type>
|
||||
inline bool isPositiveAndNotGreaterThan (Type valueToTest, Type upperLimit) noexcept
|
||||
{
|
||||
bassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero..
|
||||
return Type() <= valueToTest && valueToTest <= upperLimit;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool isPositiveAndNotGreaterThan (const int valueToTest, const int upperLimit) noexcept
|
||||
{
|
||||
bassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
|
||||
return static_cast <unsigned int> (valueToTest) <= static_cast <unsigned int> (upperLimit);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Handy function to swap two values. */
|
||||
template <typename Type>
|
||||
inline void swapVariables (Type& variable1, Type& variable2)
|
||||
{
|
||||
std::swap (variable1, variable2);
|
||||
}
|
||||
|
||||
/** Handy function for getting the number of elements in a simple const C array.
|
||||
E.g.
|
||||
@code
|
||||
static int myArray[] = { 1, 2, 3 };
|
||||
|
||||
int numElements = numElementsInArray (myArray) // returns 3
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type, int N>
|
||||
inline int numElementsInArray (Type (&array)[N])
|
||||
{
|
||||
(void) array; // (required to avoid a spurious warning in MS compilers)
|
||||
(void) sizeof (0[array]); // This line should cause an error if you pass an object with a user-defined subscript operator
|
||||
return N;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Some useful maths functions that aren't always present with all compilers and build settings.
|
||||
|
||||
/** Using beast_hypot is easier than dealing with the different types of hypot function
|
||||
that are provided by the various platforms and compilers. */
|
||||
template <typename Type>
|
||||
inline Type beast_hypot (Type a, Type b) noexcept
|
||||
{
|
||||
#if BEAST_MSVC
|
||||
return static_cast <Type> (_hypot (a, b));
|
||||
#else
|
||||
return static_cast <Type> (hypot (a, b));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** 64-bit abs function. */
|
||||
inline int64 abs64 (const int64 n) noexcept
|
||||
{
|
||||
return (n >= 0) ? n : -n;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** A predefined value for Pi, at double-precision.
|
||||
@see float_Pi
|
||||
*/
|
||||
const double double_Pi = 3.1415926535897932384626433832795;
|
||||
|
||||
/** A predefined value for Pi, at single-precision.
|
||||
@see double_Pi
|
||||
*/
|
||||
const float float_Pi = 3.14159265358979323846f;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** The isfinite() method seems to vary between platforms, so this is a
|
||||
platform-independent function for it.
|
||||
*/
|
||||
template <typename FloatingPointType>
|
||||
inline bool beast_isfinite (FloatingPointType value)
|
||||
{
|
||||
#if BEAST_WINDOWS
|
||||
return _finite (value);
|
||||
#elif BEAST_ANDROID
|
||||
return isfinite (value);
|
||||
#else
|
||||
return std::isfinite (value);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if BEAST_MSVC
|
||||
#pragma optimize ("t", off)
|
||||
#ifndef __INTEL_COMPILER
|
||||
#pragma float_control (precise, on, push)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is faster than using the normal c++ cast to convert a float to an int, and
|
||||
it will round the value to the nearest integer, rather than rounding it down
|
||||
like the normal cast does.
|
||||
|
||||
Note that this routine gets its speed at the expense of some accuracy, and when
|
||||
rounding values whose floating point component is exactly 0.5, odd numbers and
|
||||
even numbers will be rounded up or down differently.
|
||||
*/
|
||||
template <typename FloatType>
|
||||
inline int roundToInt (const FloatType value) noexcept
|
||||
{
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma float_control (precise, on, push)
|
||||
#endif
|
||||
|
||||
union { int asInt[2]; double asDouble; } n;
|
||||
n.asDouble = ((double) value) + 6755399441055744.0;
|
||||
|
||||
#if BEAST_BIG_ENDIAN
|
||||
return n.asInt [1];
|
||||
#else
|
||||
return n.asInt [0];
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BEAST_MSVC
|
||||
#ifndef __INTEL_COMPILER
|
||||
#pragma float_control (pop)
|
||||
#endif
|
||||
#pragma optimize ("", on) // resets optimisations to the project defaults
|
||||
#endif
|
||||
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works
|
||||
fine for values above zero, but negative numbers are rounded the wrong way.
|
||||
*/
|
||||
inline int roundToIntAccurate (const double value) noexcept
|
||||
{
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma float_control (pop)
|
||||
#endif
|
||||
|
||||
return roundToInt (value + 1.5e-8);
|
||||
}
|
||||
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is faster than using the normal c++ cast to convert a double to an int, and
|
||||
it will round the value to the nearest integer, rather than rounding it down
|
||||
like the normal cast does.
|
||||
|
||||
Note that this routine gets its speed at the expense of some accuracy, and when
|
||||
rounding values whose floating point component is exactly 0.5, odd numbers and
|
||||
even numbers will be rounded up or down differently. For a more accurate conversion,
|
||||
see roundDoubleToIntAccurate().
|
||||
*/
|
||||
inline int roundDoubleToInt (const double value) noexcept
|
||||
{
|
||||
return roundToInt (value);
|
||||
}
|
||||
|
||||
/** Fast floating-point-to-integer conversion.
|
||||
|
||||
This is faster than using the normal c++ cast to convert a float to an int, and
|
||||
it will round the value to the nearest integer, rather than rounding it down
|
||||
like the normal cast does.
|
||||
|
||||
Note that this routine gets its speed at the expense of some accuracy, and when
|
||||
rounding values whose floating point component is exactly 0.5, odd numbers and
|
||||
even numbers will be rounded up or down differently.
|
||||
*/
|
||||
inline int roundFloatToInt (const float value) noexcept
|
||||
{
|
||||
return roundToInt (value);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the specified integer is a power-of-two.
|
||||
*/
|
||||
template <typename IntegerType>
|
||||
bool isPowerOfTwo (IntegerType value)
|
||||
{
|
||||
return (value & (value - 1)) == 0;
|
||||
}
|
||||
|
||||
/** Returns the smallest power-of-two which is equal to or greater than the given integer.
|
||||
*/
|
||||
inline int nextPowerOfTwo (int n) noexcept
|
||||
{
|
||||
--n;
|
||||
n |= (n >> 1);
|
||||
n |= (n >> 2);
|
||||
n |= (n >> 4);
|
||||
n |= (n >> 8);
|
||||
n |= (n >> 16);
|
||||
return n + 1;
|
||||
}
|
||||
|
||||
/** Performs a modulo operation, but can cope with the dividend being negative.
|
||||
The divisor must be greater than zero.
|
||||
*/
|
||||
template <typename IntegerType>
|
||||
IntegerType negativeAwareModulo (IntegerType dividend, const IntegerType divisor) noexcept
|
||||
{
|
||||
bassert (divisor > 0);
|
||||
dividend %= divisor;
|
||||
return (dividend < 0) ? (dividend + divisor) : dividend;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if (BEAST_INTEL && BEAST_32BIT) || defined (DOXYGEN)
|
||||
/** This macro can be applied to a float variable to check whether it contains a denormalised
|
||||
value, and to normalise it if necessary.
|
||||
On CPUs that aren't vulnerable to denormalisation problems, this will have no effect.
|
||||
*/
|
||||
#define BEAST_UNDENORMALISE(x) x += 1.0f; x -= 1.0f;
|
||||
#else
|
||||
#define BEAST_UNDENORMALISE(x)
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/** This namespace contains a few template classes for helping work out class type variations.
|
||||
*/
|
||||
namespace TypeHelpers
|
||||
{
|
||||
#if BEAST_VC8_OR_EARLIER
|
||||
#define PARAMETER_TYPE(type) const type&
|
||||
#else
|
||||
/** The ParameterType struct is used to find the best type to use when passing some kind
|
||||
of object as a parameter.
|
||||
|
||||
Of course, this is only likely to be useful in certain esoteric template situations.
|
||||
|
||||
Because "typename TypeHelpers::ParameterType<SomeClass>::type" is a bit of a mouthful, there's
|
||||
a PARAMETER_TYPE(SomeClass) macro that you can use to get the same effect.
|
||||
|
||||
E.g. "myFunction (PARAMETER_TYPE (int), PARAMETER_TYPE (MyObject))"
|
||||
would evaluate to "myfunction (int, const MyObject&)", keeping any primitive types as
|
||||
pass-by-value, but passing objects as a const reference, to avoid copying.
|
||||
*/
|
||||
template <typename Type> struct ParameterType { typedef const Type& type; };
|
||||
|
||||
#if ! DOXYGEN
|
||||
template <typename Type> struct ParameterType <Type&> { typedef Type& type; };
|
||||
template <typename Type> struct ParameterType <Type*> { typedef Type* type; };
|
||||
template <> struct ParameterType <char> { typedef char type; };
|
||||
template <> struct ParameterType <unsigned char> { typedef unsigned char type; };
|
||||
template <> struct ParameterType <short> { typedef short type; };
|
||||
template <> struct ParameterType <unsigned short> { typedef unsigned short type; };
|
||||
template <> struct ParameterType <int> { typedef int type; };
|
||||
template <> struct ParameterType <unsigned int> { typedef unsigned int type; };
|
||||
template <> struct ParameterType <long> { typedef long type; };
|
||||
template <> struct ParameterType <unsigned long> { typedef unsigned long type; };
|
||||
template <> struct ParameterType <int64> { typedef int64 type; };
|
||||
template <> struct ParameterType <uint64> { typedef uint64 type; };
|
||||
template <> struct ParameterType <bool> { typedef bool type; };
|
||||
template <> struct ParameterType <float> { typedef float type; };
|
||||
template <> struct ParameterType <double> { typedef double type; };
|
||||
#endif
|
||||
|
||||
/** A helpful macro to simplify the use of the ParameterType template.
|
||||
@see ParameterType
|
||||
*/
|
||||
#define PARAMETER_TYPE(a) typename TypeHelpers::ParameterType<a>::type
|
||||
#endif
|
||||
|
||||
|
||||
/** These templates are designed to take a type, and if it's a double, they return a double
|
||||
type; for anything else, they return a float type.
|
||||
*/
|
||||
template <typename Type> struct SmallestFloatType { typedef float type; };
|
||||
template <> struct SmallestFloatType <double> { typedef double type; };
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
||||
#endif // BEAST_MATHSFUNCTIONS_H_INCLUDED
|
||||
487
modules/beast_core/maths/beast_MurmurHash.cpp
Normal file
487
modules/beast_core/maths/beast_MurmurHash.cpp
Normal file
@@ -0,0 +1,487 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// http://code.google.com/p/smhasher/
|
||||
|
||||
namespace Murmur
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Platform-specific functions and macros
|
||||
|
||||
// Microsoft Visual Studio
|
||||
|
||||
#if BEAST_MSVC
|
||||
|
||||
#define ROTL32(x,y) _rotl(x,y)
|
||||
#define ROTL64(x,y) _rotl64(x,y)
|
||||
|
||||
#define BIG_CONSTANT(x) (x)
|
||||
|
||||
// Other compilers
|
||||
|
||||
#else
|
||||
|
||||
static inline uint32_t rotl32 ( uint32_t x, int8_t r )
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
}
|
||||
|
||||
static inline uint64_t rotl64 ( uint64_t x, int8_t r )
|
||||
{
|
||||
return (x << r) | (x >> (64 - r));
|
||||
}
|
||||
|
||||
#define ROTL32(x,y) rotl32(x,y)
|
||||
#define ROTL64(x,y) rotl64(x,y)
|
||||
|
||||
#define BIG_CONSTANT(x) (x##LLU)
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Block read - if your platform needs to do endian-swapping or can only
|
||||
// handle aligned reads, do the conversion here
|
||||
|
||||
static forcedinline uint32_t getblock ( const uint32_t* p, int i )
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
|
||||
static forcedinline uint64_t getblock ( const uint64_t* p, int i )
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finalization mix - force all bits of a hash block to avalanche
|
||||
|
||||
static forcedinline uint32_t fmix ( uint32_t h )
|
||||
{
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
//----------
|
||||
|
||||
static forcedinline uint64_t fmix ( uint64_t k )
|
||||
{
|
||||
k ^= k >> 33;
|
||||
k *= BIG_CONSTANT (0xff51afd7ed558ccd);
|
||||
k ^= k >> 33;
|
||||
k *= BIG_CONSTANT (0xc4ceb9fe1a85ec53);
|
||||
k ^= k >> 33;
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MurmurHash3_x86_32 ( const void* key, int len,
|
||||
uint32_t seed, void* out )
|
||||
{
|
||||
const uint8_t* data = (const uint8_t*)key;
|
||||
const int nblocks = len / 4;
|
||||
|
||||
uint32_t h1 = seed;
|
||||
|
||||
uint32_t c1 = 0xcc9e2d51;
|
||||
uint32_t c2 = 0x1b873593;
|
||||
|
||||
//----------
|
||||
// body
|
||||
|
||||
const uint32_t* blocks = (const uint32_t*) (data + nblocks * 4);
|
||||
|
||||
for (int i = -nblocks; i; i++)
|
||||
{
|
||||
uint32_t k1 = getblock (blocks, i);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = ROTL32 (k1, 15);
|
||||
k1 *= c2;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = ROTL32 (h1, 13);
|
||||
h1 = h1 * 5 + 0xe6546b64;
|
||||
}
|
||||
|
||||
//----------
|
||||
// tail
|
||||
|
||||
const uint8_t* tail = (const uint8_t*) (data + nblocks * 4);
|
||||
|
||||
uint32_t k1 = 0;
|
||||
|
||||
switch (len & 3)
|
||||
{
|
||||
case 3:
|
||||
k1 ^= tail[2] << 16;
|
||||
|
||||
case 2:
|
||||
k1 ^= tail[1] << 8;
|
||||
|
||||
case 1:
|
||||
k1 ^= tail[0];
|
||||
k1 *= c1;
|
||||
k1 = ROTL32 (k1, 15);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
};
|
||||
|
||||
//----------
|
||||
// finalization
|
||||
|
||||
h1 ^= len;
|
||||
|
||||
h1 = fmix (h1);
|
||||
|
||||
* (uint32_t*)out = h1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MurmurHash3_x86_128 ( const void* key, const int len,
|
||||
uint32_t seed, void* out )
|
||||
{
|
||||
const uint8_t* data = (const uint8_t*)key;
|
||||
const int nblocks = len / 16;
|
||||
|
||||
uint32_t h1 = seed;
|
||||
uint32_t h2 = seed;
|
||||
uint32_t h3 = seed;
|
||||
uint32_t h4 = seed;
|
||||
|
||||
uint32_t c1 = 0x239b961b;
|
||||
uint32_t c2 = 0xab0e9789;
|
||||
uint32_t c3 = 0x38b34ae5;
|
||||
uint32_t c4 = 0xa1e38b93;
|
||||
|
||||
//----------
|
||||
// body
|
||||
|
||||
const uint32_t* blocks = (const uint32_t*) (data + nblocks * 16);
|
||||
|
||||
for (int i = -nblocks; i; i++)
|
||||
{
|
||||
uint32_t k1 = getblock (blocks, i * 4 + 0);
|
||||
uint32_t k2 = getblock (blocks, i * 4 + 1);
|
||||
uint32_t k3 = getblock (blocks, i * 4 + 2);
|
||||
uint32_t k4 = getblock (blocks, i * 4 + 3);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = ROTL32 (k1, 15);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
|
||||
h1 = ROTL32 (h1, 19);
|
||||
h1 += h2;
|
||||
h1 = h1 * 5 + 0x561ccd1b;
|
||||
|
||||
k2 *= c2;
|
||||
k2 = ROTL32 (k2, 16);
|
||||
k2 *= c3;
|
||||
h2 ^= k2;
|
||||
|
||||
h2 = ROTL32 (h2, 17);
|
||||
h2 += h3;
|
||||
h2 = h2 * 5 + 0x0bcaa747;
|
||||
|
||||
k3 *= c3;
|
||||
k3 = ROTL32 (k3, 17);
|
||||
k3 *= c4;
|
||||
h3 ^= k3;
|
||||
|
||||
h3 = ROTL32 (h3, 15);
|
||||
h3 += h4;
|
||||
h3 = h3 * 5 + 0x96cd1c35;
|
||||
|
||||
k4 *= c4;
|
||||
k4 = ROTL32 (k4, 18);
|
||||
k4 *= c1;
|
||||
h4 ^= k4;
|
||||
|
||||
h4 = ROTL32 (h4, 13);
|
||||
h4 += h1;
|
||||
h4 = h4 * 5 + 0x32ac3b17;
|
||||
}
|
||||
|
||||
//----------
|
||||
// tail
|
||||
|
||||
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
|
||||
|
||||
uint32_t k1 = 0;
|
||||
uint32_t k2 = 0;
|
||||
uint32_t k3 = 0;
|
||||
uint32_t k4 = 0;
|
||||
|
||||
switch (len & 15)
|
||||
{
|
||||
case 15:
|
||||
k4 ^= tail[14] << 16;
|
||||
|
||||
case 14:
|
||||
k4 ^= tail[13] << 8;
|
||||
|
||||
case 13:
|
||||
k4 ^= tail[12] << 0;
|
||||
k4 *= c4;
|
||||
k4 = ROTL32 (k4, 18);
|
||||
k4 *= c1;
|
||||
h4 ^= k4;
|
||||
|
||||
case 12:
|
||||
k3 ^= tail[11] << 24;
|
||||
|
||||
case 11:
|
||||
k3 ^= tail[10] << 16;
|
||||
|
||||
case 10:
|
||||
k3 ^= tail[ 9] << 8;
|
||||
|
||||
case 9:
|
||||
k3 ^= tail[ 8] << 0;
|
||||
k3 *= c3;
|
||||
k3 = ROTL32 (k3, 17);
|
||||
k3 *= c4;
|
||||
h3 ^= k3;
|
||||
|
||||
case 8:
|
||||
k2 ^= tail[ 7] << 24;
|
||||
|
||||
case 7:
|
||||
k2 ^= tail[ 6] << 16;
|
||||
|
||||
case 6:
|
||||
k2 ^= tail[ 5] << 8;
|
||||
|
||||
case 5:
|
||||
k2 ^= tail[ 4] << 0;
|
||||
k2 *= c2;
|
||||
k2 = ROTL32 (k2, 16);
|
||||
k2 *= c3;
|
||||
h2 ^= k2;
|
||||
|
||||
case 4:
|
||||
k1 ^= tail[ 3] << 24;
|
||||
|
||||
case 3:
|
||||
k1 ^= tail[ 2] << 16;
|
||||
|
||||
case 2:
|
||||
k1 ^= tail[ 1] << 8;
|
||||
|
||||
case 1:
|
||||
k1 ^= tail[ 0] << 0;
|
||||
k1 *= c1;
|
||||
k1 = ROTL32 (k1, 15);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
};
|
||||
|
||||
//----------
|
||||
// finalization
|
||||
|
||||
h1 ^= len;
|
||||
|
||||
h2 ^= len;
|
||||
|
||||
h3 ^= len;
|
||||
|
||||
h4 ^= len;
|
||||
|
||||
h1 += h2;
|
||||
|
||||
h1 += h3;
|
||||
|
||||
h1 += h4;
|
||||
|
||||
h2 += h1;
|
||||
|
||||
h3 += h1;
|
||||
|
||||
h4 += h1;
|
||||
|
||||
h1 = fmix (h1);
|
||||
|
||||
h2 = fmix (h2);
|
||||
|
||||
h3 = fmix (h3);
|
||||
|
||||
h4 = fmix (h4);
|
||||
|
||||
h1 += h2;
|
||||
|
||||
h1 += h3;
|
||||
|
||||
h1 += h4;
|
||||
|
||||
h2 += h1;
|
||||
|
||||
h3 += h1;
|
||||
|
||||
h4 += h1;
|
||||
|
||||
((uint32_t*)out)[0] = h1;
|
||||
|
||||
((uint32_t*)out)[1] = h2;
|
||||
|
||||
((uint32_t*)out)[2] = h3;
|
||||
|
||||
((uint32_t*)out)[3] = h4;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MurmurHash3_x64_128 ( const void* key, const int len,
|
||||
const uint32_t seed, void* out )
|
||||
{
|
||||
const uint8_t* data = (const uint8_t*)key;
|
||||
const int nblocks = len / 16;
|
||||
|
||||
uint64_t h1 = seed;
|
||||
uint64_t h2 = seed;
|
||||
|
||||
uint64_t c1 = BIG_CONSTANT (0x87c37b91114253d5);
|
||||
uint64_t c2 = BIG_CONSTANT (0x4cf5ad432745937f);
|
||||
|
||||
//----------
|
||||
// body
|
||||
|
||||
const uint64_t* blocks = (const uint64_t*) (data);
|
||||
|
||||
for (int i = 0; i < nblocks; i++)
|
||||
{
|
||||
uint64_t k1 = getblock (blocks, i * 2 + 0);
|
||||
uint64_t k2 = getblock (blocks, i * 2 + 1);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = ROTL64 (k1, 31);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
|
||||
h1 = ROTL64 (h1, 27);
|
||||
h1 += h2;
|
||||
h1 = h1 * 5 + 0x52dce729;
|
||||
|
||||
k2 *= c2;
|
||||
k2 = ROTL64 (k2, 33);
|
||||
k2 *= c1;
|
||||
h2 ^= k2;
|
||||
|
||||
h2 = ROTL64 (h2, 31);
|
||||
h2 += h1;
|
||||
h2 = h2 * 5 + 0x38495ab5;
|
||||
}
|
||||
|
||||
//----------
|
||||
// tail
|
||||
|
||||
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
|
||||
|
||||
uint64_t k1 = 0;
|
||||
uint64_t k2 = 0;
|
||||
|
||||
switch (len & 15)
|
||||
{
|
||||
case 15:
|
||||
k2 ^= uint64_t (tail[14]) << 48;
|
||||
|
||||
case 14:
|
||||
k2 ^= uint64_t (tail[13]) << 40;
|
||||
|
||||
case 13:
|
||||
k2 ^= uint64_t (tail[12]) << 32;
|
||||
|
||||
case 12:
|
||||
k2 ^= uint64_t (tail[11]) << 24;
|
||||
|
||||
case 11:
|
||||
k2 ^= uint64_t (tail[10]) << 16;
|
||||
|
||||
case 10:
|
||||
k2 ^= uint64_t (tail[ 9]) << 8;
|
||||
|
||||
case 9:
|
||||
k2 ^= uint64_t (tail[ 8]) << 0;
|
||||
k2 *= c2;
|
||||
k2 = ROTL64 (k2, 33);
|
||||
k2 *= c1;
|
||||
h2 ^= k2;
|
||||
|
||||
case 8:
|
||||
k1 ^= uint64_t (tail[ 7]) << 56;
|
||||
|
||||
case 7:
|
||||
k1 ^= uint64_t (tail[ 6]) << 48;
|
||||
|
||||
case 6:
|
||||
k1 ^= uint64_t (tail[ 5]) << 40;
|
||||
|
||||
case 5:
|
||||
k1 ^= uint64_t (tail[ 4]) << 32;
|
||||
|
||||
case 4:
|
||||
k1 ^= uint64_t (tail[ 3]) << 24;
|
||||
|
||||
case 3:
|
||||
k1 ^= uint64_t (tail[ 2]) << 16;
|
||||
|
||||
case 2:
|
||||
k1 ^= uint64_t (tail[ 1]) << 8;
|
||||
|
||||
case 1:
|
||||
k1 ^= uint64_t (tail[ 0]) << 0;
|
||||
k1 *= c1;
|
||||
k1 = ROTL64 (k1, 31);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
};
|
||||
|
||||
//----------
|
||||
// finalization
|
||||
|
||||
h1 ^= len;
|
||||
|
||||
h2 ^= len;
|
||||
|
||||
h1 += h2;
|
||||
|
||||
h2 += h1;
|
||||
|
||||
h1 = fmix (h1);
|
||||
|
||||
h2 = fmix (h2);
|
||||
|
||||
h1 += h2;
|
||||
|
||||
h2 += h1;
|
||||
|
||||
((uint64_t*)out)[0] = h1;
|
||||
|
||||
((uint64_t*)out)[1] = h2;
|
||||
}
|
||||
|
||||
}
|
||||
66
modules/beast_core/maths/beast_MurmurHash.h
Normal file
66
modules/beast_core/maths/beast_MurmurHash.h
Normal file
@@ -0,0 +1,66 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MURMURHASH_H_INCLUDED
|
||||
#define BEAST_MURMURHASH_H_INCLUDED
|
||||
|
||||
// Original source code links in .cpp file
|
||||
|
||||
// This file depends on some Beast declarations and defines
|
||||
|
||||
namespace Murmur
|
||||
{
|
||||
|
||||
extern void MurmurHash3_x86_32 (const void* key, int len, uint32 seed, void* out);
|
||||
extern void MurmurHash3_x86_128 (const void* key, int len, uint32 seed, void* out);
|
||||
extern void MurmurHash3_x64_128 (const void* key, int len, uint32 seed, void* out);
|
||||
|
||||
// Uses Beast to choose an appropriate routine
|
||||
|
||||
// This handy template deduces which size hash is desired
|
||||
template <typename HashType>
|
||||
inline void Hash (const void* key, int len, uint32 seed, HashType* out)
|
||||
{
|
||||
switch (8 * sizeof (HashType))
|
||||
{
|
||||
case 32:
|
||||
MurmurHash3_x86_32 (key, len, seed, out);
|
||||
break;
|
||||
|
||||
#if BEAST_64BIT
|
||||
case 128:
|
||||
MurmurHash3_x64_128 (key, len, seed, out);
|
||||
break;
|
||||
|
||||
#else
|
||||
case 128:
|
||||
MurmurHash3_x86_128 (key, len, seed, out);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
Throw (std::runtime_error ("invalid key size in MurmurHash"));
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
187
modules/beast_core/maths/beast_Random.cpp
Normal file
187
modules/beast_core/maths/beast_Random.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
Random::Random (const int64 seedValue) noexcept
|
||||
: seed (seedValue)
|
||||
{
|
||||
nextInt (); // fixes a bug where the first int is always 0
|
||||
}
|
||||
|
||||
Random::Random()
|
||||
: seed (1)
|
||||
{
|
||||
setSeedRandomly();
|
||||
}
|
||||
|
||||
Random::~Random() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void Random::setSeed (const int64 newSeed) noexcept
|
||||
{
|
||||
seed = newSeed;
|
||||
|
||||
nextInt (); // fixes a bug where the first int is always 0
|
||||
}
|
||||
|
||||
void Random::combineSeed (const int64 seedValue) noexcept
|
||||
{
|
||||
seed ^= nextInt64() ^ seedValue;
|
||||
}
|
||||
|
||||
void Random::setSeedRandomly()
|
||||
{
|
||||
static int64 globalSeed = 0;
|
||||
|
||||
combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
|
||||
combineSeed (Time::getMillisecondCounter());
|
||||
combineSeed (Time::getHighResolutionTicks());
|
||||
combineSeed (Time::getHighResolutionTicksPerSecond());
|
||||
combineSeed (Time::currentTimeMillis());
|
||||
globalSeed ^= seed;
|
||||
|
||||
nextInt (); // fixes a bug where the first int is always 0
|
||||
}
|
||||
|
||||
Random& Random::getSystemRandom() noexcept
|
||||
{
|
||||
static Random sysRand;
|
||||
return sysRand;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int Random::nextInt() noexcept
|
||||
{
|
||||
seed = (seed * literal64bit (0x5deece66d) + 11) & literal64bit (0xffffffffffff);
|
||||
|
||||
return (int) (seed >> 16);
|
||||
}
|
||||
|
||||
int Random::nextInt (const int maxValue) noexcept
|
||||
{
|
||||
bassert (maxValue > 0);
|
||||
return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
|
||||
}
|
||||
|
||||
int64 Random::nextInt64() noexcept
|
||||
{
|
||||
return (((int64) nextInt()) << 32) | (int64) (uint64) (uint32) nextInt();
|
||||
}
|
||||
|
||||
bool Random::nextBool() noexcept
|
||||
{
|
||||
return (nextInt() & 0x40000000) != 0;
|
||||
}
|
||||
|
||||
float Random::nextFloat() noexcept
|
||||
{
|
||||
return static_cast <uint32> (nextInt()) / (float) 0xffffffff;
|
||||
}
|
||||
|
||||
double Random::nextDouble() noexcept
|
||||
{
|
||||
return static_cast <uint32> (nextInt()) / (double) 0xffffffff;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
class RandomTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
RandomTests() : UnitTest ("Random", "beast") {}
|
||||
|
||||
void runTest()
|
||||
{
|
||||
beginTestCase ("Random");
|
||||
|
||||
for (int j = 10; --j >= 0;)
|
||||
{
|
||||
Random r;
|
||||
r.setSeedRandomly();
|
||||
|
||||
for (int i = 20; --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;
|
||||
133
modules/beast_core/maths/beast_Random.h
Normal file
133
modules/beast_core/maths/beast_Random.h
Normal file
@@ -0,0 +1,133 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_RANDOM_H_INCLUDED
|
||||
#define BEAST_RANDOM_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A random number generator.
|
||||
|
||||
You can create a Random object and use it to generate a sequence of random numbers.
|
||||
*/
|
||||
class BEAST_API Random : LeakChecked <Random>
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a Random object based on a seed value.
|
||||
|
||||
For a given seed value, the subsequent numbers generated by this object
|
||||
will be predictable, so a good idea is to set this value based
|
||||
on the time, e.g.
|
||||
|
||||
new Random (Time::currentTimeMillis())
|
||||
*/
|
||||
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 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 to 1.0
|
||||
*/
|
||||
float nextFloat() noexcept;
|
||||
|
||||
/** Returns the next random floating-point number.
|
||||
|
||||
@returns a random value in the range 0 to 1.0
|
||||
*/
|
||||
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;
|
||||
|
||||
/** 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;
|
||||
};
|
||||
|
||||
|
||||
#endif // BEAST_RANDOM_H_INCLUDED
|
||||
259
modules/beast_core/maths/beast_Range.h
Normal file
259
modules/beast_core/maths/beast_Range.h
Normal file
@@ -0,0 +1,259 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_RANGE_H_INCLUDED
|
||||
#define BEAST_RANGE_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** A general-purpose range object, that simply represents any linear range with
|
||||
a start and end point.
|
||||
|
||||
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.
|
||||
*/
|
||||
template <typename ValueType>
|
||||
class Range
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Constructs an empty range. */
|
||||
Range() noexcept : start(), end()
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructs a range with given start and end values. */
|
||||
Range (const ValueType startValue, const ValueType endValue) noexcept
|
||||
: start (startValue), end (bmax (startValue, endValue))
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructs a copy of another range. */
|
||||
Range (const Range& other) noexcept
|
||||
: start (other.start), end (other.end)
|
||||
{
|
||||
}
|
||||
|
||||
/** Copies another range object. */
|
||||
Range& operator= (Range other) noexcept
|
||||
{
|
||||
start = other.start;
|
||||
end = other.end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Returns the range that lies between two positions (in either order). */
|
||||
static Range between (const ValueType position1, const ValueType position2) noexcept
|
||||
{
|
||||
return position1 < position2 ? Range (position1, position2)
|
||||
: Range (position2, position1);
|
||||
}
|
||||
|
||||
/** Returns a range with the specified start position and a length of zero. */
|
||||
static Range emptyRange (const ValueType start) noexcept
|
||||
{
|
||||
return Range (start, start);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the start of the range. */
|
||||
inline ValueType getStart() const noexcept { return start; }
|
||||
|
||||
/** Returns the length of the range. */
|
||||
inline ValueType getLength() const noexcept { return end - start; }
|
||||
|
||||
/** Returns the end of the range. */
|
||||
inline ValueType getEnd() const noexcept { return end; }
|
||||
|
||||
/** Returns true if the range has a length of zero. */
|
||||
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.
|
||||
*/
|
||||
Range withStart (const ValueType newStart) const noexcept
|
||||
{
|
||||
return Range (newStart, bmax (newStart, end));
|
||||
}
|
||||
|
||||
/** Returns a range with the same length as this one, but moved to have the given start position. */
|
||||
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.
|
||||
*/
|
||||
Range withEnd (const ValueType newEnd) const noexcept
|
||||
{
|
||||
return Range (bmin (start, newEnd), newEnd);
|
||||
}
|
||||
|
||||
/** Returns a range with the same length as this one, but moved to have the given end position. */
|
||||
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 + bmax (ValueType(), newLength);
|
||||
}
|
||||
|
||||
/** Returns a range with the same start as this one, but a different length.
|
||||
Lengths less than zero are treated as zero.
|
||||
*/
|
||||
Range withLength (const ValueType newLength) const noexcept
|
||||
{
|
||||
return Range (start, start + newLength);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** 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.
|
||||
*/
|
||||
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. */
|
||||
Range operator- (const ValueType amountToSubtract) const noexcept
|
||||
{
|
||||
return Range (start - amountToSubtract, end - amountToSubtract);
|
||||
}
|
||||
|
||||
bool operator== (Range other) const noexcept { return start == other.start && end == other.end; }
|
||||
bool operator!= (Range other) const noexcept { return start != other.start || end != other.end; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the given position lies inside this range. */
|
||||
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 blimit (start, end, value);
|
||||
}
|
||||
|
||||
/** Returns true if the given range lies entirely inside this range. */
|
||||
bool contains (Range other) const noexcept
|
||||
{
|
||||
return start <= other.start && end >= other.end;
|
||||
}
|
||||
|
||||
/** Returns true if the given range intersects this one. */
|
||||
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. */
|
||||
Range getIntersectionWith (Range other) const noexcept
|
||||
{
|
||||
return Range (bmax (start, other.start),
|
||||
bmin (end, other.end));
|
||||
}
|
||||
|
||||
/** Returns the smallest range that contains both this one and the other one. */
|
||||
Range getUnionWith (Range other) const noexcept
|
||||
{
|
||||
return Range (bmin (start, other.start),
|
||||
bmax (end, other.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 (blimit (start, end - otherLen, rangeToConstrain.getStart()));
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ValueType start, end;
|
||||
};
|
||||
|
||||
|
||||
#endif // BEAST_RANGE_H_INCLUDED
|
||||
144
modules/beast_core/maths/beast_uint24.h
Normal file
144
modules/beast_core/maths/beast_uint24.h
Normal file
@@ -0,0 +1,144 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_UINT24_H_INCLUDED
|
||||
#define BEAST_UINT24_H_INCLUDED
|
||||
|
||||
/** A 24 bit unsigned integer.
|
||||
We try to be as compatible as possible with built in types.
|
||||
*/
|
||||
class uint24 : public SafeBool <uint24>
|
||||
{
|
||||
public:
|
||||
enum { mask = 0xffffff };
|
||||
inline uint24 () noexcept { /* uninitialized */ }
|
||||
inline uint24 (uint24 const& other) noexcept : m_value (other.m_value) { }
|
||||
inline uint24& operator= (uint24 const& other) noexcept { m_value = other.m_value; return *this; }
|
||||
template <typename IntegralType> inline uint24 (IntegralType value) noexcept : m_value (value & mask) { }
|
||||
template <typename IntegralType> inline uint24& operator= (IntegralType value) noexcept { m_value = value & mask; return *this; }
|
||||
inline uint32 get () const noexcept { return m_value; }
|
||||
inline bool asBoolean () const noexcept { return m_value != 0; }
|
||||
inline operator String () const { return String (m_value); }
|
||||
inline uint24& operator++ () noexcept { (++m_value) &= mask; return *this; }
|
||||
inline uint24& operator-- () noexcept { (--m_value) &= mask; return *this; }
|
||||
inline uint24 operator++ (int) noexcept { return uint24 (m_value + 1); }
|
||||
inline uint24 operator-- (int) noexcept { return uint24 (m_value - 1); }
|
||||
inline uint24& operator~ () { m_value = (~ m_value) & mask; return *this; }
|
||||
inline uint24& operator+= (uint24 const& rhs) { m_value = (m_value + rhs.m_value) & mask; return *this; }
|
||||
inline uint24& operator-= (uint24 const& rhs) { m_value = (m_value - rhs.m_value) & mask; return *this; }
|
||||
inline uint24& operator*= (uint24 const& rhs) { m_value = (m_value * rhs.m_value) & mask; return *this; }
|
||||
inline uint24& operator/= (uint24 const& rhs) { m_value = (m_value / rhs.m_value) & mask; return *this; }
|
||||
inline uint24& operator|= (uint24 const& rhs) { m_value = (m_value | rhs.m_value) & mask; return *this; }
|
||||
inline uint24& operator&= (uint24 const& rhs) { m_value = (m_value & rhs.m_value) & mask; return *this; }
|
||||
inline uint24& operator^= (uint24 const& rhs) { m_value = (m_value ^ rhs.m_value) & mask; return *this; }
|
||||
template <typename IntegralType> inline uint24& operator+= (IntegralType value) { m_value = (m_value + value) & mask; return *this; }
|
||||
template <typename IntegralType> inline uint24& operator-= (IntegralType value) { m_value = (m_value - value) & mask; return *this; }
|
||||
template <typename IntegralType> inline uint24& operator*= (IntegralType value) { m_value = (m_value * value) & mask; return *this; }
|
||||
template <typename IntegralType> inline uint24& operator/= (IntegralType value) { m_value = (m_value / value) & mask; return *this; }
|
||||
template <typename IntegralType> inline uint24& operator|= (IntegralType value) { m_value = (m_value | value) & mask; return *this; }
|
||||
template <typename IntegralType> inline uint24& operator&= (IntegralType value) { m_value = (m_value & value) & mask; return *this; }
|
||||
template <typename IntegralType> inline uint24& operator^= (IntegralType value) { m_value = (m_value ^ value) & mask; return *this; }
|
||||
template <typename IntegralType> inline bool operator== (IntegralType value) const noexcept { return m_value == value; }
|
||||
template <typename IntegralType> inline bool operator!= (IntegralType value) const noexcept { return m_value != value; }
|
||||
template <typename IntegralType> inline bool operator< (IntegralType value) const noexcept { return m_value < value; }
|
||||
template <typename IntegralType> inline bool operator> (IntegralType value) const noexcept { return m_value > value; }
|
||||
template <typename IntegralType> inline bool operator<= (IntegralType value) const noexcept { return m_value <= value; }
|
||||
template <typename IntegralType> inline bool operator>= (IntegralType value) const noexcept { return m_value >= value; }
|
||||
|
||||
// Construct from raw bytes
|
||||
static uint24 from3RawBytes (void const* buf)
|
||||
{
|
||||
uint24 result;
|
||||
uint8* const raw (reinterpret_cast <uint8*> (&result.m_value));
|
||||
uint8 const* const data (reinterpret_cast <uint8 const*> (buf));
|
||||
|
||||
#if BEAST_LITTLE_ENDIAN
|
||||
raw [0] = data [0];
|
||||
raw [1] = data [1];
|
||||
raw [2] = data [2];
|
||||
raw [3] = 0;
|
||||
#else
|
||||
raw [0] = 0;
|
||||
raw [1] = data [0];
|
||||
raw [2] = data [1];
|
||||
raw [3] = data [2];
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
uint24* operator&();
|
||||
uint24 const* operator&() const;
|
||||
|
||||
friend struct detail::SwapBytes <uint24>;
|
||||
|
||||
inline uint8& operator[] (int index) noexcept { bassert (index >= 0 && index < 3); return raw () [index]; }
|
||||
inline uint8 operator[] (int index) const noexcept { bassert (index >= 0 && index < 3); return raw () [index]; }
|
||||
|
||||
#if BEAST_LITTLE_ENDIAN
|
||||
inline uint8* raw () noexcept { return reinterpret_cast <uint8*> (&m_value); }
|
||||
inline uint8 const* raw () const noexcept { return reinterpret_cast <uint8 const*> (&m_value); }
|
||||
#else
|
||||
inline uint8* raw () noexcept { return reinterpret_cast <uint8*> (&m_value) + 1; }
|
||||
inline uint8 const* raw () const noexcept { return reinterpret_cast <uint8 const*> (&m_value) + 1; }
|
||||
#endif
|
||||
|
||||
uint32 m_value;
|
||||
};
|
||||
|
||||
inline uint24 const operator~ (uint24 const& value) noexcept { return uint24 (~value.get ()); }
|
||||
inline uint24 const operator+ (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () + rhs.get ()); }
|
||||
inline uint24 const operator- (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () - rhs.get ()); }
|
||||
inline uint24 const operator/ (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () / rhs.get ()); }
|
||||
inline uint24 const operator* (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () * rhs.get ()); }
|
||||
inline uint24 const operator| (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () ^ rhs.get ()); }
|
||||
inline uint24 const operator& (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () & rhs.get ()); }
|
||||
inline uint24 const operator^ (uint24 const& lhs, uint24 const& rhs) noexcept { return uint24 (lhs.get () ^ rhs.get ()); }
|
||||
inline bool operator== (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () == rhs.get (); }
|
||||
inline bool operator!= (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () != rhs.get (); }
|
||||
inline bool operator< (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () < rhs.get (); }
|
||||
inline bool operator> (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () > rhs.get (); }
|
||||
inline bool operator<= (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () <= rhs.get (); }
|
||||
inline bool operator>= (uint24 const& lhs, uint24 const& rhs) noexcept { return lhs.get () >= rhs.get (); }
|
||||
|
||||
/** SwapBytes specialization uint24. */
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <>
|
||||
struct SwapBytes <uint24>
|
||||
{
|
||||
inline uint24 const operator() (uint24 const& value) const noexcept
|
||||
{
|
||||
#if BEAST_LITTLE_ENDIAN
|
||||
uint24 result;
|
||||
result [0] = value [2];
|
||||
result [1] = value [1];
|
||||
result [2] = value [0];
|
||||
result [3] = 0;
|
||||
return result;
|
||||
#else
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user