36constexpr const uint64_t pow10_0to19[]=
56 1000000000000000000UL,
57 10000000000000000000UL,
61constexpr const uint8_t binSizeToDecSize[]
63 20, 19, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 16, 15,
64 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10,
65 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6,
66 05, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1
70{
return ((
int(lhs) &
int(rhs)) != 0); }
76template<
typename TChar>
82 if( idx < 0 || idx >= length )
85 const TChar* buf= src.
Buffer();
88 while ( idx < length ) {
89 const TChar c= buf[idx];
90 if ( c <
'0' || c >
'9' )
93 result= ( result * 10 ) + uint64_t( c -
'0' );
105template<
typename TChar>
110 if ( startIdx < 0 || startIdx >= srcLength )
114 const TChar* buffer= src.
Buffer();
116 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude, NC>( nf.
Whitespaces, startIdx );
122 if ( (negative= (buffer[idx] ==
'-')) ==
true || buffer[idx] ==
'+' ) {
123 if( (idx= src.
template IndexOfAny<lang::Inclusion::Exclude, NC>( nf.
Whitespaces, idx + 1 ) ) == -1 )
134 && ( idx + prefixLen < srcLength )
136 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
139 result= int64_t(
ParseHex( src, idx, nf ) );
140 if( idx - prefixLen == oldIdx )
146 && ( idx + prefixLen < srcLength )
148 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
151 result= int64_t(
ParseBin( src, idx, nf ) );
152 if( idx - prefixLen == oldIdx )
158 && ( idx + prefixLen < srcLength )
160 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
163 result= int64_t(
ParseOct( src, idx, nf ) );
164 if( idx - prefixLen == oldIdx )
171 result= int64_t(
ParseDec( src, idx, nf ) );
179 return negative ? int64_t(-result)
185template<
typename TChar>
190 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
195 bool charFound=
false;
197 const TChar* buf= src.
Buffer();
198 while ( idx < length ) {
199 const TChar c= buf[idx];
201 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
209 if ( c <
'0' || c >
'9' )
213 result= ( result * 10 ) + uint64_t( c -
'0' );
224template<
typename TChar>
229 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
234 bool charFound=
false;
236 const TChar* buf = src.
Buffer();
237 while ( idx < length ) {
240 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
274template<
typename TChar>
279 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
284 bool charFound=
false;
286 const TChar* buf= src.
Buffer();
287 while ( idx < length ) {
290 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
300 if ( c >=
'0' && c <=
'9' ) {
302 result|= uint64_t(c -
'0');
308 if ( c >=
'A' && c <=
'F' ) {
310 result|= uint64_t(c -
'A' + 10 );
316 if ( c >=
'a' && c <=
'f' ) {
318 result|= uint64_t(c -
'a' + 10 );
333template<
typename TChar>
338 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
343 bool charFound=
false;
345 const TChar* buf= src.
Buffer();
346 while ( idx < length ) {
349 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
357 if ( c >=
'0' && c <=
'7' ) {
359 result|= uint64_t(c -
'0');
373template<
typename TChar>
376 if( startIdx < 0 || startIdx >= src.
Length() )
380 const TChar* buf= src.
Buffer() + startIdx;
385 integer skip= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
388 buf+= skip - startIdx;
392 bool negative= (*buf ==
'-');
393 if ( negative || *buf ==
'+' ) {
394 if( ++buf == bufEnd )
404 if( buf + nf.
NANLiteral.Length() - 1 <= bufEnd
408 return std::numeric_limits<double>::quiet_NaN();
411 if( buf + nf.
INFLiteral.Length() - 1 <= bufEnd
415 return negative ? -std::numeric_limits<double>::infinity()
416 : std::numeric_limits<double>::infinity();
423 bool integralPartFound= isdigit(
int(c));
424 if ( integralPartFound ) {
425 if ( c <
'0' || c >
'9' )
435 ALIB_ASSERT_ERROR( buf <= bufEnd,
"STRINGS",
"Error in float parsing algorithm." )
436 if ( buf == bufEnd ) {
437 startIdx= buf - src.
Buffer();
438 return negative ? -result : result;
447 && *buf >=
'0' && *buf <=
'9' )
452 result+= ( intValue / pow( 10,
double(intIdx) ) );
454 else if( !integralPartFound )
458 if ( buf < bufEnd ) {
460 bool eSepFound=
false;
462 if ( buf + sepLen < bufEnd ) {
467 if ( (eSepFound= ( pos == sepLen ) ) ==
true )
470 if ( !eSepFound && ( *buf ==
'e' || *buf ==
'E' ) ) {
476 if (eSepFound && buf < bufEnd) {
477 bool negativeE=
false;
478 if ( (negativeE= (*buf ==
'-') ) ==
true || *buf ==
'+' )
486 result*= pow( 10, negativeE ? -exp : exp );
493 startIdx= buf - src.
Buffer();
496 return negative ? -result : result;
499template<
typename TChar>
502 int width= overrideWidth != 0 ? overrideWidth
505 if ( width < 1 ) width= 1;
513 int leadingBinaryZeros=
lang::CLZ(value);
514 digitsInValue= binSizeToDecSize[leadingBinaryZeros];
517 if( value < pow10_0to19[digitsInValue-1] )
521 && (digitsInValue == 20 || value < pow10_0to19[digitsInValue ]),
522 "STRINGS",
"Error calculating the number of digits in value {}",
534 requestedDigits= width - width / 4;
538 requestedDigits= width;
541 printDigits= (std::max)( requestedDigits, digitsInValue );
546 "STRINGS",
"Internal error, false assumption" )
547 if( printDigits >1 && width > printDigits + (printDigits - 1) / 3 )
552 bool printSpace= hasBits(nf.
Flags, NumberFormatFlags::ReplaceLeadingZerosWithSpaces);
553 int actDigit= printDigits;
554 while ( actDigit > 0 ) {
556 int digitValue= int( ( value / pow10_0to19[actDigit-1] ) );
561 && actDigit != printDigits
567 printSpace&= (digitValue == 0 && actDigit > 1);
568 buffer[idx++]= printSpace ? TChar(
' ') : TChar( 48 + digitValue );
571 value= value % pow10_0to19[actDigit-1];
579template<
typename TChar>
587 uValue= uint64_t( value );
591 uValue= uint64_t( -value );
595 int width= overrideWidth != 0 ? overrideWidth
597 if( idx != oldIdx && width > 1 )
604template<
typename TChar>
608 int groupWidth= !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) ? 0
616 int nextSeparator= 0;
619 int digits= overrideWidth != 0 ? overrideWidth : nf.
BinFieldWidth;
621 if ( groupWidth != 0 ) {
622 nextSeparator= digits<= groupWidth ? 0
623 : ( digits >= groupWidth
624 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
626 digits-= digits / (groupWidth + 1);
639 uint64_t testValue= uint64_t(1) << (digits - 1);
640 while ( digits > 0) {
642 if( groupWidth != 0 && ( digits % groupWidth) == 0 ) {
643 if ( nextSeparator != 0 )
652 buffer[idx++]= ( value & testValue ) == 0L ?
'0' :
'1';
662template<
typename TChar>
666 int groupWidth= !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) ? 0
673 int nextSeparator= 0;
675 int digits= overrideWidth != 0 ? overrideWidth : nf.
HexFieldWidth;
679 if ( groupWidth != 0 ) {
680 nextSeparator= digits<= groupWidth ? 0
681 : ( digits >= groupWidth
682 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
684 digits-= digits / (groupWidth + 1);
689 digits= value != 0 ? (
lang::MSB(value)-1) / 4 + 1
696 unsigned characterA=
static_cast<unsigned int>( hasBits(nf.
Flags, NumberFormatFlags::HexLowerCase) ?
'a' :
'A' );
697 int shiftBits= (digits -1 ) * 4;
698 uint64_t testMask= uint64_t( 15 ) << shiftBits;
699 while ( digits > 0) {
701 if( groupWidth != 0 && ( digits % groupWidth) == 0 ) {
702 if ( nextSeparator != 0 )
710 unsigned nibble=
static_cast<unsigned int>( ( value & testMask ) >> shiftBits );
711 buffer[idx++]= ( nibble < 10 ) ? static_cast<TChar>(
'0' + nibble)
712 :
static_cast<TChar
>(characterA + (nibble - 10));
723template<
typename TChar>
727 const int groupWidth= hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) && nf.
OctGroupChar !=
'\0' ? 3 : 0;
731 int nextSeparator= 0;
734 int digits= overrideWidth != 0 ? overrideWidth : nf.
OctFieldWidth;
736 if ( groupWidth != 0 ) {
737 nextSeparator= digits<= groupWidth ? 0
738 : ( digits >= groupWidth
739 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
741 digits-= digits / (groupWidth + 1);
746 digits= value != 0 ? (
lang::MSB(value)-1) / 3 + 1
753 int shiftBits= (digits -1 ) * 3;
754 while ( digits > 0) {
756 if( groupWidth != 0 && ( digits % groupWidth) == 0 ) {
757 if ( nextSeparator != 0 )
763 auto octet= ( value & (uint64_t(7) << shiftBits) ) >> shiftBits;
764 buffer[idx++]=
static_cast<TChar
>(
'0' + octet);
774template<
typename TChar>
781 auto classification= std::fpclassify(value);
782 if( classification == FP_NAN ) {
return idx+= nf.
NANLiteral.CopyTo(buffer + idx); }
783 bool isNegative= std::signbit(value);
785 if( classification == FP_ZERO ) {
794 if( classification == FP_INFINITE ) {
799 return idx+= nf.
INFLiteral.CopyTo(buffer + idx);
803 constexpr int MaxFloatSignificantDigits= 16;
807 int exp10= value != 0.0 ? int( floor(log10( value ) ) )
811 bool scientific= ( hasBits(nf.
Flags, NumberFormatFlags::ForceScientific)
813 || ( integralWidth > 0 && exp10 != 0 && exp10 >= (MaxFloatSignificantDigits - integralWidth - 1 ) )
817 integralWidth= (std::min) ( integralWidth, 15 );
825 int unusedFractDigits;
830 auto dotPos= MaxFloatSignificantDigits - exp10;
831 intPart= uint64_t(llrint( value * pow( 10, dotPos ) ));
832 fractPart= intPart % pow10_0to19[ MaxFloatSignificantDigits ];
833 intPart= intPart / pow10_0to19[ MaxFloatSignificantDigits ];
837 if ( fractPart > 0 ) {
838 ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero < 20,
"STRINGS")
839 while ( fractPart < pow10_0to19[ MaxFloatSignificantDigits - firstNonZero - 1 ] )
841 ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero > 0,
"STRINGS")
845 unusedFractDigits= fractionalDigits >= 0 ? MaxFloatSignificantDigits - fractionalDigits
850 else if (exp10 >= 0 ) {
851 int intPartSize= MaxFloatSignificantDigits - exp10;
852 ALIB_ASSERT( intPartSize > 0 && intPartSize <= MaxFloatSignificantDigits,
"STRINGS" )
853 intPart= uint64_t(llrint( value * pow( 10, intPartSize ) ));
854 fractPart= intPart % pow10_0to19[ intPartSize ];
855 intPart= intPart / pow10_0to19[ intPartSize ];
859 if ( fractPart > 0 ) {
860 while ( fractPart < pow10_0to19[ intPartSize - firstNonZero - 1 ] )
862 ALIB_ASSERT( intPartSize - firstNonZero > 0,
"STRINGS" )
866 unusedFractDigits= fractionalDigits >= 0 ? intPartSize - fractionalDigits
873 firstNonZero= -exp10;
875 fractPart= uint64_t(llrint( value * pow( 10, MaxFloatSignificantDigits + firstNonZero) ));
876 unusedFractDigits= fractionalDigits >= 0 ? MaxFloatSignificantDigits - ( fractionalDigits - firstNonZero )
881 if ( (fractionalDigits < 0 || fractionalDigits >= firstNonZero - 1 )
882 && unusedFractDigits > 0
883 && unusedFractDigits <= 18 )
886 uint64_t rest= fractPart % pow10_0to19[ unusedFractDigits ];
887 fractPart = fractPart / pow10_0to19[ unusedFractDigits ];
888 if ( rest > pow10_0to19[ unusedFractDigits ] / 2 ) {
890 int overflowDigit= 0;
891 bool overflow=
false;
892 while ( (overflowDigit <= fractionalDigits || fractionalDigits < 0 )
893 && (overflow|= fractPart == pow10_0to19[ overflowDigit ]) ==
false
894 && fractPart > pow10_0to19[ overflowDigit ]
899 if ( overflowDigit == (fractionalDigits >= 0 ? fractionalDigits : 15) ) {
911 && ( fractionalDigits < 0 || fractionalDigits > firstNonZero -1)
919 if ( intPart != 0L || integralWidth != 0 )
923 if ( fractionalDigits != 0 || hasBits(nf.
Flags, NumberFormatFlags::ForceDecimalPoint) )
927 if (fractionalDigits != 0) {
928 int fractZeros= firstNonZero - 1;
929 if ( fractionalDigits > 0 && fractZeros > fractionalDigits )
930 fractZeros= fractionalDigits;
932 for (
int i= 0 ; i < fractZeros ; ++i )
935 int qtyDigits= fractionalDigits - fractZeros;
936 int actDigit= MaxFloatSignificantDigits + 1;
937 int cntOmittedZeros= 0;
939 bool printStarted=
false;
940 while ( fractPart > 0
941 && ( qtyDigits< 0 || cntDigits < qtyDigits )
947 int digitValue= int( ( fractPart / pow10_0to19[actDigit] ) );
952 if ( (printStarted|= (digitValue != 0)) ==
false )
957 if ( digitValue == 0 )
960 for (
int i= 0; i< cntOmittedZeros ; ++i )
963 buffer[idx++]=
static_cast<TChar
>( 48 + digitValue );
967 fractPart= fractPart % pow10_0to19[actDigit];
971 if (fractionalDigits < 0 )
975 if ( cntDigits < qtyDigits ) {
976 if ( hasBits(nf.
Flags, NumberFormatFlags::OmitTrailingFractionalZeros) ) {
980 for (
int i= 0; i< cntOmittedZeros ; ++i )
982 cntDigits+= cntOmittedZeros;
985 for (
int i= cntDigits; i< qtyDigits; ++i )
997 else if ( hasBits(nf.
Flags, NumberFormatFlags::WriteExponentPlusSign) )
1000 idx=
WriteDecUnsigned( uint64_t(exp10 >= 0 ? exp10 : -exp10), buffer, idx, 2, nf );