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>
 
   83    if( idx < 0  || idx >= length )
 
   86    const TChar* buf=    src.
Buffer();
 
   89    while ( idx < length )
 
   91        const TChar c= buf[idx];
 
   92        if ( c < 
'0' || c > 
'9' )
 
   95        result= ( result * 10 ) + uint64_t( c - 
'0'  );
 
  107template<
typename TChar>
 
  113    if ( startIdx < 0 || startIdx >= srcLength )
 
  117    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=  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=  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=  int64_t( 
ParseOct( src, idx, nf ) );
 
  168        if( idx - prefixLen == oldIdx )
 
  175        result=  int64_t( 
ParseDec( src, idx, nf ) );
 
  183    return negative ? int64_t(-result)
 
  189template<
typename TChar>
 
  195    integer idx= src. 
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
 
  200    bool         charFound=  
false;
 
  202    const TChar* buf=        src.
Buffer();
 
  203    while ( idx < length )
 
  205        const TChar c= buf[idx];
 
  207             && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
 
  215        if ( c < 
'0' || c > 
'9' )
 
  219        result= ( result * 10 ) + uint64_t( c - 
'0' );
 
  230template<
typename TChar>
 
  236    integer idx= src. 
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
 
  241    bool        charFound=  
false;
 
  243    const TChar* buf     =  src.
Buffer();
 
  244    while ( idx < length )
 
  248             && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
 
  284template<
typename TChar>
 
  290    integer idx= src. 
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
 
  295    bool         charFound=  
false;
 
  297    const TChar* buf=        src.
Buffer();
 
  298    while ( idx < length )
 
  302             && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
 
  312        if ( c >= 
'0' && c <= 
'9' )
 
  315            result|=  uint64_t(c - 
'0');
 
  321        if ( c >= 
'A' && c <= 
'F' )
 
  324            result|=  uint64_t(c - 
'A' + 10 );
 
  330        if ( c >= 
'a' && c <= 
'f' )
 
  333            result|=  uint64_t(c - 
'a' + 10 );
 
  348template<
typename TChar>
 
  354    integer idx= src. 
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
 
  359    bool         charFound=  
false;
 
  361    const TChar* buf=        src.
Buffer();
 
  362    while ( idx < length )
 
  366             && hasBits(nf.
Flags, NumberFormatFlags::ReadGroupChars)
 
  374        if ( c >= 
'0' && c <= 
'7' )
 
  377            result|=  uint64_t(c - 
'0');
 
  391template<
typename TChar>
 
  395    if( startIdx < 0 || startIdx >= src.
Length() )
 
  399    const TChar* buf=    src.
Buffer() + startIdx;
 
  404        integer skip= src. 
