11constexpr const uint64_t pow10_0to19[]=
31 1000000000000000000UL,
32 10000000000000000000UL,
36constexpr const uint8_t binSizeToDecSize[]
38 20, 19, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 16, 15,
39 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10,
40 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6,
41 05, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1
45{
return ((
int(lhs) &
int(rhs)) != 0); }
51template<
typename TChar>
57 if( idx < 0 || idx >= length )
60 const TChar* buf= src.
Buffer();
63 while ( idx < length ) {
64 const TChar c= buf[idx];
65 if ( c <
'0' || c >
'9' )
68 result= ( result * 10 ) + uint64_t( c -
'0' );
80template<
typename TChar>
85 if ( startIdx < 0 || startIdx >= srcLength )
89 const TChar* buffer= src.
Buffer();
91 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude, NC>( nf.
Whitespaces, startIdx );
97 if ( (negative= (buffer[idx] ==
'-')) ==
true || buffer[idx] ==
'+' ) {
98 if( (idx= src.
template IndexOfAny<lang::Inclusion::Exclude, NC>( nf.
Whitespaces, idx + 1 ) ) == -1 )
109 && ( idx + prefixLen < srcLength )
111 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
114 result= int64_t(
ParseHex( src, idx, nf ) );
115 if( idx - prefixLen == oldIdx )
121 && ( idx + prefixLen < srcLength )
123 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
126 result= int64_t(
ParseBin( src, idx, nf ) );
127 if( idx - prefixLen == oldIdx )
133 && ( idx + prefixLen < srcLength )
135 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
138 result= int64_t(
ParseOct( src, idx, nf ) );
139 if( idx - prefixLen == oldIdx )
146 result= int64_t(
ParseDec( src, idx, nf ) );
154 return negative ? int64_t(-result)
160template<
typename TChar>
165 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
170 bool charFound=
false;
172 const TChar* buf= src.
Buffer();
173 while ( idx < length ) {
174 const TChar c= buf[idx];
176 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
184 if ( c <
'0' || c >
'9' )
188 result= ( result * 10 ) + uint64_t( c -
'0' );
199template<
typename TChar>
204 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
209 bool charFound=
false;
211 const TChar* buf = src.
Buffer();
212 while ( idx < length ) {
215 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
249template<
typename TChar>
254 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
259 bool charFound=
false;
261 const TChar* buf= src.
Buffer();
262 while ( idx < length ) {
265 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
275 if ( c >=
'0' && c <=
'9' ) {
277 result|= uint64_t(c -
'0');
283 if ( c >=
'A' && c <=
'F' ) {
285 result|= uint64_t(c -
'A' + 10 );
291 if ( c >=
'a' && c <=
'f' ) {
293 result|= uint64_t(c -
'a' + 10 );
308template<
typename TChar>
313 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
318 bool charFound=
false;
320 const TChar* buf= src.
Buffer();
321 while ( idx < length ) {
324 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
332 if ( c >=
'0' && c <=
'7' ) {
334 result|= uint64_t(c -
'0');
348template<
typename TChar>
351 if( startIdx < 0 || startIdx >= src.
Length() )
355 const TChar* buf= src.
Buffer() + startIdx;
360 integer skip= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
363 buf+= skip - startIdx;
367 bool negative= (*buf ==
'-');
368 if ( negative || *buf ==
'+' ) {
369 if( ++buf == bufEnd )
379 if( buf + nf.
NANLiteral.Length() - 1 <= bufEnd
383 return std::numeric_limits<double>::quiet_NaN();
386 if( buf + nf.
INFLiteral.Length() - 1 <= bufEnd
390 return negative ? -std::numeric_limits<double>::infinity()
391 : std::numeric_limits<double>::infinity();
398 bool integralPartFound= isdigit(
int(c));
399 if ( integralPartFound ) {
400 if ( c <
'0' || c >
'9' )
410 ALIB_ASSERT_ERROR( buf <= bufEnd,
"STRINGS",
"Error in float parsing algorithm." )
411 if ( buf == bufEnd ) {
412 startIdx= buf - src.
Buffer();
413 return negative ? -result : result;
422 && *buf >=
'0' && *buf <=
'9' )
427 result+= ( intValue / pow( 10,
double(intIdx) ) );
429 else if( !integralPartFound )
433 if ( buf < bufEnd ) {
435 bool eSepFound=
false;
437 if ( buf + sepLen < bufEnd ) {
442 if ( (eSepFound= ( pos == sepLen ) ) ==
true )
445 if ( !eSepFound && ( *buf ==
'e' || *buf ==
'E' ) ) {
451 if (eSepFound && buf < bufEnd) {
452 bool negativeE=
false;
453 if ( (negativeE= (*buf ==
'-') ) ==
true || *buf ==
'+' )
461 result*= pow( 10, negativeE ? -exp : exp );
468 startIdx= buf - src.
Buffer();
471 return negative ? -result : result;
474template<
typename TChar>
477 int width= overrideWidth != 0 ? overrideWidth
480 if ( width < 1 ) width= 1;
488 int leadingBinaryZeros=
lang::CLZ(value);
489 digitsInValue= binSizeToDecSize[leadingBinaryZeros];
492 if( value < pow10_0to19[digitsInValue-1] )
496 && (digitsInValue == 20 || value < pow10_0to19[digitsInValue ]),
497 "STRINGS",
"Error calculating the number of digits in value {}",
509 requestedDigits= width - width / 4;
513 requestedDigits= width;
516 printDigits= (std::max)( requestedDigits, digitsInValue );
521 "STRINGS",
"Internal error, false assumption" )
522 if( printDigits >1 && width > printDigits + (printDigits - 1) / 3 )
527 bool printSpace= hasBits(nf.
Flags, NumberFormatFlags::ReplaceLeadingZerosWithSpaces);
528 int actDigit= printDigits;
529 while ( actDigit > 0 ) {
531 int digitValue= int( ( value / pow10_0to19[actDigit-1] ) );
536 && actDigit != printDigits
542 printSpace&= (digitValue == 0 && actDigit > 1);
543 buffer[idx++]= printSpace ? TChar(
' ') : TChar( 48 + digitValue );
546 value= value % pow10_0to19[actDigit-1];
554template<
typename TChar>
562 uValue= uint64_t( value );
566 uValue= uint64_t( -value );
570 int width= overrideWidth != 0 ? overrideWidth
572 if( idx != oldIdx && width > 1 )
579template<
typename TChar>
583 int groupWidth= !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) ? 0
591 int nextSeparator= 0;
594 int digits= overrideWidth != 0 ? overrideWidth : nf.
BinFieldWidth;
596 if ( groupWidth != 0 ) {
597 nextSeparator= digits<= groupWidth ? 0
598 : ( digits >= groupWidth
599 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
601 digits-= digits / (groupWidth + 1);
614 uint64_t testValue= uint64_t(1) << (digits - 1);
615 while ( digits > 0) {
617 if( groupWidth != 0 && ( digits % groupWidth) == 0 ) {
618 if ( nextSeparator != 0 )
627 buffer[idx++]= ( value & testValue ) == 0L ?
'0' :
'1';
637template<
typename TChar>
641 int groupWidth= !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) ? 0
648 int nextSeparator= 0;
650 int digits= overrideWidth != 0 ? overrideWidth : nf.
HexFieldWidth;
654 if ( groupWidth != 0 ) {
655 nextSeparator= digits<= groupWidth ? 0
656 : ( digits >= groupWidth
657 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
659 digits-= digits / (groupWidth + 1);
664 digits= value != 0 ? (
lang::MSB(value)-1) / 4 + 1
671 unsigned characterA=
static_cast<unsigned int>( hasBits(nf.
Flags, NumberFormatFlags::HexLowerCase) ?
'a' :
'A' );
672 int shiftBits= (digits -1 ) * 4;
673 uint64_t testMask= uint64_t( 15 ) << shiftBits;
674 while ( digits > 0) {
676 if( groupWidth != 0 && ( digits % groupWidth) == 0 ) {
677 if ( nextSeparator != 0 )
685 unsigned nibble=
static_cast<unsigned int>( ( value & testMask ) >> shiftBits );
686 buffer[idx++]= ( nibble < 10 ) ? static_cast<TChar>(
'0' + nibble)
687 :
static_cast<TChar
>(characterA + (nibble - 10));
698template<
typename TChar>
702 const int groupWidth= hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) && nf.
OctGroupChar !=
'\0' ? 3 : 0;
706 int nextSeparator= 0;
709 int digits= overrideWidth != 0 ? overrideWidth : nf.
OctFieldWidth;
711 if ( groupWidth != 0 ) {
712 nextSeparator= digits<= groupWidth ? 0
713 : ( digits >= groupWidth
714 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
716 digits-= digits / (groupWidth + 1);
721 digits= value != 0 ? (
lang::MSB(value)-1) / 3 + 1
728 int shiftBits= (digits -1 ) * 3;
729 while ( digits > 0) {
731 if( groupWidth != 0 && ( digits % groupWidth) == 0 ) {
732 if ( nextSeparator != 0 )
738 auto octet= ( value & (uint64_t(7) << shiftBits) ) >> shiftBits;
739 buffer[idx++]=
static_cast<TChar
>(
'0' + octet);
749template<
typename TChar>
756 auto classification= std::fpclassify(value);
757 if( classification == FP_NAN ) {
return idx+= nf.
NANLiteral.CopyTo(buffer + idx); }
758 bool isNegative= std::signbit(value);
760 if( classification == FP_ZERO ) {
769 if( classification == FP_INFINITE ) {
774 return idx+= nf.
INFLiteral.CopyTo(buffer + idx);
778 constexpr int MaxFloatSignificantDigits= 16;
782 int exp10= value != 0.0 ? int( floor(log10( value ) ) )
786 bool scientific= ( hasBits(nf.
Flags, NumberFormatFlags::ForceScientific)
788 || ( integralWidth > 0 && exp10 != 0 && exp10 >= (MaxFloatSignificantDigits - integralWidth - 1 ) )
792 integralWidth= (std::min) ( integralWidth, 15 );
800 int unusedFractDigits;
805 auto dotPos= MaxFloatSignificantDigits - exp10;
806 intPart= uint64_t(llrint( value * pow( 10, dotPos ) ));
807 fractPart= intPart % pow10_0to19[ MaxFloatSignificantDigits ];
808 intPart= intPart / pow10_0to19[ MaxFloatSignificantDigits ];
812 if ( fractPart > 0 ) {
813 ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero < 20,
"STRINGS")
814 while ( fractPart < pow10_0to19[ MaxFloatSignificantDigits - firstNonZero - 1 ] )
816 ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero > 0,
"STRINGS")
820 unusedFractDigits= fractionalDigits >= 0 ? MaxFloatSignificantDigits - fractionalDigits
825 else if (exp10 >= 0 ) {
826 int intPartSize= MaxFloatSignificantDigits - exp10;
827 ALIB_ASSERT( intPartSize > 0 && intPartSize <= MaxFloatSignificantDigits,
"STRINGS" )
828 intPart= uint64_t(llrint( value * pow( 10, intPartSize ) ));
829 fractPart= intPart % pow10_0to19[ intPartSize ];
830 intPart= intPart / pow10_0to19[ intPartSize ];
834 if ( fractPart > 0 ) {
835 while ( fractPart < pow10_0to19[ intPartSize - firstNonZero - 1 ] )
837 ALIB_ASSERT( intPartSize - firstNonZero > 0,
"STRINGS" )
841 unusedFractDigits= fractionalDigits >= 0 ? intPartSize - fractionalDigits
848 firstNonZero= -exp10;
850 fractPart= uint64_t(llrint( value * pow( 10, MaxFloatSignificantDigits + firstNonZero) ));
851 unusedFractDigits= fractionalDigits >= 0 ? MaxFloatSignificantDigits - ( fractionalDigits - firstNonZero )
856 if ( (fractionalDigits < 0 || fractionalDigits >= firstNonZero - 1 )
857 && unusedFractDigits > 0
858 && unusedFractDigits <= 18 )
861 uint64_t rest= fractPart % pow10_0to19[ unusedFractDigits ];
862 fractPart = fractPart / pow10_0to19[ unusedFractDigits ];
863 if ( rest > pow10_0to19[ unusedFractDigits ] / 2 ) {
865 int overflowDigit= 0;
866 bool overflow=
false;
867 while ( (overflowDigit <= fractionalDigits || fractionalDigits < 0 )
868 && (overflow|= fractPart == pow10_0to19[ overflowDigit ]) ==
false
869 && fractPart > pow10_0to19[ overflowDigit ]
874 if ( overflowDigit == (fractionalDigits >= 0 ? fractionalDigits : 15) ) {
886 && ( fractionalDigits < 0 || fractionalDigits > firstNonZero -1)
894 if ( intPart != 0L || integralWidth != 0 )
898 if ( fractionalDigits != 0 || hasBits(nf.
Flags, NumberFormatFlags::ForceDecimalPoint) )
902 if (fractionalDigits != 0) {
903 int fractZeros= firstNonZero - 1;
904 if ( fractionalDigits > 0 && fractZeros > fractionalDigits )
905 fractZeros= fractionalDigits;
907 for (
int i= 0 ; i < fractZeros ; ++i )
910 int qtyDigits= fractionalDigits - fractZeros;
911 int actDigit= MaxFloatSignificantDigits + 1;
912 int cntOmittedZeros= 0;
914 bool printStarted=
false;
915 while ( fractPart > 0
916 && ( qtyDigits< 0 || cntDigits < qtyDigits )
922 int digitValue= int( ( fractPart / pow10_0to19[actDigit] ) );
927 if ( (printStarted|= (digitValue != 0)) ==
false )
932 if ( digitValue == 0 )
935 for (
int i= 0; i< cntOmittedZeros ; ++i )
938 buffer[idx++]=
static_cast<TChar
>( 48 + digitValue );
942 fractPart= fractPart % pow10_0to19[actDigit];
946 if (fractionalDigits < 0 )
950 if ( cntDigits < qtyDigits ) {
951 if ( hasBits(nf.
Flags, NumberFormatFlags::OmitTrailingFractionalZeros) ) {
955 for (
int i= 0; i< cntOmittedZeros ; ++i )
957 cntDigits+= cntOmittedZeros;
960 for (
int i= cntDigits; i< qtyDigits; ++i )
972 else if ( hasBits(nf.
Flags, NumberFormatFlags::WriteExponentPlusSign) )
975 idx=
WriteDecUnsigned( uint64_t(exp10 >= 0 ? exp10 : -exp10), buffer, idx, 2, nf );