upgrade to JUCE 5.4.3. Remove (probably) unused JUCE modules. Remove VST2 target (it's been end-of-life'd by Steinberg and by JUCE)
This commit is contained in:
@ -44,10 +44,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_ASCII (const CharPointer_ASCII& other) noexcept
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
inline CharPointer_ASCII (const CharPointer_ASCII& other) = default;
|
||||
|
||||
inline CharPointer_ASCII operator= (const CharPointer_ASCII other) noexcept
|
||||
{
|
||||
|
@ -45,10 +45,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF16 (const CharPointer_UTF16& other) noexcept
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
inline CharPointer_UTF16 (const CharPointer_UTF16& other) = default;
|
||||
|
||||
inline CharPointer_UTF16 operator= (CharPointer_UTF16 other) noexcept
|
||||
{
|
||||
|
@ -41,10 +41,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF32 (const CharPointer_UTF32& other) noexcept
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
inline CharPointer_UTF32 (const CharPointer_UTF32& other) = default;
|
||||
|
||||
inline CharPointer_UTF32 operator= (CharPointer_UTF32 other) noexcept
|
||||
{
|
||||
|
@ -41,10 +41,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF8 (const CharPointer_UTF8& other) noexcept
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
inline CharPointer_UTF8 (const CharPointer_UTF8& other) = default;
|
||||
|
||||
inline CharPointer_UTF8 operator= (CharPointer_UTF8 other) noexcept
|
||||
{
|
||||
|
@ -236,13 +236,23 @@ public:
|
||||
STRING_DOUBLE_PAIR_COMBOS (10e10),
|
||||
STRING_DOUBLE_PAIR_COMBOS (1.4962e+2),
|
||||
STRING_DOUBLE_PAIR_COMBOS (3198693.0973e4),
|
||||
STRING_DOUBLE_PAIR_COMBOS (10973097.2087e-4),
|
||||
STRING_DOUBLE_PAIR_COMBOS (10973097.2087E-4),
|
||||
STRING_DOUBLE_PAIR_COMBOS (1.3986e00006),
|
||||
STRING_DOUBLE_PAIR_COMBOS (2087.3087e+00006),
|
||||
STRING_DOUBLE_PAIR_COMBOS (6.0872e-00006),
|
||||
|
||||
// Too many sig figs. The parsing routine on MinGW gets the last
|
||||
// significant figure wrong.
|
||||
STRING_DOUBLE_PAIR_COMBOS (17654321098765432.9),
|
||||
STRING_DOUBLE_PAIR_COMBOS (183456789012345678.9),
|
||||
STRING_DOUBLE_PAIR_COMBOS (1934567890123456789.9),
|
||||
STRING_DOUBLE_PAIR_COMBOS (20345678901234567891.9),
|
||||
STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000),
|
||||
STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752e3),
|
||||
STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752e100),
|
||||
STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000e-5),
|
||||
STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000e-40),
|
||||
|
||||
STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890),
|
||||
STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890e-111)
|
||||
|
||||
@ -262,6 +272,7 @@ public:
|
||||
|
||||
{
|
||||
String nans[] = { "NaN", "-nan", "+NAN", "1.0E1024", "-1.0E-999", "1.23456789012345678901234567890e123456789"};
|
||||
|
||||
for (auto nan : nans)
|
||||
{
|
||||
auto charPtr = nan.getCharPointer();
|
||||
@ -271,6 +282,7 @@ public:
|
||||
|
||||
{
|
||||
String infs[] = { "Inf", "-inf", "INF"};
|
||||
|
||||
for (auto inf : infs)
|
||||
{
|
||||
auto charPtr = inf.getCharPointer();
|
||||
|
@ -295,6 +295,7 @@ public:
|
||||
|
||||
int numSigFigs = 0;
|
||||
bool decimalPointFound = false;
|
||||
int extraExponent = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -302,9 +303,22 @@ public:
|
||||
{
|
||||
auto digit = (int) text.getAndAdvance() - '0';
|
||||
|
||||
if (numSigFigs >= maxSignificantDigits
|
||||
|| ((numSigFigs == 0 && (! decimalPointFound)) && digit == 0))
|
||||
continue;
|
||||
if (decimalPointFound)
|
||||
{
|
||||
if (numSigFigs >= maxSignificantDigits)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (numSigFigs >= maxSignificantDigits)
|
||||
{
|
||||
++extraExponent;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (numSigFigs == 0 && digit == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
*currentCharacter++ = (char) ('0' + (char) digit);
|
||||
numSigFigs++;
|
||||
@ -323,37 +337,58 @@ public:
|
||||
|
||||
c = *text;
|
||||
|
||||
auto writeExponentDigits = [](int exponent, char* destination)
|
||||
{
|
||||
auto exponentDivisor = 100;
|
||||
|
||||
while (exponentDivisor > 1)
|
||||
{
|
||||
auto digit = exponent / exponentDivisor;
|
||||
*destination++ = (char) ('0' + (char) digit);
|
||||
exponent -= digit * exponentDivisor;
|
||||
exponentDivisor /= 10;
|
||||
}
|
||||
|
||||
*destination++ = (char) ('0' + (char) exponent);
|
||||
};
|
||||
|
||||
if ((c == 'e' || c == 'E') && numSigFigs > 0)
|
||||
{
|
||||
*currentCharacter++ = 'e';
|
||||
bool parsedExponentIsPositive = true;
|
||||
|
||||
switch (*++text)
|
||||
{
|
||||
case '-': *currentCharacter++ = '-'; // Fall-through..
|
||||
case '-': parsedExponentIsPositive = false; // Fall-through..
|
||||
case '+': ++text;
|
||||
}
|
||||
|
||||
int exponentMagnitude = 0;
|
||||
int exponent = 0;
|
||||
|
||||
while (text.isDigit())
|
||||
{
|
||||
if (currentCharacter == &buffer[bufferSize - 1])
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
auto digit = (int) text.getAndAdvance() - '0';
|
||||
|
||||
if (digit != 0 || exponentMagnitude != 0)
|
||||
{
|
||||
*currentCharacter++ = (char) ('0' + (char) digit);
|
||||
exponentMagnitude = (exponentMagnitude * 10) + digit;
|
||||
}
|
||||
if (digit != 0 || exponent != 0)
|
||||
exponent = (exponent * 10) + digit;
|
||||
}
|
||||
|
||||
if (exponentMagnitude > std::numeric_limits<double>::max_exponent10)
|
||||
exponent = extraExponent + (parsedExponentIsPositive ? exponent : -exponent);
|
||||
|
||||
if (exponent < 0)
|
||||
*currentCharacter++ = '-';
|
||||
|
||||
exponent = std::abs (exponent);
|
||||
|
||||
if (exponent > std::numeric_limits<double>::max_exponent10)
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
if (exponentMagnitude == 0)
|
||||
*currentCharacter++ = '0';
|
||||
writeExponentDigits (exponent, currentCharacter);
|
||||
}
|
||||
else if (extraExponent > 0)
|
||||
{
|
||||
*currentCharacter++ = 'e';
|
||||
writeExponentDigits (extraExponent, currentCharacter);
|
||||
}
|
||||
|
||||
#if JUCE_WINDOWS
|
||||
|
@ -28,11 +28,11 @@ Identifier::~Identifier() noexcept {}
|
||||
|
||||
Identifier::Identifier (const Identifier& other) noexcept : name (other.name) {}
|
||||
|
||||
Identifier::Identifier (Identifier&& other) noexcept : name (static_cast<String&&> (other.name)) {}
|
||||
Identifier::Identifier (Identifier&& other) noexcept : name (std::move (other.name)) {}
|
||||
|
||||
Identifier& Identifier::operator= (Identifier&& other) noexcept
|
||||
{
|
||||
name = static_cast<String&&> (other.name);
|
||||
name = std::move (other.name);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,6 @@ private:
|
||||
StringArray countryCodes;
|
||||
StringPairArray translations;
|
||||
std::unique_ptr<LocalisedStrings> fallback;
|
||||
friend struct ContainerDeletePolicy<LocalisedStrings>;
|
||||
|
||||
void loadFromText (const String&, bool ignoreCase);
|
||||
|
||||
|
@ -351,19 +351,19 @@ String::String (const CharPointer_UTF16 t) : text (StringHolder::createFromCha
|
||||
String::String (const CharPointer_UTF32 t) : text (StringHolder::createFromCharPointer (t)) {}
|
||||
String::String (const CharPointer_ASCII t) : text (StringHolder::createFromCharPointer (t)) {}
|
||||
|
||||
String::String (const CharPointer_UTF8 t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {}
|
||||
String::String (const CharPointer_UTF16 t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {}
|
||||
String::String (const CharPointer_UTF32 t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {}
|
||||
String::String (const wchar_t* const t, size_t maxChars) : text (StringHolder::createFromCharPointer (castToCharPointer_wchar_t (t), maxChars)) {}
|
||||
String::String (CharPointer_UTF8 t, size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {}
|
||||
String::String (CharPointer_UTF16 t, size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {}
|
||||
String::String (CharPointer_UTF32 t, size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {}
|
||||
String::String (const wchar_t* t, size_t maxChars) : text (StringHolder::createFromCharPointer (castToCharPointer_wchar_t (t), maxChars)) {}
|
||||
|
||||
String::String (const CharPointer_UTF8 start, const CharPointer_UTF8 end) : text (StringHolder::createFromCharPointer (start, end)) {}
|
||||
String::String (const CharPointer_UTF16 start, const CharPointer_UTF16 end) : text (StringHolder::createFromCharPointer (start, end)) {}
|
||||
String::String (const CharPointer_UTF32 start, const CharPointer_UTF32 end) : text (StringHolder::createFromCharPointer (start, end)) {}
|
||||
String::String (CharPointer_UTF8 start, CharPointer_UTF8 end) : text (StringHolder::createFromCharPointer (start, end)) {}
|
||||
String::String (CharPointer_UTF16 start, CharPointer_UTF16 end) : text (StringHolder::createFromCharPointer (start, end)) {}
|
||||
String::String (CharPointer_UTF32 start, CharPointer_UTF32 end) : text (StringHolder::createFromCharPointer (start, end)) {}
|
||||
|
||||
String::String (const std::string& s) : text (StringHolder::createFromFixedLength (s.data(), s.size())) {}
|
||||
String::String (StringRef s) : text (StringHolder::createFromCharPointer (s.text)) {}
|
||||
|
||||
String String::charToString (const juce_wchar character)
|
||||
String String::charToString (juce_wchar character)
|
||||
{
|
||||
String result (PreallocationBytes (CharPointerType::getBytesRequiredFor (character)));
|
||||
CharPointerType t (result.text);
|
||||
@ -397,7 +397,7 @@ namespace NumberToStringConverters
|
||||
}
|
||||
|
||||
// pass in a pointer to the END of a buffer..
|
||||
static char* numberToString (char* t, const int64 n) noexcept
|
||||
static char* numberToString (char* t, int64 n) noexcept
|
||||
{
|
||||
if (n >= 0)
|
||||
return printDigits (t, static_cast<uint64> (n));
|
||||
@ -414,7 +414,7 @@ namespace NumberToStringConverters
|
||||
return printDigits (t, v);
|
||||
}
|
||||
|
||||
static char* numberToString (char* t, const int n) noexcept
|
||||
static char* numberToString (char* t, int n) noexcept
|
||||
{
|
||||
if (n >= 0)
|
||||
return printDigits (t, static_cast<unsigned int> (n));
|
||||
@ -426,12 +426,12 @@ namespace NumberToStringConverters
|
||||
return t;
|
||||
}
|
||||
|
||||
static char* numberToString (char* t, const unsigned int v) noexcept
|
||||
static char* numberToString (char* t, unsigned int v) noexcept
|
||||
{
|
||||
return printDigits (t, v);
|
||||
}
|
||||
|
||||
static char* numberToString (char* t, const long n) noexcept
|
||||
static char* numberToString (char* t, long n) noexcept
|
||||
{
|
||||
if (n >= 0)
|
||||
return printDigits (t, static_cast<unsigned long> (n));
|
||||
@ -441,7 +441,7 @@ namespace NumberToStringConverters
|
||||
return t;
|
||||
}
|
||||
|
||||
static char* numberToString (char* t, const unsigned long v) noexcept
|
||||
static char* numberToString (char* t, unsigned long v) noexcept
|
||||
{
|
||||
return printDigits (t, v);
|
||||
}
|
||||
@ -455,14 +455,14 @@ namespace NumberToStringConverters
|
||||
setp (d, d + charsNeededForDouble);
|
||||
}
|
||||
|
||||
size_t writeDouble (double n, int numDecPlaces)
|
||||
size_t writeDouble (double n, int numDecPlaces, bool useScientificNotation)
|
||||
{
|
||||
{
|
||||
std::ostream o (this);
|
||||
|
||||
if (numDecPlaces > 0)
|
||||
{
|
||||
o.setf (std::ios_base::fixed);
|
||||
o.setf (useScientificNotation ? std::ios_base::scientific : std::ios_base::fixed);
|
||||
o.precision ((std::streamsize) numDecPlaces);
|
||||
}
|
||||
|
||||
@ -473,41 +473,16 @@ namespace NumberToStringConverters
|
||||
}
|
||||
};
|
||||
|
||||
static char* doubleToString (char* buffer, const int numChars, double n, int numDecPlaces, size_t& len) noexcept
|
||||
static char* doubleToString (char* buffer, double n, int numDecPlaces, bool useScientificNotation, size_t& len) noexcept
|
||||
{
|
||||
if (numDecPlaces > 0 && numDecPlaces < 7 && n > -1.0e20 && n < 1.0e20)
|
||||
{
|
||||
auto* end = buffer + numChars;
|
||||
auto* t = end;
|
||||
auto v = (int64) (std::pow (10.0, numDecPlaces) * std::abs (n) + 0.5);
|
||||
*--t = (char) 0;
|
||||
|
||||
while (numDecPlaces >= 0 || v > 0)
|
||||
{
|
||||
if (numDecPlaces == 0)
|
||||
*--t = '.';
|
||||
|
||||
*--t = (char) ('0' + (v % 10));
|
||||
|
||||
v /= 10;
|
||||
--numDecPlaces;
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
*--t = '-';
|
||||
|
||||
len = (size_t) (end - t - 1);
|
||||
return t;
|
||||
}
|
||||
|
||||
StackArrayStream strm (buffer);
|
||||
len = strm.writeDouble (n, numDecPlaces);
|
||||
len = strm.writeDouble (n, numDecPlaces, useScientificNotation);
|
||||
jassert (len <= charsNeededForDouble);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <typename IntegerType>
|
||||
static String::CharPointerType createFromInteger (const IntegerType number)
|
||||
static String::CharPointerType createFromInteger (IntegerType number)
|
||||
{
|
||||
char buffer [charsNeededForInt];
|
||||
auto* end = buffer + numElementsInArray (buffer);
|
||||
@ -515,11 +490,11 @@ namespace NumberToStringConverters
|
||||
return StringHolder::createFromFixedLength (start, (size_t) (end - start - 1));
|
||||
}
|
||||
|
||||
static String::CharPointerType createFromDouble (const double number, const int numberOfDecimalPlaces)
|
||||
static String::CharPointerType createFromDouble (double number, int numberOfDecimalPlaces, bool useScientificNotation)
|
||||
{
|
||||
char buffer [charsNeededForDouble];
|
||||
size_t len;
|
||||
auto start = doubleToString (buffer, numElementsInArray (buffer), (double) number, numberOfDecimalPlaces, len);
|
||||
auto start = doubleToString (buffer, number, numberOfDecimalPlaces, useScientificNotation, len);
|
||||
return StringHolder::createFromFixedLength (start, len);
|
||||
}
|
||||
}
|
||||
@ -534,10 +509,10 @@ String::String (uint64 number) : text (NumberToStringConverters::createF
|
||||
String::String (long number) : text (NumberToStringConverters::createFromInteger (number)) {}
|
||||
String::String (unsigned long number) : text (NumberToStringConverters::createFromInteger (number)) {}
|
||||
|
||||
String::String (float number) : text (NumberToStringConverters::createFromDouble ((double) number, 0)) {}
|
||||
String::String (double number) : text (NumberToStringConverters::createFromDouble (number, 0)) {}
|
||||
String::String (float number, int numberOfDecimalPlaces) : text (NumberToStringConverters::createFromDouble ((double) number, numberOfDecimalPlaces)) {}
|
||||
String::String (double number, int numberOfDecimalPlaces) : text (NumberToStringConverters::createFromDouble (number, numberOfDecimalPlaces)) {}
|
||||
String::String (float number) : text (NumberToStringConverters::createFromDouble ((double) number, 0, false)) {}
|
||||
String::String (double number) : text (NumberToStringConverters::createFromDouble ( number, 0, false)) {}
|
||||
String::String (float number, int numberOfDecimalPlaces, bool useScientificNotation) : text (NumberToStringConverters::createFromDouble ((double) number, numberOfDecimalPlaces, useScientificNotation)) {}
|
||||
String::String (double number, int numberOfDecimalPlaces, bool useScientificNotation) : text (NumberToStringConverters::createFromDouble ( number, numberOfDecimalPlaces, useScientificNotation)) {}
|
||||
|
||||
//==============================================================================
|
||||
int String::length() const noexcept
|
||||
@ -1392,7 +1367,7 @@ String String::replaceCharacter (const juce_wchar charToReplace, const juce_wcha
|
||||
break;
|
||||
}
|
||||
|
||||
return static_cast<String&&> (builder.result);
|
||||
return std::move (builder.result);
|
||||
}
|
||||
|
||||
String String::replaceCharacters (StringRef charactersToReplace, StringRef charactersToInsertInstead) const
|
||||
@ -1417,7 +1392,7 @@ String String::replaceCharacters (StringRef charactersToReplace, StringRef chara
|
||||
break;
|
||||
}
|
||||
|
||||
return static_cast<String&&> (builder.result);
|
||||
return std::move (builder.result);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@ -1499,7 +1474,7 @@ String String::toUpperCase() const
|
||||
++(builder.source);
|
||||
}
|
||||
|
||||
return static_cast<String&&> (builder.result);
|
||||
return std::move (builder.result);
|
||||
}
|
||||
|
||||
String String::toLowerCase() const
|
||||
@ -1517,7 +1492,7 @@ String String::toLowerCase() const
|
||||
++(builder.source);
|
||||
}
|
||||
|
||||
return static_cast<String&&> (builder.result);
|
||||
return std::move (builder.result);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@ -1782,7 +1757,7 @@ String String::retainCharacters (StringRef charactersToRetain) const
|
||||
}
|
||||
|
||||
builder.write (0);
|
||||
return static_cast<String&&> (builder.result);
|
||||
return std::move (builder.result);
|
||||
}
|
||||
|
||||
String String::removeCharacters (StringRef charactersToRemove) const
|
||||
@ -1803,7 +1778,7 @@ String String::removeCharacters (StringRef charactersToRemove) const
|
||||
break;
|
||||
}
|
||||
|
||||
return static_cast<String&&> (builder.result);
|
||||
return std::move (builder.result);
|
||||
}
|
||||
|
||||
String String::initialSectionContainingOnly (StringRef permittedCharacters) const
|
||||
@ -2005,7 +1980,7 @@ String String::createStringFromData (const void* const unknownData, int size)
|
||||
|
||||
StringCreationHelper builder ((size_t) numChars);
|
||||
|
||||
auto src = (const uint16*) (data + 2);
|
||||
auto src = reinterpret_cast<const uint16*> (data + 2);
|
||||
|
||||
if (CharPointer_UTF16::isByteOrderMarkBigEndian (data))
|
||||
{
|
||||
@ -2019,7 +1994,7 @@ String String::createStringFromData (const void* const unknownData, int size)
|
||||
}
|
||||
|
||||
builder.write (0);
|
||||
return static_cast<String&&> (builder.result);
|
||||
return std::move (builder.result);
|
||||
}
|
||||
|
||||
auto* start = (const char*) data;
|
||||
@ -2047,7 +2022,7 @@ struct StringEncodingConverter
|
||||
{
|
||||
auto& source = const_cast<String&> (s);
|
||||
|
||||
typedef typename CharPointerType_Dest::CharType DestChar;
|
||||
using DestChar = typename CharPointerType_Dest::CharType;
|
||||
|
||||
if (source.isEmpty())
|
||||
return CharPointerType_Dest (reinterpret_cast<const DestChar*> (&emptyChar));
|
||||
@ -2075,19 +2050,19 @@ struct StringEncodingConverter
|
||||
template <>
|
||||
struct StringEncodingConverter<CharPointer_UTF8, CharPointer_UTF8>
|
||||
{
|
||||
static CharPointer_UTF8 convert (const String& source) noexcept { return CharPointer_UTF8 ((CharPointer_UTF8::CharType*) source.getCharPointer().getAddress()); }
|
||||
static CharPointer_UTF8 convert (const String& source) noexcept { return CharPointer_UTF8 (reinterpret_cast<CharPointer_UTF8::CharType*> (source.getCharPointer().getAddress())); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StringEncodingConverter<CharPointer_UTF16, CharPointer_UTF16>
|
||||
{
|
||||
static CharPointer_UTF16 convert (const String& source) noexcept { return CharPointer_UTF16 ((CharPointer_UTF16::CharType*) source.getCharPointer().getAddress()); }
|
||||
static CharPointer_UTF16 convert (const String& source) noexcept { return CharPointer_UTF16 (reinterpret_cast<CharPointer_UTF16::CharType*> (source.getCharPointer().getAddress())); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StringEncodingConverter<CharPointer_UTF32, CharPointer_UTF32>
|
||||
{
|
||||
static CharPointer_UTF32 convert (const String& source) noexcept { return CharPointer_UTF32 ((CharPointer_UTF32::CharType*) source.getCharPointer().getAddress()); }
|
||||
static CharPointer_UTF32 convert (const String& source) noexcept { return CharPointer_UTF32 (reinterpret_cast<CharPointer_UTF32::CharType*> (source.getCharPointer().getAddress())); }
|
||||
};
|
||||
|
||||
CharPointer_UTF8 String::toUTF8() const { return StringEncodingConverter<CharPointerType, CharPointer_UTF8 >::convert (*this); }
|
||||
@ -2210,12 +2185,128 @@ StringRef::StringRef (String::CharPointerType stringLiteral) noexcept : text (s
|
||||
StringRef::StringRef (const String& string) noexcept : text (string.getCharPointer()) {}
|
||||
StringRef::StringRef (const std::string& string) : StringRef (string.c_str()) {}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
static String reduceLengthOfFloatString (const String& input)
|
||||
{
|
||||
const auto start = input.getCharPointer();
|
||||
const auto end = start + (int) input.length();
|
||||
auto trimStart = end;
|
||||
auto trimEnd = trimStart;
|
||||
auto exponentTrimStart = end;
|
||||
auto exponentTrimEnd = exponentTrimStart;
|
||||
|
||||
decltype (*start) currentChar = '\0';
|
||||
|
||||
for (auto c = end - 1; c > start; --c)
|
||||
{
|
||||
currentChar = *c;
|
||||
|
||||
if (currentChar == '0' && c + 1 == trimStart)
|
||||
{
|
||||
--trimStart;
|
||||
}
|
||||
else if (currentChar == '.')
|
||||
{
|
||||
if (trimStart == c + 1 && trimStart != end && *trimStart == '0')
|
||||
++trimStart;
|
||||
|
||||
break;
|
||||
}
|
||||
else if (currentChar == 'e' || currentChar == 'E')
|
||||
{
|
||||
auto cNext = c + 1;
|
||||
|
||||
if (cNext != end)
|
||||
{
|
||||
if (*cNext == '-')
|
||||
++cNext;
|
||||
|
||||
exponentTrimStart = cNext;
|
||||
|
||||
if (cNext != end && *cNext == '+')
|
||||
++cNext;
|
||||
|
||||
exponentTrimEnd = cNext;
|
||||
}
|
||||
|
||||
while (cNext != end && *cNext++ == '0')
|
||||
exponentTrimEnd = cNext;
|
||||
|
||||
if (exponentTrimEnd == end)
|
||||
exponentTrimStart = c;
|
||||
|
||||
trimStart = c;
|
||||
trimEnd = trimStart;
|
||||
}
|
||||
}
|
||||
|
||||
if ((trimStart != trimEnd && currentChar == '.') || exponentTrimStart != exponentTrimEnd)
|
||||
{
|
||||
if (trimStart == trimEnd)
|
||||
return String (start, exponentTrimStart) + String (exponentTrimEnd, end);
|
||||
|
||||
if (exponentTrimStart == exponentTrimEnd)
|
||||
return String (start, trimStart) + String (trimEnd, end);
|
||||
|
||||
if (trimEnd == exponentTrimStart)
|
||||
return String (start, trimStart) + String (exponentTrimEnd, end);
|
||||
|
||||
return String (start, trimStart) + String (trimEnd, exponentTrimStart) + String (exponentTrimEnd, end);
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
static String serialiseDouble (double input)
|
||||
{
|
||||
auto absInput = std::abs (input);
|
||||
|
||||
if (absInput >= 1.0e6 || absInput <= 1.0e-5)
|
||||
return reduceLengthOfFloatString ({ input, 15, true });
|
||||
|
||||
int intInput = (int) input;
|
||||
|
||||
if ((double) intInput == input)
|
||||
return { input, 1 };
|
||||
|
||||
auto numberOfDecimalPlaces = [absInput]
|
||||
{
|
||||
if (absInput < 1.0)
|
||||
{
|
||||
if (absInput >= 1.0e-3)
|
||||
{
|
||||
if (absInput >= 1.0e-1) return 16;
|
||||
if (absInput >= 1.0e-2) return 17;
|
||||
return 18;
|
||||
}
|
||||
|
||||
if (absInput >= 1.0e-4) return 19;
|
||||
return 20;
|
||||
}
|
||||
|
||||
if (absInput < 1.0e3)
|
||||
{
|
||||
if (absInput < 1.0e1) return 15;
|
||||
if (absInput < 1.0e2) return 14;
|
||||
return 13;
|
||||
}
|
||||
|
||||
if (absInput < 1.0e4) return 12;
|
||||
if (absInput < 1.0e5) return 11;
|
||||
return 10;
|
||||
}();
|
||||
|
||||
return reduceLengthOfFloatString (String (input, numberOfDecimalPlaces));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
#define STRINGIFY2(X) #X
|
||||
#define STRINGIFY(X) STRINGIFY2(X)
|
||||
|
||||
#define STRINGIFY2(X) #X
|
||||
#define STRINGIFY(X) STRINGIFY2(X)
|
||||
|
||||
class StringTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
@ -2491,7 +2582,21 @@ public:
|
||||
expect (String::toHexString (data, 8, 1).equalsIgnoreCase ("01 02 03 04 0a 0b 0c 0d"));
|
||||
expect (String::toHexString (data, 8, 2).equalsIgnoreCase ("0102 0304 0a0b 0c0d"));
|
||||
|
||||
expectEquals (String (12345.67, 4), String ("12345.6700"));
|
||||
expectEquals (String (12345.67, 6), String ("12345.670000"));
|
||||
expectEquals (String (2589410.5894, 7), String ("2589410.5894000"));
|
||||
expectEquals (String (12345.67, 8), String ("12345.67000000"));
|
||||
expectEquals (String (1e19, 4), String ("10000000000000000000.0000"));
|
||||
expectEquals (String (1e-34, 36), String ("0.000000000000000000000000000000000100"));
|
||||
expectEquals (String (1.39, 1), String ("1.4"));
|
||||
|
||||
expectEquals (String (12345.67, 4, true), String ("1.2346e+04"));
|
||||
expectEquals (String (12345.67, 6, true), String ("1.234567e+04"));
|
||||
expectEquals (String (2589410.5894, 7, true), String ("2.5894106e+06"));
|
||||
expectEquals (String (12345.67, 8, true), String ("1.23456700e+04"));
|
||||
expectEquals (String (1e19, 4, true), String ("1.0000e+19"));
|
||||
expectEquals (String (1e-34, 5, true), String ("1.00000e-34"));
|
||||
expectEquals (String (1.39, 1, true), String ("1.4e+00"));
|
||||
|
||||
beginTest ("Subsections");
|
||||
String s3;
|
||||
@ -2681,6 +2786,147 @@ public:
|
||||
expect (! v2.equals (v4));
|
||||
expect (! v4.equals (v2));
|
||||
}
|
||||
|
||||
{
|
||||
beginTest ("Significant figures");
|
||||
|
||||
// Integers
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (13, 1), String ("10"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (13, 2), String ("13"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (13, 3), String ("13.0"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (13, 4), String ("13.00"));
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (19368, 1), String ("20000"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (19348, 3), String ("19300"));
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (-5, 1), String ("-5"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (-5, 3), String ("-5.00"));
|
||||
|
||||
// Zero
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (0, 1), String ("0"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (0, 2), String ("0.0"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (0, 3), String ("0.00"));
|
||||
|
||||
// Floating point
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (19.0, 1), String ("20"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (19.0, 2), String ("19"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (19.0, 3), String ("19.0"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (19.0, 4), String ("19.00"));
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (-5.45, 1), String ("-5"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (-5.45, 3), String ("-5.45"));
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (12345.6789, 9), String ("12345.6789"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (12345.6789, 8), String ("12345.679"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (12345.6789, 5), String ("12346"));
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (0.00028647, 6), String ("0.000286470"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (0.0028647, 6), String ("0.00286470"));
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (2.8647, 6), String ("2.86470"));
|
||||
|
||||
expectEquals (String::toDecimalStringWithSignificantFigures (-0.0000000000019, 1), String ("-0.000000000002"));
|
||||
}
|
||||
|
||||
{
|
||||
beginTest ("Float trimming");
|
||||
|
||||
{
|
||||
StringPairArray tests;
|
||||
tests.set ("1", "1");
|
||||
tests.set ("1.0", "1.0");
|
||||
tests.set ("-1", "-1");
|
||||
tests.set ("-100", "-100");
|
||||
tests.set ("110", "110");
|
||||
tests.set ("9090", "9090");
|
||||
tests.set ("1000.0", "1000.0");
|
||||
tests.set ("1.0", "1.0");
|
||||
tests.set ("-1.00", "-1.0");
|
||||
tests.set ("1.20", "1.2");
|
||||
tests.set ("1.300", "1.3");
|
||||
tests.set ("1.301", "1.301");
|
||||
tests.set ("1e", "1");
|
||||
tests.set ("-1e+", "-1");
|
||||
tests.set ("1e-", "1");
|
||||
tests.set ("1e0", "1");
|
||||
tests.set ("1e+0", "1");
|
||||
tests.set ("1e-0", "1");
|
||||
tests.set ("1e000", "1");
|
||||
tests.set ("1e+000", "1");
|
||||
tests.set ("-1e-000", "-1");
|
||||
tests.set ("1e100", "1e100");
|
||||
tests.set ("100e100", "100e100");
|
||||
tests.set ("100.0e0100", "100.0e100");
|
||||
tests.set ("-1e1", "-1e1");
|
||||
tests.set ("1e10", "1e10");
|
||||
tests.set ("-1e+10", "-1e10");
|
||||
tests.set ("1e-10", "1e-10");
|
||||
tests.set ("1e0010", "1e10");
|
||||
tests.set ("1e-0010", "1e-10");
|
||||
tests.set ("1e-1", "1e-1");
|
||||
tests.set ("-1.0e1", "-1.0e1");
|
||||
tests.set ("1.0e-1", "1.0e-1");
|
||||
tests.set ("1.00e-1", "1.0e-1");
|
||||
tests.set ("1.001e1", "1.001e1");
|
||||
tests.set ("1.010e+1", "1.01e1");
|
||||
tests.set ("-1.1000e1", "-1.1e1");
|
||||
|
||||
for (auto& input : tests.getAllKeys())
|
||||
expectEquals (reduceLengthOfFloatString (input), tests[input]);
|
||||
}
|
||||
|
||||
{
|
||||
std::map<double, String> tests;
|
||||
tests[1] = "1.0";
|
||||
tests[1.1] = "1.1";
|
||||
tests[1.01] = "1.01";
|
||||
tests[0.76378] = "7.6378e-1";
|
||||
tests[-10] = "-1.0e1";
|
||||
tests[10.01] = "1.001e1";
|
||||
tests[10691.01] = "1.069101e4";
|
||||
tests[0.0123] = "1.23e-2";
|
||||
tests[-3.7e-27] = "-3.7e-27";
|
||||
tests[1e+40] = "1.0e40";
|
||||
|
||||
for (auto& test : tests)
|
||||
expectEquals (reduceLengthOfFloatString (String (test.first, 15, true)), test.second);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
beginTest ("Serialisation");
|
||||
|
||||
std::map <double, String> tests;
|
||||
|
||||
tests[364] = "364.0";
|
||||
tests[1e7] = "1.0e7";
|
||||
tests[12345678901] = "1.2345678901e10";
|
||||
|
||||
tests[1234567890123456.7] = "1.234567890123457e15";
|
||||
tests[12345678.901234567] = "1.234567890123457e7";
|
||||
tests[1234567.8901234567] = "1.234567890123457e6";
|
||||
tests[123456.78901234567] = "123456.7890123457";
|
||||
tests[12345.678901234567] = "12345.67890123457";
|
||||
tests[1234.5678901234567] = "1234.567890123457";
|
||||
tests[123.45678901234567] = "123.4567890123457";
|
||||
tests[12.345678901234567] = "12.34567890123457";
|
||||
tests[1.2345678901234567] = "1.234567890123457";
|
||||
tests[0.12345678901234567] = "0.1234567890123457";
|
||||
tests[0.012345678901234567] = "0.01234567890123457";
|
||||
tests[0.0012345678901234567] = "0.001234567890123457";
|
||||
tests[0.00012345678901234567] = "0.0001234567890123457";
|
||||
tests[0.000012345678901234567] = "0.00001234567890123457";
|
||||
tests[0.0000012345678901234567] = "1.234567890123457e-6";
|
||||
tests[0.00000012345678901234567] = "1.234567890123457e-7";
|
||||
|
||||
for (auto& test : tests)
|
||||
{
|
||||
expectEquals (serialiseDouble (test.first), test.second);
|
||||
expectEquals (serialiseDouble (-test.first), "-" + test.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -153,11 +153,11 @@ public:
|
||||
toUTF32() methods let you access the string's content in any of the other formats.
|
||||
*/
|
||||
#if (JUCE_STRING_UTF_TYPE == 32)
|
||||
typedef CharPointer_UTF32 CharPointerType;
|
||||
using CharPointerType = CharPointer_UTF32;
|
||||
#elif (JUCE_STRING_UTF_TYPE == 16)
|
||||
typedef CharPointer_UTF16 CharPointerType;
|
||||
using CharPointerType = CharPointer_UTF16;
|
||||
#elif (DOXYGEN || JUCE_STRING_UTF_TYPE == 8)
|
||||
typedef CharPointer_UTF8 CharPointerType;
|
||||
using CharPointerType = CharPointer_UTF8;
|
||||
#else
|
||||
#error "You must set the value of JUCE_STRING_UTF_TYPE to be either 8, 16, or 32!"
|
||||
#endif
|
||||
@ -962,21 +962,26 @@ public:
|
||||
|
||||
/** Creates a string representing this floating-point number.
|
||||
@param floatValue the value to convert to a string
|
||||
@param numberOfDecimalPlaces if this is > 0, it will format the number using that many
|
||||
decimal places, and will not use exponent notation. If 0 or
|
||||
less, it will use exponent notation if necessary.
|
||||
@param numberOfDecimalPlaces if this is > 0 the number will be formatted using that many
|
||||
decimal places, adding trailing zeros as required. If 0 or
|
||||
less the number will be formatted using the C++ standard
|
||||
library default format, which uses scientific notation for
|
||||
large and small numbers.
|
||||
@param useScientificNotation if the number should be formatted using scientific notation
|
||||
@see getDoubleValue, getIntValue
|
||||
*/
|
||||
String (float floatValue, int numberOfDecimalPlaces);
|
||||
String (float floatValue, int numberOfDecimalPlaces, bool useScientificNotation = false);
|
||||
|
||||
/** Creates a string representing this floating-point number.
|
||||
@param doubleValue the value to convert to a string
|
||||
@param numberOfDecimalPlaces if this is > 0, it will format the number using that many
|
||||
decimal places, and will not use exponent notation. If 0 or
|
||||
less, it will use exponent notation if necessary.
|
||||
decimal places, adding trailing zeros as required, and
|
||||
will not use exponent notation. If 0 or less, it will use
|
||||
exponent notation if necessary.
|
||||
@param useScientificNotation if the number should be formatted using scientific notation
|
||||
@see getFloatValue, getIntValue
|
||||
*/
|
||||
String (double doubleValue, int numberOfDecimalPlaces);
|
||||
String (double doubleValue, int numberOfDecimalPlaces, bool useScientificNotation = false);
|
||||
|
||||
// Automatically creating a String from a bool opens up lots of nasty type conversion edge cases.
|
||||
// If you want a String representation of a bool you can cast the bool to an int first.
|
||||
@ -1056,6 +1061,131 @@ public:
|
||||
*/
|
||||
static String toHexString (const void* data, int size, int groupSize = 1);
|
||||
|
||||
/** Returns a string containing a decimal with a set number of significant figures.
|
||||
|
||||
@param number the intput number
|
||||
@param numberOfSignificantFigures the number of significant figures to use
|
||||
*/
|
||||
template <typename DecimalType>
|
||||
static String toDecimalStringWithSignificantFigures (DecimalType number, int numberOfSignificantFigures)
|
||||
{
|
||||
jassert (numberOfSignificantFigures > 0);
|
||||
|
||||
if (number == 0)
|
||||
{
|
||||
if (numberOfSignificantFigures > 1)
|
||||
{
|
||||
String result ("0.0");
|
||||
|
||||
for (int i = 2; i < numberOfSignificantFigures; ++i)
|
||||
result += "0";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return "0";
|
||||
}
|
||||
|
||||
auto numDigitsBeforePoint = (int) std::ceil (std::log10 (number < 0 ? -number : number));
|
||||
|
||||
#if JUCE_PROJUCER_LIVE_BUILD
|
||||
auto doubleNumber = (double) number;
|
||||
constexpr int bufferSize = 311;
|
||||
char buffer[bufferSize];
|
||||
auto* ptr = &(buffer[0]);
|
||||
auto* const safeEnd = ptr + (bufferSize - 1);
|
||||
auto numSigFigsParsed = 0;
|
||||
|
||||
auto writeToBuffer = [safeEnd] (char* destination, char data)
|
||||
{
|
||||
*destination++ = data;
|
||||
|
||||
if (destination == safeEnd)
|
||||
{
|
||||
*destination = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
auto truncateOrRound = [numberOfSignificantFigures] (double fractional, int sigFigsParsed)
|
||||
{
|
||||
return (sigFigsParsed == numberOfSignificantFigures - 1) ? (int) std::round (fractional)
|
||||
: (int) fractional;
|
||||
};
|
||||
|
||||
if (doubleNumber < 0)
|
||||
{
|
||||
doubleNumber *= -1;
|
||||
*ptr++ = '-';
|
||||
}
|
||||
|
||||
if (numDigitsBeforePoint > 0)
|
||||
{
|
||||
doubleNumber /= std::pow (10.0, numDigitsBeforePoint);
|
||||
|
||||
while (numDigitsBeforePoint-- > 0)
|
||||
{
|
||||
if (numSigFigsParsed == numberOfSignificantFigures)
|
||||
{
|
||||
if (writeToBuffer (ptr++, '0'))
|
||||
return buffer;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
doubleNumber *= 10;
|
||||
auto digit = truncateOrRound (doubleNumber, numSigFigsParsed);
|
||||
|
||||
if (writeToBuffer (ptr++, (char) ('0' + digit)))
|
||||
return buffer;
|
||||
|
||||
++numSigFigsParsed;
|
||||
doubleNumber -= digit;
|
||||
}
|
||||
|
||||
if (numSigFigsParsed == numberOfSignificantFigures)
|
||||
{
|
||||
*ptr++ = '\0';
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr++ = '0';
|
||||
}
|
||||
|
||||
if (writeToBuffer (ptr++, '.'))
|
||||
return buffer;
|
||||
|
||||
while (numSigFigsParsed < numberOfSignificantFigures)
|
||||
{
|
||||
doubleNumber *= 10;
|
||||
auto digit = truncateOrRound (doubleNumber, numSigFigsParsed);
|
||||
|
||||
if (writeToBuffer (ptr++, (char) ('0' + digit)))
|
||||
return buffer;
|
||||
|
||||
if (numSigFigsParsed != 0 || digit != 0)
|
||||
++numSigFigsParsed;
|
||||
|
||||
doubleNumber -= digit;
|
||||
}
|
||||
|
||||
*ptr++ = '\0';
|
||||
return buffer;
|
||||
#else
|
||||
auto shift = numberOfSignificantFigures - numDigitsBeforePoint;
|
||||
auto factor = std::pow (10.0, shift);
|
||||
auto rounded = std::round (number * factor) / factor;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision (std::max (shift, 0)) << rounded;
|
||||
return ss.str();
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the character pointer currently being used to store this string.
|
||||
|
||||
@ -1278,7 +1408,7 @@ private:
|
||||
static String createHex (uint64);
|
||||
|
||||
template <typename Type>
|
||||
static String createHex (Type n) { return createHex (static_cast<typename TypeHelpers::UnsignedTypeWithSize<sizeof (n)>::type> (n)); }
|
||||
static String createHex (Type n) { return createHex (static_cast<typename TypeHelpers::UnsignedTypeWithSize<(int) sizeof (n)>::type> (n)); }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
@ -33,7 +33,12 @@ StringArray::StringArray (const StringArray& other)
|
||||
}
|
||||
|
||||
StringArray::StringArray (StringArray&& other) noexcept
|
||||
: strings (static_cast<Array<String>&&> (other.strings))
|
||||
: strings (std::move (other.strings))
|
||||
{
|
||||
}
|
||||
|
||||
StringArray::StringArray (Array<String>&& other) noexcept
|
||||
: strings (std::move (other))
|
||||
{
|
||||
}
|
||||
|
||||
@ -80,7 +85,7 @@ StringArray& StringArray::operator= (const StringArray& other)
|
||||
|
||||
StringArray& StringArray::operator= (StringArray&& other) noexcept
|
||||
{
|
||||
strings = static_cast<Array<String>&&> (other.strings);
|
||||
strings = std::move (other.strings);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -127,19 +132,18 @@ String& StringArray::getReference (int index) noexcept
|
||||
return strings.getReference (index);
|
||||
}
|
||||
|
||||
void StringArray::add (const String& newString)
|
||||
void StringArray::add (String newString)
|
||||
{
|
||||
strings.add (newString);
|
||||
// NB: the local temp copy is to avoid a dangling pointer if the
|
||||
// argument being passed-in is a reference into this array.
|
||||
strings.add (std::move (newString));
|
||||
}
|
||||
|
||||
void StringArray::add (String&& stringToAdd)
|
||||
void StringArray::insert (int index, String newString)
|
||||
{
|
||||
strings.add (static_cast<String&&> (stringToAdd));
|
||||
}
|
||||
|
||||
void StringArray::insert (int index, const String& newString)
|
||||
{
|
||||
strings.insert (index, newString);
|
||||
// NB: the local temp copy is to avoid a dangling pointer if the
|
||||
// argument being passed-in is a reference into this array.
|
||||
strings.insert (index, std::move (newString));
|
||||
}
|
||||
|
||||
bool StringArray::addIfNotAlreadyThere (const String& newString, bool ignoreCase)
|
||||
@ -153,6 +157,8 @@ bool StringArray::addIfNotAlreadyThere (const String& newString, bool ignoreCase
|
||||
|
||||
void StringArray::addArray (const StringArray& otherArray, int startIndex, int numElementsToAdd)
|
||||
{
|
||||
jassert (this != &otherArray); // can't add from our own elements!
|
||||
|
||||
if (startIndex < 0)
|
||||
{
|
||||
jassertfalse;
|
||||
@ -168,13 +174,15 @@ void StringArray::addArray (const StringArray& otherArray, int startIndex, int n
|
||||
|
||||
void StringArray::mergeArray (const StringArray& otherArray, bool ignoreCase)
|
||||
{
|
||||
jassert (this != &otherArray); // can't add from our own elements!
|
||||
|
||||
for (auto& s : otherArray)
|
||||
addIfNotAlreadyThere (s, ignoreCase);
|
||||
}
|
||||
|
||||
void StringArray::set (int index, const String& newString)
|
||||
void StringArray::set (int index, String newString)
|
||||
{
|
||||
strings.set (index, newString);
|
||||
strings.set (index, std::move (newString));
|
||||
}
|
||||
|
||||
bool StringArray::contains (StringRef stringToLookFor, bool ignoreCase) const
|
||||
|
@ -54,6 +54,16 @@ public:
|
||||
/** Creates an array containing a list of strings. */
|
||||
StringArray (const std::initializer_list<const char*>& strings);
|
||||
|
||||
/** Creates a StringArray by moving from an Array<String> */
|
||||
StringArray (Array<String>&&) noexcept;
|
||||
|
||||
/** Creates a StringArray from an array of objects which can be implicitly converted to Strings. */
|
||||
template <typename Type>
|
||||
StringArray (const Array<Type>& stringArray)
|
||||
{
|
||||
addArray (stringArray.begin(), stringArray.end());
|
||||
}
|
||||
|
||||
/** Creates an array from a raw array of strings.
|
||||
@param strings an array of strings to add
|
||||
@param numberOfStrings how many items there are in the array
|
||||
@ -96,6 +106,14 @@ public:
|
||||
/** Move assignment operator */
|
||||
StringArray& operator= (StringArray&&) noexcept;
|
||||
|
||||
/** Copies a StringArray from an array of objects which can be implicitly converted to Strings. */
|
||||
template <typename Type>
|
||||
StringArray& operator= (const Array<Type>& stringArray)
|
||||
{
|
||||
addArray (stringArray.begin(), stringArray.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Swaps the contents of this and another StringArray. */
|
||||
void swapWith (StringArray&) noexcept;
|
||||
|
||||
@ -169,10 +187,7 @@ public:
|
||||
|
||||
//==============================================================================
|
||||
/** Appends a string at the end of the array. */
|
||||
void add (const String& stringToAdd);
|
||||
|
||||
/** Appends a string at the end of the array. */
|
||||
void add (String&& stringToAdd);
|
||||
void add (String stringToAdd);
|
||||
|
||||
/** Inserts a string into the array.
|
||||
|
||||
@ -181,7 +196,7 @@ public:
|
||||
If the index is less than zero or greater than the size of the array,
|
||||
the new string will be added to the end of the array.
|
||||
*/
|
||||
void insert (int index, const String& stringToAdd);
|
||||
void insert (int index, String stringToAdd);
|
||||
|
||||
/** Adds a string to the array as long as it's not already in there.
|
||||
The search can optionally be case-insensitive.
|
||||
@ -195,7 +210,7 @@ public:
|
||||
If the index is higher than the array's size, the new string will be
|
||||
added to the end of the array; if it's less than zero nothing happens.
|
||||
*/
|
||||
void set (int index, const String& newString);
|
||||
void set (int index, String newString);
|
||||
|
||||
/** Appends some strings from another array to the end of this one.
|
||||
|
||||
@ -208,6 +223,18 @@ public:
|
||||
int startIndex = 0,
|
||||
int numElementsToAdd = -1);
|
||||
|
||||
/** Adds items from a range of start/end iterators of some kind of objects which
|
||||
can be implicitly converted to Strings.
|
||||
*/
|
||||
template <typename Iterator>
|
||||
void addArray (Iterator&& start, Iterator&& end)
|
||||
{
|
||||
ensureStorageAllocated (size() + (int) static_cast<size_t> (end - start));
|
||||
|
||||
while (start != end)
|
||||
strings.add (*start++);
|
||||
}
|
||||
|
||||
/** Merges the strings from another array into this one.
|
||||
This will not add a string that already exists.
|
||||
|
||||
@ -393,7 +420,7 @@ public:
|
||||
|
||||
//==============================================================================
|
||||
/** Sorts the array into alphabetical order.
|
||||
@param ignoreCase if true, the comparisons used will be case-sensitive.
|
||||
@param ignoreCase if true, the comparisons used will not be case-sensitive.
|
||||
*/
|
||||
void sort (bool ignoreCase);
|
||||
|
||||
|
Reference in New Issue
Block a user