template IndexOfAny<lang::Inclusion::Exclude>( nf.
Whitespaces, startIdx );
 
  407        buf+= skip - startIdx;
 
  411    bool negative= (*buf == 
'-');
 
  412    if ( negative || *buf == 
'+' )
 
  414        if( ++buf == bufEnd )
 
  424    if(     buf + nf.
NANLiteral.Length() - 1 <= bufEnd
 
  428        return std::numeric_limits<double>::quiet_NaN();
 
  431    if(     buf + nf.
INFLiteral.Length() - 1 <= bufEnd
 
  435        return negative ? -std::numeric_limits<double>::infinity()
 
  436                        :  std::numeric_limits<double>::infinity();
 
  443    bool integralPartFound= isdigit(
int(c));
 
  444    if ( integralPartFound )
 
  446        if (  c < 
'0' || c > 
'9' )
 
  456        ALIB_ASSERT_ERROR( buf <= bufEnd, 
"STRINGS", 
"Error in float parsing algorithm." )
 
  459            startIdx= buf - src.
Buffer();
 
  460            return negative ? -result : result;
 
  471             &&  *buf >= 
'0'  &&  *buf <= 
'9' )
 
  476            result+= ( intValue / pow( 10, 
double(intIdx) ) );
 
  479    else if( !integralPartFound )
 
  486        bool eSepFound=  
false;
 
  488        if ( buf + sepLen < bufEnd )
 
  494            if ( (eSepFound= ( pos == sepLen ) ) == 
true )
 
  497        if ( !eSepFound && ( *buf == 
'e' || *buf == 
'E' ) )
 
  504        if (eSepFound && buf < bufEnd)
 
  506            bool negativeE= 
false;
 
  507            if ( (negativeE= (*buf == 
'-') ) == 
true ||  *buf == 
'+' )
 
  517                    result*= pow( 10, negativeE ? -exp : exp );
 
  529    startIdx= buf - src.
Buffer();
 
  532    return negative ? -result : result;
 
  535template<
typename TChar>
 
  539    int width= overrideWidth != 0 ? overrideWidth
 
  542    if ( width < 1  )   width=  1;
 
  551            int leadingBinaryZeros= 
lang::CLZ(value);
 
  552            digitsInValue= binSizeToDecSize[leadingBinaryZeros];
 
  555            if( value < pow10_0to19[digitsInValue-1] )
 
  559                                  && (digitsInValue == 20 || value <  pow10_0to19[digitsInValue  ]),
 
  560                              "STRINGS", 
"Error calculating the number of digits in value {}",
 
  574            requestedDigits=  width - width / 4;
 
  580            requestedDigits= width;
 
  583        printDigits= (std::max)( requestedDigits, digitsInValue );
 
  588                             "STRINGS", 
"Internal error, false assumption" )
 
  589        if( printDigits >1  && width > printDigits + (printDigits - 1) / 3 )
 
  594    bool printSpace= hasBits(nf.
Flags, NumberFormatFlags::ReplaceLeadingZerosWithSpaces);
 
  595    int  actDigit=      printDigits;
 
  596    while ( actDigit > 0 )
 
  599        int digitValue=   int( ( value / pow10_0to19[actDigit-1] ) );
 
  604            &&  actDigit != printDigits
 
  610        printSpace&= (digitValue == 0 && actDigit > 1);
 
  611        buffer[idx++]=  printSpace ? TChar(
' ') : TChar( 48 + digitValue ); 
 
  614        value=    value % pow10_0to19[actDigit-1];
 
  622template<
typename TChar>
 
  632        uValue= uint64_t( value );
 
  638        uValue= uint64_t( -value );
 
  642    int width= overrideWidth != 0 ? overrideWidth
 
  644    if( idx != oldIdx && width > 1 )
 
  651template<
typename TChar>
 
  656    int groupWidth=   !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars)             ? 0
 
  664    int nextSeparator= 0; 
 
  667    int digits=  overrideWidth != 0 ? overrideWidth  : nf.
BinFieldWidth;
 
  670        if ( groupWidth != 0 )
 
  672            nextSeparator=  digits<= groupWidth ? 0
 
  673                            :   (     digits >= groupWidth
 
  674                                  && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
 
  676            digits-= digits / (groupWidth + 1); 
 
  689    uint64_t testValue= uint64_t(1) << (digits - 1);
 
  693        if( groupWidth != 0 && ( digits % groupWidth) == 0 )
 
  695            if ( nextSeparator != 0 )
 
  704        buffer[idx++]= ( value & testValue ) == 0L ? 
'0' : 
'1';
 
  714template<
typename TChar>
 
  719    int groupWidth=  !hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars)             ? 0
 
  726    int nextSeparator= 0; 
 
  728    int digits= overrideWidth != 0 ? overrideWidth : nf.
