32constexpr const uint64_t pow10_0to19[]=
52 1000000000000000000UL,
53 10000000000000000000UL,
57constexpr const uint8_t binSizeToDecSize[]
59 20, 19, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 16, 15,
60 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10,
61 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6,
62 05, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1
66{
return ((
int(lhs) &
int(rhs)) != 0); }
72template<
typename TChar>
79 if( idx < 0 || idx >= length )
83 const TChar* buf= src.
Buffer();
87 while ( idx < length )
89 const TChar c= buf[idx];
90 if ( c <
'0' || c >
'9' )
93 result= ( result * 10 ) +
static_cast<uint64_t
>( c -
'0' );
105template<
typename TChar>
111 if ( startIdx < 0 || startIdx >= srcLength )
116 const TChar* buffer= src.
Buffer();
119 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude, NC>( nf.
Whitespaces, startIdx );
125 if ( (negative= (buffer[idx] ==
'-')) ==
true || buffer[idx] ==
'+' )
127 if( (idx= src.
template IndexOfAny<lang::Inclusion::Exclude, NC>( nf.
Whitespaces, idx + 1 ) ) == -1 )
138 && ( idx + prefixLen < srcLength )
140 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
143 result=
static_cast<int64_t
>(
ParseHex( src, idx, nf ) );
144 if( idx - prefixLen == oldIdx )
150 && ( idx + prefixLen < srcLength )
152 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
155 result=
static_cast<int64_t
>(
ParseBin( src, idx, nf ) );
156 if( idx - prefixLen == oldIdx )
162 && ( idx + prefixLen < srcLength )
164 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
167 result=
static_cast<int64_t
>(
ParseOct( src, idx, nf ) );
168 if( idx - prefixLen == oldIdx )
175 result=
static_cast<int64_t
>(
ParseDec( src, idx, nf ) );
183 return negative ?
static_cast<int64_t
>(-result)
184 :
static_cast<int64_t
>( result);
189template<
typename TChar>
195 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
200 bool charFound=
false;
203 const TChar* buf= src.
Buffer();
205 while ( idx < length )
207 const TChar c= buf[idx];
209 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
217 if ( c <
'0' || c >
'9' )
221 result= ( result * 10 ) +
static_cast<uint64_t
>( c -
'0' );
232template<
typename TChar>
238 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
243 bool charFound=
false;
246 const TChar* buf= src.
Buffer();
248 while ( idx < length )
252 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
288template<
typename TChar>
294 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
299 bool charFound=
false;
302 const TChar* buf= src.
Buffer();
304 while ( idx < length )
308 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
318 if ( c >=
'0' && c <=
'9' )
321 result|=
static_cast<uint64_t
>(c -
'0');
327 if ( c >=
'A' && c <=
'F' )
330 result|=
static_cast<uint64_t
>(c -
'A' + 10 );
336 if ( c >=
'a' && c <=
'f' )
339 result|=
static_cast<uint64_t
>(c -
'a' + 10 );
354template<
typename TChar>
360 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
365 bool charFound=
false;
368 const TChar* buf= src.
Buffer();
370 while ( idx < length )
374 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
382 if ( c >=
'0' && c <=
'7' )
385 result|=
static_cast<uint64_t
>(c -
'0');
399template<
typename TChar>
403 if( startIdx < 0 || startIdx >= src.
Length() )
408 const TChar* buf= src.
Buffer() + startIdx;
414 integer skip= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
417 buf+= skip - startIdx;
421 bool negative= (*buf ==
'-');
422 if ( negative || *buf ==
'+' )
424 if( ++buf == bufEnd )
434 if( buf + nf.
NANLiteral.Length() - 1 <= bufEnd
438 return std::numeric_limits<double>::quiet_NaN();
441 if( buf + nf.
INFLiteral.Length() - 1 <= bufEnd
445 return negative ? -std::numeric_limits<double>::infinity()
446 : std::numeric_limits<double>::infinity();
453 bool integralPartFound= isdigit(c);
454 if ( integralPartFound )
456 if ( c <
'0' || c >
'9' )
466 ALIB_ASSERT_ERROR( buf <= bufEnd,
"STRINGS",
"Error in float parsing algorithm." )
469 startIdx= buf - src.
Buffer();
470 return negative ? -result : result;
481 && *buf >=
'0' && *buf <=
'9' )
486 result+= ( intValue / pow( 10,
static_cast<double>(intIdx) ) );
489 else if( !integralPartFound )
496 bool eSepFound=
false;
498 if ( buf + sepLen < bufEnd )
504 if ( (eSepFound= ( pos == sepLen ) ) ==
true )
507 if ( !eSepFound && ( *buf ==
'e' || *buf ==
'E' ) )
514 if (eSepFound && buf < bufEnd)
516 bool negativeE=
false;
517 if ( (negativeE= (*buf ==
'-') ) ==
true || *buf ==
'+' )
527 result*= pow( 10, negativeE ? -exp : exp );
539 startIdx= buf - src.
Buffer();
542 return negative ? -result : result;
545template<
typename TChar>
549 int width= overrideWidth != 0 ? overrideWidth
552 if ( width < 1 ) width= 1;
561 int leadingBinaryZeros=
lang::CLZ(value);
562 digitsInValue= binSizeToDecSize[leadingBinaryZeros];
565 if( value < pow10_0to19[digitsInValue-1] )
569 && (digitsInValue == 20 || value < pow10_0to19[digitsInValue ]),
570 "STRINGS",
"Error in digitsInValue calculation" )
583 requestedDigits= width - width / 4;
589 requestedDigits= width;
592 printDigits= (std::max)( requestedDigits, digitsInValue );
597 "STRINGS",
"Internal error, false assumption" )
598 if( printDigits >1 && width > printDigits + (printDigits - 1) / 3 )
603 bool printSpace= hasBits(nf.
Flags, NumberFormatFlags::ReplaceLeadingZerosWithSpaces);
604 int actDigit= printDigits;
605 while ( actDigit > 0 )
608 int digitValue=
static_cast<int>( ( value / pow10_0to19[actDigit-1] ) );
613 && actDigit != printDigits
619 printSpace&= (digitValue == 0 && actDigit > 1);
620 buffer[idx++]= printSpace ? TChar(
' ') : TChar( 48 + digitValue );
623 value= value % pow10_0to19[actDigit-1];
631template<
typename TChar>
641 uValue=
static_cast<uint64_t
>( value );
647 uValue=
static_cast<uint64_t
>( -value );
651 int width= overrideWidth != 0 ? overrideWidth
653 if( idx != oldIdx && width > 1 )
660template<
typename TChar>
665 int groupWidth= !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) ? 0
673 int nextSeparator= 0;
676 int digits= overrideWidth != 0 ? overrideWidth : nf.
BinFieldWidth;
679 if ( groupWidth != 0 )
681 nextSeparator= digits<= groupWidth ? 0
682 : ( digits >= groupWidth
683 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
685 digits-= digits / (groupWidth + 1);
698 uint64_t testValue=
static_cast<uint64_t
>(1) << (digits - 1);
702 if( groupWidth != 0 && ( digits % groupWidth) == 0 )
704 if ( nextSeparator != 0 )
713 buffer[idx++]= ( value & testValue ) == 0L ?
'0' :
'1';
723template<
typename TChar>
728 int groupWidth= !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) ? 0
735 int nextSeparator= 0;
737 int digits= overrideWidth != 0 ? overrideWidth : nf.
HexFieldWidth;
742 if ( groupWidth != 0 )
744 nextSeparator= digits<= groupWidth ? 0
745 : ( digits >= groupWidth
746 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
748 digits-= digits / (groupWidth + 1);
754 digits= value != 0 ? (
lang::MSB(value)-1) / 4 + 1
761 unsigned int characterA=
static_cast<unsigned int>( hasBits(nf.
Flags, NumberFormatFlags::HexLowerCase) ?
'a' :
'A' );
762 int shiftBits= (digits -1 ) * 4;
763 uint64_t testMask=
static_cast<uint64_t
>( 15 ) << shiftBits;
767 if( groupWidth != 0 && ( digits % groupWidth) == 0 )
769 if ( nextSeparator != 0 )
777 unsigned int nibble=
static_cast<unsigned int>( ( value & testMask ) >> shiftBits );
778 buffer[idx++]= ( nibble < 10 ) ? static_cast<TChar>(
'0' + nibble)
779 :
static_cast<TChar
>(characterA + (nibble - 10));
790template<
typename TChar>
795 const int groupWidth= hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) && nf.
OctGroupChar !=
'\0' ? 3 : 0;
799 int nextSeparator= 0;
802 int digits= overrideWidth != 0 ? overrideWidth : nf.
OctFieldWidth;
805 if ( groupWidth != 0 )
807 nextSeparator= digits<= groupWidth ? 0
808 : ( digits >= groupWidth
809 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
811 digits-= digits / (groupWidth + 1);
817 digits= value != 0 ? (
lang::MSB(value)-1) / 3 + 1
824 int shiftBits= (digits -1 ) * 3;
828 if( groupWidth != 0 && ( digits % groupWidth) == 0 )
830 if ( nextSeparator != 0 )
836 auto octet= ( value & (
static_cast<uint64_t
>(7) << shiftBits) ) >> shiftBits;
837 buffer[idx++]=
static_cast<TChar
>(
'0' + octet);
847template<
typename TChar>
855 auto classification= std::fpclassify(value);
856 if( classification == FP_NAN ) {
return idx+= nf.
NANLiteral.CopyTo(buffer + idx); }
857 bool isNegative= std::signbit(value);
860 if( classification == FP_ZERO )
870 if( classification == FP_INFINITE )
876 return idx+= nf.
INFLiteral.CopyTo(buffer + idx);
880 constexpr int MaxFloatSignificantDigits= 16;
884 int exp10= value != 0.0 ?
static_cast<int>( floor(log10( value ) ) )
888 bool scientific= ( hasBits(nf.
Flags, NumberFormatFlags::ForceScientific)
890 || ( integralWidth > 0 && exp10 != 0 && exp10 >= (MaxFloatSignificantDigits - integralWidth - 1 ) )
894 integralWidth= (std::min) ( integralWidth, 15 );
902 int unusedFractDigits;
908 auto dotPos= MaxFloatSignificantDigits - exp10;
909 intPart=
static_cast<uint64_t
>(llrint( value * pow( 10, dotPos ) ));
910 fractPart= intPart % pow10_0to19[ MaxFloatSignificantDigits ];
911 intPart= intPart / pow10_0to19[ MaxFloatSignificantDigits ];
917 ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero < 20)
918 while ( fractPart < pow10_0to19[ MaxFloatSignificantDigits - firstNonZero - 1 ] )
920 ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero > 0)
924 unusedFractDigits= fractionalDigits >= 0 ? MaxFloatSignificantDigits - fractionalDigits
929 else if (exp10 >= 0 )
931 int intPartSize= MaxFloatSignificantDigits - exp10;
932 ALIB_ASSERT( intPartSize > 0 && intPartSize <= MaxFloatSignificantDigits )
933 intPart=
static_cast<uint64_t
>(llrint( value * pow( 10, intPartSize ) ));
934 fractPart= intPart % pow10_0to19[ intPartSize ];
935 intPart= intPart / pow10_0to19[ intPartSize ];
941 while ( fractPart < pow10_0to19[ intPartSize - firstNonZero - 1 ] )
947 unusedFractDigits= fractionalDigits >= 0 ? intPartSize - fractionalDigits
955 firstNonZero= -exp10;
957 fractPart=
static_cast<uint64_t
>(llrint( value * pow( 10, MaxFloatSignificantDigits + firstNonZero) ));
958 unusedFractDigits= fractionalDigits >= 0 ? MaxFloatSignificantDigits - ( fractionalDigits - firstNonZero )
963 if ( (fractionalDigits < 0 || fractionalDigits >= firstNonZero - 1 )
964 && unusedFractDigits > 0
965 && unusedFractDigits <= 18 )
968 uint64_t rest= fractPart % pow10_0to19[ unusedFractDigits ];
969 fractPart = fractPart / pow10_0to19[ unusedFractDigits ];
970 if ( rest > pow10_0to19[ unusedFractDigits ] / 2 )
973 int overflowDigit= 0;
974 bool overflow=
false;
975 while ( (overflowDigit <= fractionalDigits || fractionalDigits < 0 )
976 && (overflow|= fractPart == pow10_0to19[ overflowDigit ]) ==
false
977 && fractPart > pow10_0to19[ overflowDigit ]
983 if ( overflowDigit == (fractionalDigits >= 0 ? fractionalDigits : 15) )
1002 && ( fractionalDigits < 0 || fractionalDigits > firstNonZero -1)
1010 if ( intPart != 0L || integralWidth != 0 )
1014 if ( fractionalDigits != 0 || hasBits(nf.
Flags, NumberFormatFlags::ForceDecimalPoint) )
1018 if (fractionalDigits != 0)
1020 int fractZeros= firstNonZero - 1;
1021 if ( fractionalDigits > 0 && fractZeros > fractionalDigits )
1022 fractZeros= fractionalDigits;
1024 for (
int i= 0 ; i < fractZeros ; ++i )
1027 int qtyDigits= fractionalDigits - fractZeros;
1028 int actDigit= MaxFloatSignificantDigits + 1;
1029 int cntOmittedZeros= 0;
1031 bool printStarted=
false;
1032 while ( fractPart > 0
1033 && ( qtyDigits< 0 || cntDigits < qtyDigits )
1039 int digitValue=
static_cast<int>( ( fractPart / pow10_0to19[actDigit] ) );
1044 if ( (printStarted|= (digitValue != 0)) ==
false )
1049 if ( digitValue == 0 )
1053 for (
int i= 0; i< cntOmittedZeros ; ++i )
1056 buffer[idx++]=
static_cast<TChar
>( 48 + digitValue );
1060 fractPart= fractPart % pow10_0to19[actDigit];
1064 if (fractionalDigits < 0 )
1068 if ( cntDigits < qtyDigits )
1070 if ( hasBits(nf.
Flags, NumberFormatFlags::OmitTrailingFractionalZeros) )
1072 if( cntDigits == 0 )
1077 for (
int i= 0; i< cntOmittedZeros ; ++i )
1079 cntDigits+= cntOmittedZeros;
1082 for (
int i= cntDigits; i< qtyDigits; ++i )
1097 else if ( hasBits(nf.
Flags, NumberFormatFlags::WriteExponentPlusSign) )
1100 idx=
WriteDecUnsigned(
static_cast<uint64_t
>(exp10 >= 0 ? exp10 : -exp10), buffer, idx, 2, nf );