26JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4514 4996)
43 return toLowerCase (character) != character;
52 return toUpperCase (character) != character;
56JUCE_END_IGNORE_WARNINGS_MSVC
71 return (character >=
'0' && character <=
'9');
81 return (character >=
'a' && character <=
'z')
82 || (character >=
'A' && character <=
'Z');
92 return (character >=
'a' && character <=
'z')
93 || (character >=
'A' && character <=
'Z')
94 || (character >=
'0' && character <=
'9');
104 return (character >=
' ' && character <=
'~');
114 auto d = (
unsigned int) (
digit -
'0');
116 if (d < (
unsigned int) 10)
119 d += (
unsigned int) (
'0' -
'a');
121 if (d < (
unsigned int) 6)
124 d += (
unsigned int) (
'a' -
'A');
126 if (d < (
unsigned int) 6)
132double CharacterFunctions::mulexp10 (
const double value,
int exponent)
noexcept
140 const bool negative = (
exponent < 0);
145 double result = 1.0,
power = 10.0;
147 for (
int bit = 1;
exponent != 0; bit <<= 1)
161 return negative ? (value / result) : (value * result);
169 static const uint16 lookup[] = { 0x20AC, 0x0007, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
170 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0007, 0x017D, 0x0007,
171 0x0007, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
172 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0007, 0x017E, 0x0178 };
183#define STR(value) QUOTE(value)
184#define ASYM_CHARPTR_DOUBLE_PAIR(str, value) std::pair<const char*, double> (STR(str), value)
185#define CHARPTR_DOUBLE_PAIR(value) ASYM_CHARPTR_DOUBLE_PAIR(value, value)
186#define CHARPTR_DOUBLE_PAIR_COMBOS(value) \
187 CHARPTR_DOUBLE_PAIR(value), \
188 CHARPTR_DOUBLE_PAIR(-value), \
189 ASYM_CHARPTR_DOUBLE_PAIR(+value, value), \
190 ASYM_CHARPTR_DOUBLE_PAIR(000000 ## value, value), \
191 ASYM_CHARPTR_DOUBLE_PAIR(+000 ## value, value), \
192 ASYM_CHARPTR_DOUBLE_PAIR(-0 ## value, -value)
197template <
typename CharPo
interType>
200 using CharType =
typename CharPointerType::CharType;
203 CharPointerType source (
charPtr);
205 result.
setSize (CharPointerType::getBytesRequiredFor (source) +
sizeof (CharType));
206 CharPointerType dest { (CharType*) result.
getData() };
207 dest.writeAll (source);
211template <
typename FromCharPo
interType,
typename ToCharPo
interType>
214 using ToCharType =
typename ToCharPointerType ::CharType;
215 using FromCharType =
typename FromCharPointerType::CharType;
223 while ((c =
sourcePtr.getAndAdvance()) !=
'\0')
225 requiredSize += ToCharPointerType::getBytesRequiredFor (c);
251template <
typename CharPo
interType>
264 "",
"-",
"+",
"e",
"e+",
"E-",
"f",
" ",
",",
";",
"<",
"'",
"\"",
"_",
"k",
265 " +",
" -",
" -e",
"-In ",
" +n",
"n",
" r"
271 const CharPointer_ASCII::CharType*
nullCharPtrs[] = {
"." };
273 result.nulls = result.terminals;
290 "\xf0\x9f\x8f\x81\xF0\x9F\x9A\x97"
297 for (
auto vec : { &result.terminals, &result.nulls })
304template <
typename CharPo
interType,
typename StorageType>
321 for (
auto vec : { &result.terminals, &result.nulls })
335 { 0xd801, 0xdc37, 0x0 },
336 { 0x0065, 0xd83d, 0xde03, 0x0 },
337 { 0xd83c, 0xdfc1, 0xd83d, 0xde97, 0x0 }
350 { 0x00000065, 0x0001f603, 0x0 },
351 { 0x0001f3c1, 0x0001f697, 0x0 }
357template <
typename TestFunction>
373 data.append (suffix.getData(), suffix.getSize());
381template <
typename CharPo
interType>
385 using CharType =
typename CharPointerType::CharType;
387 CharacterFunctionsTests()
388 : UnitTest (
"CharacterFunctions", UnitTestCategories::text)
391 void runTest()
override
393 beginTest (
"readDoubleValue");
398 CHARPTR_DOUBLE_PAIR_COMBOS (0),
399 CHARPTR_DOUBLE_PAIR_COMBOS (3),
400 CHARPTR_DOUBLE_PAIR_COMBOS (4931),
401 CHARPTR_DOUBLE_PAIR_COMBOS (5000),
402 CHARPTR_DOUBLE_PAIR_COMBOS (9862097),
405 CHARPTR_DOUBLE_PAIR_COMBOS (0.),
406 CHARPTR_DOUBLE_PAIR_COMBOS (9.),
407 CHARPTR_DOUBLE_PAIR_COMBOS (7.000),
408 CHARPTR_DOUBLE_PAIR_COMBOS (0.2),
409 CHARPTR_DOUBLE_PAIR_COMBOS (.298630),
410 CHARPTR_DOUBLE_PAIR_COMBOS (1.118),
411 CHARPTR_DOUBLE_PAIR_COMBOS (0.9000),
412 CHARPTR_DOUBLE_PAIR_COMBOS (0.0000001),
413 CHARPTR_DOUBLE_PAIR_COMBOS (500.0000001),
414 CHARPTR_DOUBLE_PAIR_COMBOS (9862098.2398604),
417 CHARPTR_DOUBLE_PAIR_COMBOS (0e0),
418 CHARPTR_DOUBLE_PAIR_COMBOS (0.e0),
419 CHARPTR_DOUBLE_PAIR_COMBOS (0.00000e0),
420 CHARPTR_DOUBLE_PAIR_COMBOS (.0e7),
421 CHARPTR_DOUBLE_PAIR_COMBOS (0e-5),
422 CHARPTR_DOUBLE_PAIR_COMBOS (2E0),
423 CHARPTR_DOUBLE_PAIR_COMBOS (4.E0),
424 CHARPTR_DOUBLE_PAIR_COMBOS (1.2000000E0),
425 CHARPTR_DOUBLE_PAIR_COMBOS (1.2000000E6),
426 CHARPTR_DOUBLE_PAIR_COMBOS (.398e3),
427 CHARPTR_DOUBLE_PAIR_COMBOS (10e10),
428 CHARPTR_DOUBLE_PAIR_COMBOS (1.4962e+2),
429 CHARPTR_DOUBLE_PAIR_COMBOS (3198693.0973e4),
430 CHARPTR_DOUBLE_PAIR_COMBOS (10973097.2087E-4),
431 CHARPTR_DOUBLE_PAIR_COMBOS (1.3986e00006),
432 CHARPTR_DOUBLE_PAIR_COMBOS (2087.3087e+00006),
433 CHARPTR_DOUBLE_PAIR_COMBOS (6.0872e-00006),
435 CHARPTR_DOUBLE_PAIR_COMBOS (1.7976931348623157e+308),
436 CHARPTR_DOUBLE_PAIR_COMBOS (2.2250738585072014e-308),
440 CHARPTR_DOUBLE_PAIR_COMBOS (17654321098765432.9),
441 CHARPTR_DOUBLE_PAIR_COMBOS (183456789012345678.9),
442 CHARPTR_DOUBLE_PAIR_COMBOS (1934567890123456789.9),
443 CHARPTR_DOUBLE_PAIR_COMBOS (20345678901234567891.9),
444 CHARPTR_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000),
445 CHARPTR_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752e3),
446 CHARPTR_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752e100),
447 CHARPTR_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000e-5),
448 CHARPTR_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000005e-40),
450 CHARPTR_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890),
451 CHARPTR_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890e-111),
454 auto asciiToMemoryBlock = [] (
const char* asciiPtr,
bool removeNullTerminator)
456 auto block = memoryBlockFromCharPtr<CharPointer_ASCII> (asciiPtr);
457 return convert<CharPointer_ASCII, CharPointerType> (block, removeNullTerminator);
460 const auto separators = getSeparators<CharPointerType>();
462 for (
const auto& trial : trials)
464 for (
const auto& terminal : separators.terminals)
466 MemoryBlock
data { asciiToMemoryBlock (trial.first,
true) };
467 data.append (terminal.getData(), terminal.getSize());
469 CharPointerType charPtr { (CharType*)
data.getData() };
470 expectEquals (CharacterFunctions::readDoubleValue (charPtr), trial.second);
471 expect (*charPtr == *(CharPointerType ((CharType*) terminal.getData())));
479 for (
auto* ptr : asciiPtrs)
480 result.push_back (asciiToMemoryBlock (ptr, removeNullTerminator));
486 const auto prefixes = asciiToMemoryBlocks (prefixCharPtrs,
true);
490 auto nans = asciiToMemoryBlocks (nanCharPtrs,
true);
492 withAllPrefixesAndSuffixes (prefixes, separators.terminals, nans, [
this] (
const MemoryBlock& data,
493 const MemoryBlock& suffix)
495 CharPointerType charPtr { (CharType*) data.getData() };
496 expect (
std::isnan (CharacterFunctions::readDoubleValue (charPtr)));
497 expect (*charPtr == *(CharPointerType ((CharType*) suffix.getData())));
502 std::vector<const char*> infCharPtrs = {
"Inf",
"inf",
"INF",
"InF",
"1.0E1024",
"1.23456789012345678901234567890e123456789" };
503 auto infs = asciiToMemoryBlocks (infCharPtrs,
true);
505 withAllPrefixesAndSuffixes (prefixes, separators.terminals, infs, [
this] (
const MemoryBlock& data,
506 const MemoryBlock& suffix)
508 CharPointerType charPtr { (CharType*) data.getData() };
510 :
std::numeric_limits<
double>::infinity();
511 expectEquals (CharacterFunctions::readDoubleValue (charPtr), expected);
512 expect (*charPtr == *(CharPointerType ((CharType*) suffix.getData())));
521 const MemoryBlock& suffix)
523 CharPointerType charPtr { (CharType*) data.getData() };
526 expect (*
charPtr == *(CharPointerType ((CharType*) suffix.getData())));
533 MemoryBlock
data { n.getData(), n.getSize() };
534 CharPointerType
charPtr { (CharType*)
data.getData() };
536 expect (
charPtr == CharPointerType { (CharType*)
data.getData() }.findEndOfWhitespace());
542static CharacterFunctionsTests<CharPointer_ASCII> characterFunctionsTestsAscii;
543static CharacterFunctionsTests<CharPointer_UTF8> characterFunctionsTestsUtf8;
544static CharacterFunctionsTests<CharPointer_UTF16> characterFunctionsTestsUtf16;
545static CharacterFunctionsTests<CharPointer_UTF32> characterFunctionsTestsUtf32;
A collection of functions for manipulating characters and character strings.
static juce_wchar toLowerCase(juce_wchar character) noexcept
Converts a character to lower-case.
static bool isDigit(char character) noexcept
Checks whether a character is a digit.
static bool isLowerCase(juce_wchar character) noexcept
Checks whether a unicode character is lower-case.
static bool isLetter(char character) noexcept
Checks whether a character is alphabetic.
static bool isWhitespace(char character) noexcept
Checks whether a character is whitespace.
static double readDoubleValue(CharPointerType &text) noexcept
Parses a character string to read a floating-point number.
static int getHexDigitValue(juce_wchar digit) noexcept
Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legal hex digit.
static bool isLetterOrDigit(char character) noexcept
Checks whether a character is alphabetic or numeric.
static bool isUpperCase(juce_wchar character) noexcept
Checks whether a unicode character is upper-case.
static bool isPrintable(char character) noexcept
Checks whether a character is a printable character, i.e.
static juce_wchar getUnicodeCharFromWindows1252Codepage(uint8 windows1252Char) noexcept
Converts a byte of Windows 1252 codepage to unicode.
A class to hold a resizable block of raw data.
void * getData() noexcept
Returns a void pointer to the data.
void setSize(size_t newSize, bool initialiseNewSpaceToZero=false)
Resizes the memory block.
unsigned short uint16
A platform-independent 16-bit unsigned integer type.
wchar_t juce_wchar
A platform-independent 32-bit unicode character type.
constexpr bool exactlyEqual(Type a, Type b)
Equivalent to operator==, but suppresses float-equality warnings.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
std::u16string convert(const std::string &utf8Str)
convert an UTF-8 string to an UTF-16 string