HexFieldWidth;
 
  733        if ( groupWidth != 0 )
 
  735            nextSeparator=  digits<= groupWidth ? 0
 
  736                            :   (     digits >= groupWidth
 
  737                                  && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
 
  739            digits-= digits / (groupWidth + 1); 
 
  745        digits=  value != 0 ? (
lang::MSB(value)-1) / 4 + 1
 
  752    unsigned int characterA= 
static_cast<unsigned int>( hasBits(nf.
Flags, NumberFormatFlags::HexLowerCase) ? 
'a' : 
'A' );
 
  753    int          shiftBits= (digits -1 ) * 4;
 
  754    uint64_t testMask=  uint64_t( 15 ) << shiftBits;
 
  758        if( groupWidth != 0 && ( digits % groupWidth) == 0 )
 
  760            if ( nextSeparator != 0 )
 
  768        unsigned int nibble= 
static_cast<unsigned int>( ( value & testMask ) >> shiftBits );
 
  769        buffer[idx++]=   ( nibble < 10 )   ?  static_cast<TChar>(
'0' + nibble)
 
  770                                           :  
static_cast<TChar
>(characterA + (nibble - 10));
 
  781template<
typename TChar>
 
  786    const int groupWidth=  hasBits(nf.
Flags, NumberFormatFlags::WriteGroupChars) && nf.
OctGroupChar != 
'\0' ? 3 : 0;
 
  790    int nextSeparator= 0; 
 
  793    int digits= overrideWidth != 0 ? overrideWidth : nf.
OctFieldWidth;
 
  796        if ( groupWidth != 0 )
 
  798            nextSeparator=  digits<= groupWidth ? 0
 
  799                            :   (     digits >= groupWidth
 
  800                                  && (digits % (groupWidth + 1)) == 0 ) ? 1 : 2;
 
  802            digits-= digits / (groupWidth + 1); 
 
  808        digits=  value != 0 ? (
lang::MSB(value)-1) / 3 + 1
 
  815    int           shiftBits= (digits -1 ) * 3;
 
  819        if( groupWidth != 0 && ( digits % groupWidth) == 0 )
 
  821            if ( nextSeparator != 0 )
 
  827        auto octet= ( value & (uint64_t(7) << shiftBits) ) >> shiftBits;
 
  828        buffer[idx++]= 
static_cast<TChar
>(
'0' + octet);
 
  838template<
typename TChar>
 
  846    auto classification=  std::fpclassify(value);
 
  847    if( classification == FP_NAN )    {  
return idx+= nf.
NANLiteral.CopyTo(buffer + idx);   }
 
  848    bool isNegative= std::signbit(value);
 
  851        if( classification == FP_ZERO )
 
  861    if( classification == FP_INFINITE )
 
  867        return idx+= nf.
INFLiteral.CopyTo(buffer + idx);
 
  871    constexpr int MaxFloatSignificantDigits= 16;
 
  875    int exp10=      value != 0.0   ? int( floor(log10( value ) ) )
 
  879    bool scientific=  (     hasBits(nf.
Flags, NumberFormatFlags::ForceScientific)
 
  881                        || (  integralWidth          > 0 && exp10 != 0 && exp10 >= (MaxFloatSignificantDigits - integralWidth          - 1 ) )
 
  885    integralWidth=         (std::min) ( integralWidth,                 15 );
 
  893    int unusedFractDigits;
 
  899        auto dotPos= MaxFloatSignificantDigits - exp10;
 
  900        intPart=     uint64_t(llrint( value * pow( 10, dotPos ) ));
 
  901        fractPart=   intPart %  pow10_0to19[ MaxFloatSignificantDigits ];
 
  902        intPart=     intPart /  pow10_0to19[ MaxFloatSignificantDigits ];
 
  908            ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero < 20, 
"STRINGS")
 
  909            while ( fractPart < pow10_0to19[ MaxFloatSignificantDigits - firstNonZero - 1 ] )
 
  911            ALIB_ASSERT( MaxFloatSignificantDigits - firstNonZero > 0, 
"STRINGS")
 
  915        unusedFractDigits= fractionalDigits >= 0 ?  MaxFloatSignificantDigits - fractionalDigits
 
  920     else if (exp10 >= 0 )
 
  922        int intPartSize= MaxFloatSignificantDigits - exp10;
 
  923        ALIB_ASSERT( intPartSize > 0  && intPartSize <= MaxFloatSignificantDigits, 
"STRINGS" )
 
  924        intPart=     uint64_t(llrint( value * pow( 10, intPartSize ) ));
 
  925        fractPart=   intPart %  pow10_0to19[ intPartSize ];
 
  926        intPart=     intPart /  pow10_0to19[ intPartSize ];
 
  932            while ( fractPart < pow10_0to19[ intPartSize - firstNonZero - 1 ] )
 
  934            ALIB_ASSERT( intPartSize - firstNonZero > 0, 
"STRINGS" )
 
  938        unusedFractDigits= fractionalDigits >= 0 ?  intPartSize - fractionalDigits
 
  946        firstNonZero= -exp10;
 
  948        fractPart=    uint64_t(llrint( value * pow( 10, MaxFloatSignificantDigits + firstNonZero) ));
 
  949        unusedFractDigits= fractionalDigits >= 0 ?  MaxFloatSignificantDigits - ( fractionalDigits - firstNonZero )
 
  954    if (     (fractionalDigits < 0 || fractionalDigits  >= firstNonZero - 1 )
 
  955         &&  unusedFractDigits >  0
 
  956         &&  unusedFractDigits <= 18 )
 
  959        uint64_t rest= fractPart % pow10_0to19[ unusedFractDigits ];
 
  960        fractPart    = fractPart / pow10_0to19[ unusedFractDigits ];
 
  961        if ( rest > pow10_0to19[ unusedFractDigits ] / 2 )
 
  964            int  overflowDigit= 0;
 
  965            bool overflow=      
false;
 
  966            while (    (overflowDigit <= fractionalDigits || fractionalDigits < 0 )
 
  967                    && (overflow|= fractPart == pow10_0to19[ overflowDigit ]) == 
false 
  968                    &&  fractPart > pow10_0to19[ overflowDigit ]
 
  974                if ( overflowDigit == (fractionalDigits >= 0 ? fractionalDigits : 15) )
 
  993                 && ( fractionalDigits < 0 || fractionalDigits > firstNonZero -1)
 
 1001    if ( intPart != 0L || integralWidth != 0 )
 
 1005    if ( fractionalDigits != 0 || hasBits(nf.
Flags, NumberFormatFlags::ForceDecimalPoint) )
 
 1009    if (fractionalDigits != 0)
 
 1011        int fractZeros= firstNonZero - 1;
 
 1012        if ( fractionalDigits > 0 && fractZeros > fractionalDigits )
 
 1013            fractZeros= fractionalDigits;
 
 1015        for ( 
int i= 0 ; i < fractZeros ; ++i )
 
 1018        int  qtyDigits=        fractionalDigits - fractZeros;
 
 1019        int  actDigit=         MaxFloatSignificantDigits + 1;
 
 1020        int  cntOmittedZeros=  0;
 
 1022        bool printStarted=     
false;
 
 1023        while (    fractPart > 0
 
 1024                && ( qtyDigits< 0 || cntDigits < qtyDigits )
 
 1030            int digitValue=   int(  ( fractPart  / pow10_0to19[actDigit] ) );
 
 1035            if ( (printStarted|= (digitValue != 0)) == 
false )
 
 1040            if ( digitValue == 0 )
 
 1044                for ( 
int i= 0; i< cntOmittedZeros ; ++i )
 
 1047                buffer[idx++]= 
static_cast<TChar
>( 48 + digitValue ); 
 
 1051            fractPart=    fractPart % pow10_0to19[actDigit];
 
 1055        if (fractionalDigits < 0 )
 
 1059        if ( cntDigits < qtyDigits )
 
 1061            if ( hasBits(nf.
Flags, NumberFormatFlags::OmitTrailingFractionalZeros) )
 
 1063                if( cntDigits == 0 )
 
 1068                for ( 
int i= 0; i< cntOmittedZeros ; ++i )
 
 1070                cntDigits+= cntOmittedZeros;
 
 1073                for ( 
int i= cntDigits; i< qtyDigits; ++i )
 
 1088        else if ( hasBits(nf.
Flags, NumberFormatFlags::WriteExponentPlusSign) )
 
 1091        idx= 
WriteDecUnsigned( uint64_t(exp10 >= 0 ? exp10 : -exp10), buffer, idx, 2, nf );