46constexpr const uint64_t pow10_0to19[]=
66 1000000000000000000UL,
67 10000000000000000000UL,
71constexpr const uint8_t binSizeToDecSize[]
73 20, 19, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 16, 15,
74 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10,
75 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6,
76 05, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1
80{
return ((
int(lhs) &
int(rhs)) != 0); }
86template<
typename TChar>
93 if( idx < 0 || idx >= length )
97 const TChar* buf= src.
Buffer();
101 while ( idx < length )
103 const TChar c= buf[idx];
104 if ( c <
'0' || c >
'9' )
107 result= ( result * 10 ) +
static_cast<uint64_t
>( c -
'0' );
119template<
typename TChar>
125 if ( startIdx < 0 || startIdx >= srcLength )
130 const TChar* buffer= src.
Buffer();
133 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude, false>( nf.
Whitespaces, startIdx );
139 if ( (negative= (buffer[idx] ==
'-')) ==
true || buffer[idx] ==
'+' )
141 if( (idx= src.
template IndexOfAny<lang::Inclusion::Exclude, false>( nf.
Whitespaces, idx + 1 ) ) == -1 )
152 && ( idx + prefixLen < srcLength )
154 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
157 result=
static_cast<int64_t
>(
ParseHex( src, idx, nf ) );
158 if( idx - prefixLen == oldIdx )
164 && ( idx + prefixLen < srcLength )
166 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
169 result=
static_cast<int64_t
>(
ParseBin( src, idx, nf ) );
170 if( idx - prefixLen == oldIdx )
176 && ( idx + prefixLen < srcLength )
178 && nf.
Whitespaces.IndexOf( buffer[ idx + prefixLen ] ) == -1 )
181 result=
static_cast<int64_t
>(
ParseOct( src, idx, nf ) );
182 if( idx - prefixLen == oldIdx )
189 result=
static_cast<int64_t
>(
ParseDec( src, idx, nf ) );
197 return negative ?
static_cast<int64_t
>(-result)
198 :
static_cast<int64_t
>( result);
203template<
typename TChar>
209 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
214 bool charFound=
false;
217 const TChar* buf= src.
Buffer();
219 while ( idx < length )
221 const TChar c= buf[idx];
223 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
231 if ( c <
'0' || c >
'9' )
235 result= ( result * 10 ) +
static_cast<uint64_t
>( c -
'0' );
246template<
typename TChar>
252 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
257 bool charFound=
false;
260 const TChar* buf= src.
Buffer();
262 while ( idx < length )
266 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
302template<
typename TChar>
308 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
313 bool charFound=
false;
316 const TChar* buf= src.
Buffer();
318 while ( idx < length )
322 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
332 if ( c >=
'0' && c <=
'9' )
335 result|=
static_cast<uint64_t
>(c -
'0');
341 if ( c >=
'A' && c <=
'F' )
344 result|=
static_cast<uint64_t
>(c -
'A' + 10 );
350 if ( c >=
'a' && c <=
'f' )
353 result|=
static_cast<uint64_t
>(c -
'a' + 10 );
368template<
typename TChar>
374 integer idx= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
379 bool charFound=
false;
382 const TChar* buf= src.
Buffer();
384 while ( idx < length )
388 && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
396 if ( c >=
'0' && c <=
'7' )
399 result|=
static_cast<uint64_t
>(c -
'0');
413template<
typename TChar>
417 if( startIdx < 0 || startIdx >= src.
Length() )
422 const TChar* buf= src.
Buffer() + startIdx;
428 integer skip= src.
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
431 buf+= skip - startIdx;
435 bool negative= (*buf ==
'-');
436 if ( negative || *buf ==
'+' )
438 if( ++buf == bufEnd )
448 if( buf + nf.
NANLiteral.Length() - 1 <= bufEnd
452 return std::numeric_limits<double>::quiet_NaN();
455 if( buf + nf.
INFLiteral.Length() - 1 <= bufEnd
459 return negative ? -std::numeric_limits<double>::infinity()
460 : std::numeric_limits<double>::infinity();
467 bool integralPartFound= isdigit(c);
468 if ( integralPartFound )
470 if ( c <
'0' || c >
'9' )
480 ALIB_ASSERT_ERROR( buf <= bufEnd,
"STRINGS",
"Error in float parsing algorithm." )
483 startIdx= buf - src.
Buffer();
484 return negative ? -result : result;
495 && *buf >=
'0' && *buf <=
'9' )
500 result+= ( intValue / pow( 10,
static_cast<double>(intIdx) ) );
503 else if( !integralPartFound )
510 bool eSepFound=
false;
512 if ( buf + sepLen < bufEnd )
518 if ( (eSepFound= ( pos == sepLen ) ) ==
true )
521 if ( !eSepFound && ( *buf ==
'e' || *buf ==
'E' ) )
528 if (eSepFound && buf < bufEnd)
530 bool negativeE=
false;
531 if ( (negativeE= (*buf ==
'-') ) ==
true || *buf ==
'+' )
541 result*= pow( 10, negativeE ? -exp : exp );
553 startIdx= buf - src.
Buffer();
556 return negative ? -result : result;
559template<
typename TChar>
563 int width= overrideWidth != 0 ? overrideWidth
566 if ( width < 1 ) width= 1;
575 int leadingBinaryZeros=
lang::CLZ(value);
576 digitsInValue= binSizeToDecSize[leadingBinaryZeros];
579 if( value < pow10_0to19[digitsInValue-1] )
583 && ( digitsInValue == 20 || value < pow10_0to19[ digitsInValue ] ),
584 "STRINGS",
"Error in digitsInValue calculation" )
597 requestedDigits= width - width / 4;
603 requestedDigits= width;
606 printDigits= (std::max)( requestedDigits, digitsInValue );
611 "STRINGS",
"Internal error, false assumption" )
612 if( printDigits >1 && width > printDigits + (printDigits - 1) / 3 )
617 int actDigit= printDigits;
618 while ( actDigit > 0 )
621 int digitValue=
static_cast<int>( ( value / pow10_0to19[actDigit-1] ) );
626 && actDigit != printDigits
632 buffer[idx++]=
static_cast<TChar
>( 48 + digitValue );
635 value= value % pow10_0to19[actDigit-1];
643template<
typename TChar>
653 uValue=
static_cast<uint64_t
>( value );
659 uValue=
static_cast<uint64_t
>( -value );
663 int width= overrideWidth != 0 ? overrideWidth
665 if( idx != oldIdx && width > 1 )
672template<
typename TChar>
677 int groupWidth= !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) ? 0
685 int nextSeparator= 0;
688 int digits= overrideWidth != 0 ? overrideWidth : nf.
BinFieldWidth;
691 if ( groupWidth != 0 )
693 nextSeparator= digits<= groupWidth ? 0
694 : ( digits >= groupWidth
695 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
697 digits-= digits / (groupWidth + 1);
710 uint64_t testValue=
static_cast<uint64_t
>(1) << (digits - 1);
714 if( groupWidth != 0 && ( digits % groupWidth) == 0 )
716 if ( nextSeparator != 0 )
725 buffer[idx++]= ( value & testValue ) == 0L ?
'0' :
'1';
735template<
typename TChar>
740 int groupWidth= !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) ? 0
747 int nextSeparator= 0;
749 int digits= overrideWidth != 0 ? overrideWidth : nf.
HexFieldWidth;
754 if ( groupWidth != 0 )
756 nextSeparator= digits<= groupWidth ? 0
757 : ( digits >= groupWidth
758 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
760 digits-= digits / (groupWidth + 1);
766 digits= value != 0 ? (
lang::MSB(value)-1) / 4 + 1
773 unsigned int characterA=
static_cast<unsigned int>( hasBits(nf.
Flags, NumberFormatFlags::HexLowerCase) ?
'a' :
'A' );
774 int shiftBits= (digits -1 ) * 4;
775 uint64_t testMask=
static_cast<uint64_t
>( 15 ) << shiftBits;
779 if( groupWidth != 0 && ( digits % groupWidth) == 0 )
781 if ( nextSeparator != 0 )
789 unsigned int nibble=
static_cast<unsigned int>( ( value & testMask ) >> shiftBits );
790 buffer[idx++]= ( nibble < 10 ) ? static_cast<TChar>(
'0' + nibble)
791 :
static_cast<TChar
>(characterA + (nibble - 10));
802template<
typename TChar>
807 const int groupWidth= hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) && nf.
OctGroupChar !=
'\0' ? 3 : 0;
811 int nextSeparator= 0;
814 int digits= overrideWidth != 0 ? overrideWidth : nf.
OctFieldWidth;
817 if ( groupWidth != 0 )
819 nextSeparator= digits<= groupWidth ? 0
820 : ( digits >= groupWidth
821 && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
823 digits-= digits / (groupWidth + 1);
829 digits= value != 0 ? (
lang::MSB(value)-1) / 3 + 1
836 int shiftBits= (digits -1 ) * 3;
840 if( groupWidth != 0 && ( digits % groupWidth) == 0 )
842 if ( nextSeparator != 0 )
848 auto octet= ( value & (
static_cast<uint64_t
>(7) << shiftBits) ) >> shiftBits;
849 buffer[idx++]=
static_cast<TChar
>(
'0' + octet);
859template<
typename TChar>
867 auto classification= std::fpclassify(value);
868 if( classification == FP_NAN ) {
return idx+= nf.
NANLiteral.CopyTo(buffer + idx); }
869 bool isNegative= std::signbit(value);
872 if( classification == FP_ZERO )
882 if( classification == FP_INFINITE )
888 return idx+= nf.
INFLiteral.CopyTo(buffer + idx);
892 constexpr int MaxFloatSignificantDigits= 16;
896 int exp10= value != 0.0 ?
static_cast<int>( floor(log10( value ) ) )
900 bool scientific= ( hasBits(nf.
Flags, NumberFormatFlags::ForceScientific)
902 || ( integralWidth > 0 && exp10 != 0 && exp10 >= (MaxFloatSignificantDigits - integralWidth - 1 ) )
906 integralWidth= (std::min) ( integralWidth, 15 );
914 int unusedFractDigits;
920 auto dotPos= MaxFloatSignificantDigits - exp10;
921 intPart=
static_cast<uint64_t
>(llrint( value * pow( 10, dotPos ) ));
922 fractPart= intPart % pow10_0to19[ MaxFloatSignificantDigits ];
923 intPart= intPart / pow10_0to19[ MaxFloatSignificantDigits ];
929 ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero < 20)
930 while ( fractPart < pow10_0to19[ MaxFloatSignificantDigits - firstNonZero - 1 ] )
932 ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero > 0)
936 unusedFractDigits= fractionalDigits >= 0 ? MaxFloatSignificantDigits - fractionalDigits
941 else if (exp10 >= 0 )
943 int intPartSize= MaxFloatSignificantDigits - exp10;
944 ALIB_ASSERT( intPartSize > 0 && intPartSize <= MaxFloatSignificantDigits )
945 intPart=
static_cast<uint64_t
>(llrint( value * pow( 10, intPartSize ) ));
946 fractPart= intPart % pow10_0to19[ intPartSize ];
947 intPart= intPart / pow10_0to19[ intPartSize ];
953 while ( fractPart < pow10_0to19[ intPartSize - firstNonZero - 1 ] )
959 unusedFractDigits= fractionalDigits >= 0 ? intPartSize - fractionalDigits
967 firstNonZero= -exp10;
969 fractPart=
static_cast<uint64_t
>(llrint( value * pow( 10, MaxFloatSignificantDigits + firstNonZero) ));
970 unusedFractDigits= fractionalDigits >= 0 ? MaxFloatSignificantDigits - ( fractionalDigits - firstNonZero )
975 if ( (fractionalDigits < 0 || fractionalDigits >= firstNonZero - 1 )
976 && unusedFractDigits > 0
977 && unusedFractDigits <= 18 )
980 uint64_t rest= fractPart % pow10_0to19[ unusedFractDigits ];
981 fractPart = fractPart / pow10_0to19[ unusedFractDigits ];
982 if ( rest > pow10_0to19[ unusedFractDigits ] / 2 )
985 int overflowDigit= 0;
986 bool overflow=
false;
987 while ( (overflowDigit <= fractionalDigits || fractionalDigits < 0 )
988 && (overflow|= fractPart == pow10_0to19[ overflowDigit ]) ==
false
989 && fractPart > pow10_0to19[ overflowDigit ]
995 if ( overflowDigit == (fractionalDigits >= 0 ? fractionalDigits : 15) )
1014 && ( fractionalDigits < 0 || fractionalDigits > firstNonZero -1)
1022 if ( intPart != 0L || integralWidth != 0 )
1026 if ( fractionalDigits != 0 || hasBits(nf.
Flags, NumberFormatFlags::ForceDecimalPoint) )
1030 if (fractionalDigits != 0)
1032 int fractZeros= firstNonZero - 1;
1033 if ( fractionalDigits > 0 && fractZeros > fractionalDigits )
1034 fractZeros= fractionalDigits;
1036 for (
int i= 0 ; i < fractZeros ; ++i )
1039 int qtyDigits= fractionalDigits - fractZeros;
1040 int actDigit= MaxFloatSignificantDigits + 1;
1041 int cntOmittedZeros= 0;
1043 bool printStarted=
false;
1044 while ( fractPart > 0
1045 && ( qtyDigits< 0 || cntDigits < qtyDigits )
1051 int digitValue=
static_cast<int>( ( fractPart / pow10_0to19[actDigit] ) );
1056 if ( (printStarted|= (digitValue != 0)) ==
false )
1061 if ( digitValue == 0 )
1065 for (
int i= 0; i< cntOmittedZeros ; ++i )
1068 buffer[idx++]=
static_cast<TChar
>( 48 + digitValue );
1072 fractPart= fractPart % pow10_0to19[actDigit];
1076 if (fractionalDigits < 0 )
1080 if ( cntDigits < qtyDigits )
1082 if ( hasBits(nf.
Flags, NumberFormatFlags::OmitTrailingFractionalZeros) )
1084 if( cntDigits == 0 )
1089 for (
int i= 0; i< cntOmittedZeros ; ++i )
1091 cntDigits+= cntOmittedZeros;
1094 for (
int i= cntDigits; i< qtyDigits; ++i )
1109 else if ( hasBits(nf.
Flags, NumberFormatFlags::WriteExponentPlusSign) )
1112 idx=
WriteDecUnsigned(
static_cast<uint64_t
>(exp10 >= 0 ? exp10 : -exp10), buffer, idx, 2, nf );