Ignore:
Timestamp:
Jul 5, 2020, 4:04:20 PM (16 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast, new-ast-unique-expr
Children:
9ec8c5f
Parents:
74cfafb2
Message:

new version for printing int128 values including manipulators

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    r74cfafb2 r2c60c644  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 19 16:15:34 2020
    13 // Update Count     : 1019
     12// Last Modified On : Sun Jul  5 08:14:07 2020
     13// Update Count     : 1063
    1414//
    1515
     
    3030} // extern "C"
    3131
    32 #include <bitmanip.hfa>                                                                 // fms
     32#include <bitmanip.hfa>                                                                 // high1
    3333
    3434
     
    168168
    169169        static void base10_128( ostype & os, unsigned int128 val ) {
    170                 if ( val > UINT64_MAX ) {
     170                if ( val > P10_UINT64 ) {
    171171                        base10_128( os, val / P10_UINT64 );                     // recursive
    172172                        fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
     
    455455
    456456// Default prefix for non-decimal prints is 0b, 0, 0x.
    457 #define IntegralFMTImpl( T, CODE, IFMTNP, IFMTP ) \
     457#define IntegralFMTImpl( T, IFMTNP, IFMTP ) \
    458458forall( dtype ostype | ostream( ostype ) ) { \
    459459        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     
    506506                        if ( f.flags.left && spaces > 0 ) fmt( os, "%*s", spaces, " " ); \
    507507                        return os; \
    508                 } /* if  */ \
     508                } /* if */ \
    509509\
    510510                char fmtstr[sizeof(IFMTP)];                                             /* sizeof includes '\0' */ \
     
    516516                if ( ! f.flags.nobsdp ) { fmtstr[star] = '#'; star -= 1; } \
    517517                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
    518                 if ( f.flags.sign && f.base == CODE ) { fmtstr[star] = '+'; star -= 1; } \
     518                if ( f.flags.sign ) { fmtstr[star] = '+'; star -= 1; } \
    519519                if ( f.flags.pad0 && ! f.flags.pc ) { fmtstr[star] = '0'; star -= 1; } \
    520520                fmtstr[star] = '%'; \
     
    522522                if ( ! f.flags.pc ) {                                                   /* no precision */ \
    523523                        fmtstr[sizeof(IFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
    524                         /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
     524                        /* printf( "%s %c\n", &fmtstr[star], f.base ); */ \
    525525                        fmt( os, &fmtstr[star], f.wd, f.val ); \
    526526                } else {                                                                                /* precision */ \
    527527                        fmtstr[sizeof(IFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    528                         /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
     528                        /* printf( "%s %c\n", &fmtstr[star], f.base ); */ \
    529529                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
    530530                } /* if */ \
     
    534534} // distribution
    535535
    536 IntegralFMTImpl( signed char, 'd', "%    *hh ", "%    *.*hh " )
    537 IntegralFMTImpl( unsigned char, 'u', "%    *hh ", "%    *.*hh " )
    538 IntegralFMTImpl( signed short int, 'd', "%    *h ", "%    *.*h " )
    539 IntegralFMTImpl( unsigned short int, 'u', "%    *h ", "%    *.*h " )
    540 IntegralFMTImpl( signed int, 'd', "%    * ", "%    *.* " )
    541 IntegralFMTImpl( unsigned int, 'u', "%    * ", "%    *.* " )
    542 IntegralFMTImpl( signed long int, 'd', "%    *l ", "%    *.*l " )
    543 IntegralFMTImpl( unsigned long int, 'u', "%    *l ", "%    *.*l " )
    544 IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
    545 IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
    546 
    547 
     536IntegralFMTImpl( signed char, "%    *hh ", "%    *.*hh " )
     537IntegralFMTImpl( unsigned char, "%    *hh ", "%    *.*hh " )
     538IntegralFMTImpl( signed short int, "%    *h ", "%    *.*h " )
     539IntegralFMTImpl( unsigned short int, "%    *h ", "%    *.*h " )
     540IntegralFMTImpl( signed int, "%    * ", "%    *.* " )
     541IntegralFMTImpl( unsigned int, "%    * ", "%    *.* " )
     542IntegralFMTImpl( signed long int, "%    *l ", "%    *.*l " )
     543IntegralFMTImpl( unsigned long int, "%    *l ", "%    *.*l " )
     544IntegralFMTImpl( signed long long int, "%    *ll ", "%    *.*ll " )
     545IntegralFMTImpl( unsigned long long int, "%    *ll ", "%    *.*ll " )
     546
     547#if 0
    548548#if defined( __SIZEOF_INT128__ )
    549549// Default prefix for non-decimal prints is 0b, 0, 0x.
     
    663663IntegralFMTImpl128( unsigned int128, unsigned, 'u', "%    *ll ", "%    *.*ll " )
    664664#endif // __SIZEOF_INT128__
     665#endif // 0
     666
     667#if 1
     668#if defined( __SIZEOF_INT128__ )
     669// Default prefix for non-decimal prints is 0b, 0, 0x.
     670forall( dtype ostype | ostream( ostype ) )
     671static inline void base_128( ostype & os, unsigned int128 val, unsigned int128 power, _Ostream_Manip(uint64_t) & f, unsigned int maxdig, unsigned int bits, unsigned int cnt = 0 ) {
     672        int wd = 1;                                                                                     // f.wd is never 0 because 0 implies left-pad
     673        if ( val > power ) {                                                            // subdivide value into printable 64-bit values
     674                base_128( os, val / power, power, f, maxdig, bits, cnt + 1 ); // recursive
     675                f.val = val % power;
     676                if ( cnt == 1 && f.flags.left ) { wd = f.wd; f.wd = maxdig; } // copy f.wd across printing of middle value
     677                (ostype &)(os | f);
     678                if ( cnt == 1 ) {
     679                        if ( f.flags.left ) { wd -= maxdig; f.wd = wd < 0 ? 1 : wd; }
     680                        sepOff( os );                                                           // no seperator between chunks
     681                } // if
     682        } else {
     683                f.val = val;
     684                // f.pc is unsigned => use wd
     685                if ( f.flags.pc && f.pc > maxdig * cnt ) { wd = f.pc - maxdig * cnt; f.pc = wd < 0 ? 0 : wd; }
     686                else { f.flags.pc = false; f.pc = 0; }
     687
     688                if ( ! f.flags.left ) {                                                 // right justify
     689                        wd = f.wd - maxdig * cnt;
     690                        f.wd = wd < 0 ? 1 : wd;
     691                        wd = maxdig;
     692                } else {                                                                                // left justify
     693                        if ( cnt != 0 ) {                                                       // value >= 2^64 ?
     694                                unsigned int dig, bs = 0;
     695                                // compute size of prefix base and digits
     696                                if ( f.base == 'd' || f.base == 'u' ) { // no base prefix
     697                                        dig = ceil( log10( f.val ) );           // use floating-point
     698                                        if ( f.base == 'd' && (f.flags.neg || f.flags.sign) ) bs = 1; // sign ?
     699                                } else {
     700                                        dig = ceiling( high1( f.val ), bits );
     701                                        if ( ! f.flags.nobsdp ) {                       // base prefix ?
     702                                                if ( f.base == 'o' ) {
     703                                                        // 0 prefix for octal is not added for precision with leading zero
     704                                                        if ( f.pc <= dig ) bs = 1;      // 1 character prefix
     705                                                } else bs = 2;                                  // 2 character prefix
     706                                        } // if
     707                                } // if
     708                                wd = f.wd - (f.pc > dig ? f.pc : dig) - bs; // precision > leading digits ?
     709                                if ( wd < 0 ) wd = 1;
     710                                f.wd = 1;
     711                        } // if
     712                        // all manipulators handled implicitly for value < 2^64
     713                } // if
     714                // prior checks ensure wd not negative
     715
     716                if ( f.flags.neg ) f.val = -f.val;
     717                (ostype &)(os | f);
     718
     719                if ( ! f.flags.left ) { f.flags.pad0 = true; f.flags.pc = false; } // left pad with 0s
     720                else { f.pc = maxdig; f.flags.pc = true; }              // left pad with precision
     721                if ( cnt != 0 ) sepOff( os );                                   // no seperator between chunks
     722                f.wd = wd;
     723                f.flags.sign = false;                                                   // no +/- sign
     724                f.flags.nobsdp = true;                                                  // no base prefix
     725        } // if
     726} // base_128
     727
     728#define IntegralFMTImpl128( T ) \
     729forall( dtype ostype | ostream( ostype ) ) { \
     730        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     731                _Ostream_Manip(uint64_t) fmt; \
     732                fmt.[wd, pc, base, all] = f.[wd, pc, base, all]; \
     733                if ( f.base == 'b' | f.base == 'B' ) { \
     734                        base_128( os, f.val, (unsigned int128)1 << 64, fmt, 64, 1 ); \
     735                } else if ( f.base == 'o' ) { \
     736                        base_128( os, f.val, (unsigned int128)1 << 63, fmt, 21, 3 ); \
     737                } else if ( f.base == 'd' || f.base == 'u' ) { \
     738                        if ( f.base == 'd' && f.val < 0 ) { f.val = -f.val; fmt.flags.neg = true; } \
     739                        base_128( os, f.val, (unsigned int128)10_000_000_000_000_000_000UL, fmt, 19, 0 ); \
     740                } else { \
     741                        base_128( os, f.val, (unsigned int128)1 << 64, fmt, 16, 4 ); \
     742                } /* if */ \
     743                return os; \
     744        } /* ?|? */ \
     745        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
     746} // distribution
     747
     748IntegralFMTImpl128( int128 )
     749IntegralFMTImpl128( unsigned int128 )
     750#endif // __SIZEOF_INT128__
     751#endif // 0
    665752
    666753// *********************************** floating point ***********************************
Note: See TracChangeset for help on using the changeset viewer.